原题: https://cn.vjudge.net/problem/Gym-101991J
题意:
有一个正三边形的平面(中心为(0,0,0)),现在告诉你一个顶点A的坐标和平面法向量alpha,边长,问三个点离H(0,0,-h)的距离
解析:
用O - alpha和O - A叉积,得到一个平行与BC的向量,那么很容易得到OB和OC,BH=OH-OB,CH=OH-OC,就解出来了
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8;
const double pi=acos(-1);
int dcmp(double x){
if(abs(x)<eps) return 0;
if(x>0) return 1;
return -1;
}
struct Point{
double x,y,z;
Point(){}
Point(double x,double y,double z):x(x),y(y),z(z){}
};
typedef Point Vector;
bool operator == (const Point &a, const Point &b){
return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0 &&dcmp(a.z - b.z) == 0;
}
Vector operator + (Vector a, Vector b){
return Vector(a.x + b.x, a.y + b.y,a.z + b.z);
}
Vector operator - (Vector a, Vector b){
return Vector(a.x - b.x, a.y - b.y,a.z - b.z);
}
Vector operator * (Vector a, double p){
return Vector(a.x*p, a.y*p,a.z*p);
}
Vector operator / (Vector a, double p){
return Vector(a.x / p, a.y / p,a.z/p);
}
Vector Across(Vector a,Vector b){
return Vector(a.y*b.z-b.y*a.z,b.x*a.z-a.x*b.z,a.x*b.y-b.x*a.y);
}
double Dot(Vector a, Vector b){//内积
return a.x*b.x + a.y*b.y+a.z*b.z;
}
double Length(Vector a){
return sqrt(Dot(a,a));
}
double Distance(Point a, Point b){//两点间距离
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)+(a.z-b.z)*(a.z-b.z));
}
int main(){
freopen("jupiter.in","r",stdin);
int t;scanf("%d",&t);
while(t--){
double xx,yy,zz;
scanf("%lf%lf%lf",&xx,&yy,&zz);
Vector alpha(xx,yy,zz);
scanf("%lf%lf%lf",&xx,&yy,&zz);
Vector A(xx,yy,zz),O(0,0,0);
double Len,H;
scanf("%lf%lf",&Len,&H);
Vector OA = A-O , opOA = O-A;
opOA=opOA/Length(opOA);
opOA=opOA*Len*sqrt(3)/6.0;
Vector OB = Across(alpha,A-O);
OB=OB/Length(OB);
OB=OB*Len/2;
Vector OC = OB * -1.0;
OB=OB+opOA;
OC=OC+opOA;
Vector OH {0,0,-H};
double oa=Length(OH-OA),ob=Length(OH-OB),oc=Length(OH-OC);
printf("%.6f %.6f %.6f\n",oa,ob,oc);
}
}