Algorithm 版 (精华区)
发信人: Lerry (life is waiting...), 信区: Algorithm
标 题: [合集]如何判断一个点是否在一个平面上?
发信站: 哈工大紫丁香 (2003年11月27日18:31:07 星期四), 站内信件
────────────────────────────────────────
jijian (CC) 于 2003年10月09日19:39:59 星期四 说道:
题目是这样的,两个球和一点
求这点是否在两个球的交线(交线是圆)构成的平面上,其中球心坐标和半径
都是整数,点的坐标也是整数。
我是用勾股定理判的,WA了
────────────────────────────────────────
hewind ( 比pineapple写的程序慢了200倍! :( 555~~) 于 2003年10月09日20:13:37 星期四 说道:
得到两个球的方程,
联立得相交线方程,
可得到三个点的坐标,
通过这三个点的坐标就可以得构造平面方程,
也可以得到一个点的坐标,然后以球心连心为法线,用点法式构造平面方程。
测试这个点是否满足这个平面方程。
可否?
────────────────────────────────────────
xiong (赤龙之怒) 于 2003年10月09日20:29:25 星期四 说道:
我求的平面方程,还是WA了。
#include "stdio.h"
#include "iostream.h"
#include "math.h"
const double small=0.00000000000001;
bool isin(double rx,double ry,double rz,double r,double x,double y,double z)
{
if(r*r-((rx-x)*(rx-x)+(ry-y)*(ry-y)+(rz-z)*(rz-z))>=0.0)
return true;
else
return false;
}
int main()
{
char name[100];
double x1,y1,z1,r1,x2,y2,z2,r2,x0,y0,z0,d,temp,m,cx,cy,cz;
bool change,is1,is2;
while(cin>>name>>x1>>y1>>z1>>r1>>x2>>y2>>z2>>r2>>x0>>y0>>z0)
{
cout<<name<<endl;
d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
change=false;
if(r1<r2)
{
change=true;
temp=r1;r1=r2;r2=temp;
temp=x1;x1=x2;x2=temp;
temp=y1;y1=y2;y2=temp;
temp=z1;z1=z2;z2=temp;
}
m=(r1*r1-r2*r2+d*d)/2.0/d;
cx=x1+m/d*(x2-x1);
cy=y1+m/d*(y2-y1);
cz=z1+m/d*(z2-z1);
is1=isin(x1,y1,z1,r1,x0,y0,z0);
is2=isin(x2,y2,z2,r2,x0,y0,z0);
if(!change)
{
if(is1)cout<<"y"<<endl;
else cout<<"n"<<endl;
if(is2)cout<<"y"<<endl;
else cout<<"n"<<endl;
}
else
{
if(is2)cout<<"y"<<endl;
else cout<<"n"<<endl;
if(is1)cout<<"y"<<endl;
else cout<<"n"<<endl;
}
temp=(x0-cx)*(x2-x1)+(y0-cy)*(y2-y1)+(z0-cz)*(z2-z1);
if((fabs(temp-0.0)>=small)&&(is1||is2))
cout<<"y"<<endl;
else
cout<<"n"<<endl;
}
return 0;
}
────────────────────────────────────────
jijian (CC) 于 2003年10月09日20:30:47 星期四 说道:
我是这样判断的
利用比例关系求出两圆交线确定的面和连心线的交点坐标
如果第三个点在这个面上,
那么第三点,圆心1和连心线和面的交点构成了
直角三角形
可是WA了
────────────────────────────────────────
Taliux (彻夜孤灯) 于 2003年10月09日20:42:25 星期四 说道:
是指整个平面,还是交线围住的那部分?
────────────────────────────────────────
hewind ( 比pineapple写的程序慢了200倍! :( 555~~) 于 2003年10月09日20:50:17 星期四 说道:
不一定,要是第三点与圆心1的连线垂直于连心线,也满足情况,而显然,第三点不在
面上,而在过圆心1的垂线上
────────────────────────────────────────
oi (边城浪子) 于 Thu Oct 9 20:53:55 2003 说道:
判断该点到两个球心的距离是否相等,相等,则在平面上。
────────────────────────────────────────
hewind ( 比pineapple写的程序慢了200倍! :( 555~~) 于 2003年10月09日20:55:42 星期四 说道:
不行,
这两个球半径不一定相等。
如果不相等,显然,第三点到两个球心的距离不相等
────────────────────────────────────────
hewind ( 比pineapple写的程序慢了200倍! :( 555~~) 于 2003年10月09日20:58:14 星期四 说道:
还有一个情况,当这两个球相交的面并不是在两球心之间,而是在两球心之外。
你的方法也失效。
────────────────────────────────────────
xiong (赤龙之怒) 于 2003年10月09日21:02:51 星期四 说道:
整个平面
────────────────────────────────────────
Taliux (彻夜孤灯) 于 2003年10月09日21:06:53 星期四 说道:
那样是直角边不是斜边呀
────────────────────────────────────────
oi (边城浪子) 于 Thu Oct 9 21:12:17 2003 说道:
对了,我定式思维:)
────────────────────────────────────────
jijian (CC) 于 2003年10月09日21:13:50 星期四 说道:
第三点和交点的连线为直边
圆心1和交点的连线也为直边
圆心1 和第三点的连线为斜边
你说的这个情况不会判为在平面上
────────────────────────────────────────
jijian (CC) 于 2003年10月09日21:17:14 星期四 说道:
在我的程序中,
如果r1>r2,那么他们的值交换
而且我是利用向量的差值和比例来求解的
即使在内部,也会得出这个点的坐标
我把程序贴出来。
//写的有点乱。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define eps 0.000001
int main()
{
freopen("d:\\uva10425.in","r",stdin);
freopen("d:\\uva10425.out","w",stdout);
char cname[10];
long long x1,y1,z1,r1,x2,y2,z2,r2,x3,y3,z3;
while(cin>>cname>>x1>>y1>>z1>>r1>>x2>>y2>>z2>>r2>>x3>>y3>>z3)
{
printf("%s\n",cname);
bool change=false;
if(r1<r2)
change=true,swap(x1,x2),swap(y1,y2),swap(z1,z2);
bool ok1,ok2,ok3;
long long dis13_2=(x1-x3)*(x1-x3)+(y1-y3)*(y1-y3)+(z1-z3)*(z1-z3);
if(dis13_2<=r1*r1)
ok1=true;
else
ok1=false;
if((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)+(z2-z3)*(z2-z3)<=r2*r2)
ok2=true;
else
ok2=false;
//
double temp=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2);
double dis12=sqrt(temp);
if(fabs(temp)<eps)
{
if(r1*r1==(x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)+(z2-z3)*(z2-z3))
ok3=false;
}
else{
double temp2=(double)(r1*r1+temp-r2*r2)/2./dis12;
double k=temp2/dis12;
double cx=x1+(x2-x1)*k,cy=y1+(y2-y1)*k,cz=z1+(z2-z1)*k;
if((x3-cx)*(x3-cx)+(y3-cy)*(y3-cy)+(z3-cz)*(z3-cz)+temp2*temp2-(double
)dis13_2<eps||(ok1==false&&ok2==false))
ok3=false;
else
ok3=true;
//
}
if(change==false)
{
if(ok1==true) printf("y\n");
else printf("n\n");
if(ok2==true) printf("y\n");
else printf("n\n");
}
else
{
if(ok2==true) printf("y\n");
else printf("n\n");
if(ok1==true) printf("y\n");
else printf("n\n");
}
if(ok3==true) printf("y\n");
else printf("n\n");
}
return 0;
}
────────────────────────────────────────
pineapple (菠萝) 于 2003年10月10日14:33:01 星期五 说道:
题号, 我看一下.
────────────────────────────────────────
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.657毫秒