未经过题目测试。。。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define llu unsigned ll
using namespace std;
const double eps=1e-8;
const double dnf=1e20;
const double pi=acos(-1.0);
const int maxp=1010;
//浮点型数值是否为0
int sgn(double x)
{
if(abs(x)<eps) return 0;
if(x<0) return -1;
return 1;
}
struct Point3
{
double x,y,z;
Point3(double xx=0,double yy=0,double zz=0)
{
x=xx,y=yy,z=zz;
}
void input(void)
{
scanf("%lf%lf%lf",&x,&y,&z);
}
void output(void)
{
printf("%.2f %.2f %.2f\n",x,y,z);
}
double len(void)
{
return sqrt(x*x+y*y+z*z);
}
double len2(void)
{
return x*x+y*y+z*z;
}
double dis(const Point3 &b) const
{
return sqrt((x-b.x)*(x-b.x)+(y-b.y)*(y-b.y)+(z-b.z)*(z-b.z));
}
bool operator ==(const Point3 &b) const
{
return sgn(x-b.x)==0&&sgn(y-b.y)==0&&sgn(z-b.z)==0;
}
bool operator <(const Point3 &b) const
{
if(sgn(x-b.x)!=0) return x<b.x;
if(sgn(y-b.y)!=0) return y<b.y;
return sgn(z-b.z)<0;
}
Point3 operator + (const Point3 &b) const
{
return Point3(x+b.x,y+b.y,z+b.z);
}
Point3 operator - (const Point3 &b) const
{
return Point3(x-b.x,y-b.y,z-b.z);
}
Point3 operator * (const double &k) const
{
return Point3(x*k,y*k,z*k);
}
Point3 operator / (const double &k) const
{
return Point3(x/k,y/k,z/k);
}
Point3 operator ^ (const Point3 &b) const
{
return Point3(y*b.z-z*b.y,z*b.x-x*b.z,x*b.y-y*b.x);
}
double operator * (const Point3 &b) const
{
return x*b.x+y*b.y+z*b.z;
}
double rad(Point3 a,Point3 b)
{
Point3 p=(*this);
return acos(((a-p)*(b-p))/(a.dis(p)*b.dis(p)));
}
Point3 turn_to_r(double r)
{
double l=len();
if(!sgn(l)) return *this;
r/=l;
return Point3(x*r,y*r,z*r);
}
};
struct Line3
{
Point3 s,e;
Line3(){}
Line3(Point3 ss,Point3 ee)
{
s=ss,e=ee;
}
void input(void)
{
s.input();
e.input();
}
void output(void)
{
s.output();
e.output();
}
bool operator == (const Line3 v)
{
return (s==v.s)&&(e==v.e);
}
double len(void)
{
return s.dis(e);
}
double dis_point_to_line(Point3 p)
{
return ((e-s)^(p-s)).len()/s.dis(e);
}
double dis_point_to_seg(Point3 p)
{
if(sgn((p-s)*(e-s))<0||sgn((p-e)*(s-e))<0)
return min(p.dis(s),p.dis(e));
return dis_point_to_line(p);
}
Point3 point_prog_line(Point3 p)
{
return s+(((e-s)*((e-s)*(p-s)))/((e-s).len2()));
}
//P绕此向量逆时针转angle角度
Point3 turn_line_angle(Point3 p,double angle)
{
if(sgn(((s-p)^(e-p)).len())==0) return p;
Point3 f1=(e-s)^(p-s);
Point3 f2=(e-s)^f1;
double len=((s-p)^(e-p)).len()/s.dis(e);
f1=f1.turn_to_r(len);
f2=f2.turn_to_r(len);
Point3 h=p+f2;
Point3 pp=h+f1;
return h+((p-h)*cos(angle))+((pp-h)*sin(angle));
}
bool point_is_on_seg(Point3 p)
{
return sgn(((s-p)^(e-p)).len())==0&&sgn((s-p)*(e-p))==0;
}
};
struct Plane
{
Point3 a,b,c,o;//o是法向量
Plane(){}
Point3 pvec(void)
{
return (b-a)^(c-a);
}
Plane(Point3 aa,Point3 bb,Point3 cc)
{
a=aa,b=bb,c=cc,o=pvec();
}
//ax+by+cz+d=0;
Plane(double aa,double bb,double cc,double dd)
{
o=Point3(aa,bb,cc);
if(sgn(aa)!=0)
a=Point3((-dd-cc-bb)/aa,1,1);
else if(sgn(bb)!=0)
a=Point3(1,(-dd-cc-aa)/bb,1);
else if(sgn(cc)!=0)
a=Point3(1,1,(-dd-aa-bb)/cc);
}
//点在平面上的判断
bool point_is_on_plane(Point3 p)
{
return sgn((p-a)*o)==0;
}
//两平面夹角
double angle_plane(Plane f)
{
return acos(o*f.o)/(o.len()*f.o.len());
}
//平面和直线的交点,返回值是交点个数
int cross_line_plane(Line3 u,Point3 &p)
{
double x=o*(u.e-a);
double y=o*(u.s-a);
double d=x-y;
if(sgn(d)==0) return 0;
p=((u.s*x)-(u.e*y))/d;
return 1;
}
//点到平面最近点 (也就是投影)
Point3 point_to_plane(Point3 p)
{
Line3 u=Line3(p,p+o);
cross_line_plane(u,p);
return p;
}
//平面和平面的交线
int cross_plane_plane(Plane f,Line3 &u)
{
Point3 oo=o^f.o;
Point3 v=o^oo;
double d=abs(f.o*v);
if(sgn(d)==0) return 0;
Point3 q=a+(v*(f.o*(f.a-a))/d);
u=Line3(q,q+oo);
return 1;
}
};
int main(void)
{
return 0;
}