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毫秒