1265 四点共面(几何问题)
1265 四点共面
题目链接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1265
给出三维空间上的四个点(点与点的位置均不相同),判断这4个点是否在同一个平面内(4点共线也算共面)。如果共面,输出"Yes",否则输出"No"。
收起
输入
第1行:一个数T,表示输入的测试数量(1 <= T <= 1000) 第2 - 4T + 1行:每行4行表示一组数据,每行3个数,x, y, z, 表示该点的位置坐标(-1000 <= x, y, z <= 1000)。
输出
输出共T行,如果共面输出"Yes",否则输出"No"。
输入样例
1 1 2 0 2 3 0 4 0 0 0 0 0
输出样例
Yes
该题典型的高中知识,利用法向量判断是否共面。一个平面最少由三个点(a,b,c)组成,然后两个不同点就可以得到一个向量,两个向量(如 ac,ab 向量)可求法向量(n1)。这里法向量的求法为 向量积,不懂向量积的自行百度,向量积也称为外积,叉乘。几何意义就是垂直ac,ab的一个法向量。然后加进来一点d,题意也就是问d点在不在abc平面上! 然后我们看看 d点与任意两点比如说(d a b)构成的平面是不是与(abc)是同一个,比较法向量便知!代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
//求向量积的函数
int P(int a[],int b[],int c[])
{
c[0]=a[1]*b[2]-b[1]*a[2];
c[1]=b[0]*a[2]-b[2]*a[0];
c[2]=a[0]*b[1]-b[0]*a[1];
//printf("\n%d-%d-%d\n",c[0],c[1],c[2]);
}
int main()
{
int T;
cin>>T;
int a[3],b[3],c[3],d[3],ac[3],ab[3],ad[3];
//两个法向量
int n1[3],n2[3];
while(T--)
{
for(int i=0;i<3;i++)
cin>>a[i];
for(int i=0;i<3;i++)
cin>>b[i];
for(int i=0;i<3;i++)
cin>>c[i];
for(int i=0;i<3;i++)
cin>>d[i];
//求ac,ab向量
for(int i=0;i<3;i++)
{
ac[i]=c[i]-a[i];
ab[i]=b[i]-a[i];
ad[i]=d[i]-a[i];
}
// 求法向量
P(ac,ab,n1);
P(ad,ab,n2);
// 下面是判断两个法向量是不是平行关系 ,是不是倍数关系
// 先找到不为0的一个数,然后除以它就是倍数关系
int j;
for(j=0;j<3;j++)
{
if(n1[j]!=0)
break;
}
// 倍数temp
double temp=(double)n2[j] / (double)n1[j];
int flag=0;
for(int i=0;i<3;i++)
{
//因为两个相等的浮点数相减不一定为0
if(fabs((double)n2[i]-(double)(n1[i]*temp))>pow(10,-4))
flag=1;
}
if(flag==0)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}