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三个向量, 求出 A X B (cross product), 就是以A B构成的平面的一个法向量(如果 AB共线,则法向量为0), 在求其与C之间的点积, 如果为0, 则表示两个向量为0。 所以四点共面。

#include<bits/stdc++.h>
using namespace std;
const double EPS=1e-8;
struct Point{//点 二维三维 
	double x,y,z;
	Point(){};
	Point(double x,double y,double z=0):x(x),y(y),z(z){}
	Point operator - (const Point &a)const //向量减
	{
	 return Point(x-a.x,y-a.y,z-a.z); 
	} 
	/*double operator ^(const Point &a)const//向量积sin
	{
	          //二维           三维 
	 return x*a.y-y*a.x//+y*a.z-z*a.y-x*a.z+z*a.x;//值
  	} */
	Point operator ^(const Point &a)const//向量积sin
	{
	 return Point(y*a.z-z*a.y,z*a.x-x*a.z,x*a.y-y*a.x);//法向量
  	} 
		  
	double operator *(const Point &a)const//点积cos
	{     
	        //  二维     三维 
	 return x*a.x+y*a.y+z*a.z;	
	} 
};
/*
struct Circle{//圆 
	double x,y,r;
	Circle(){}
	Circle(double x,double y,double r):x(x),y(y),r(r){}
};
//默认 是 返还true  否 返回false 
bool Cross(const Point&p1,const Point&p2,const Point&p3,const Point&p4) 
{
//判断向量p1p2是否跨立p3p4 
 double a1=(p3-p1)^(p2-p1);
 double a2=(p4-p1)^(p2-p1);
 if(a1*a2>0)//同向
  return false;
 return true;	
}
//判断线段p1p2与圆是否相交 
bool Lcc(Point p1,Point p2,Circle c)
{
 bool flag1=(p1.x-c.x)*(p1.x-c.x)+(p1.y-c.y)*(p1.y-c.y)<=c.r*c.r;
 //判断点p1是否在圆内
 bool flag2=(p2.x-c.x)*(p2.x-c.x)+(p2.y-c.y)*(p2.y-c.y)<=c.r*c.r;
 //判断点p2是否在圆内
 if(flag1&&flag2)//两点都在圆内,不相交 
  return false; 
 if(flag1||flag2)//一点在圆内,一点在圆外,相交 
  return true; 
 //两点在圆外,判断形成的线段是否与圆相交
 double A,B,C,dis1,dis2,angle1,angle2;
 //将直线p1p2化为一般式:Ax+By+C=0的形式,先化为两点式,然后由两点式得出一般式 
 A=p1.y-p2.y;
 B=p2.x-p1.x;
 C=p1.x*p2.y-p2.x*p1.y;
 //使用距离公式判断圆心到直线ax+by+c=0的距离是否大于半径
 dis1=A*c.x+B*c.y+C;
 dis1*=dis1;
 dis2=(A*A+B*B)*c.r*c.r;
 if(dis1>dis2)//距离大于半径 
  return false; 
 angle1=(c.x-p1.x)*(p2.x-p1.x)+(c.y-p1.y)*(p2.y-p1.y);//c-p1与p1p2夹角
 angle2=(c.x-p2.x)*(p1.x-p2.x)+(c.y-p2.y)*(p1.y-p2.y);//c-p2与p1p2夹角  
 if(angle1>0&&angle2>0)//都是锐角 相交 
  return true;
 return false; 
} */
//判断四点是否共面 
int main()
{
 int t;
 cin>>t;
 while(t--)
 {
 	Point p[4];
	for(int i=0;i<4;i++)
	 cin>>p[i].x>>p[i].y>>p[i].z;
	double tmp=((p[1]-p[0])^(p[2]-p[0]))*(p[3]-p[0]);
	if(fabs(tmp)<EPS) 
 	 cout<<"Yes\n";
 	else cout<<"No\n";
 }
 return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值