12.三维计算几何基础
三维计算几何基础
定义
struct Point3{
double x,y,z;
Point3(double x=0,double y=0,double z=0):x(x),y(y),z(z){}
};
typedef Point3 Vector3;
基本运算
Vector3 operator +(Vector3 A,Vector3 B){return Vector3(A.x+B.x,A.y+B.y,A.z+B.z);}
Vector3 operator -(Point3 A,Point3 B){return Vector3(A.x-B.x,A.y-B.y,A.z-B.z);}
Vector3 operator *(Vector3 A,double p){return Vector3(A.x*p,A.y*p,A.z*p);}
Vector3 operator /(Vector3 A,double p){return Vector3(A.x/p,A.y/p,A.z/p);}
直线的表示,可以用参数方程 (点和向量)来表示,射线和线段可以看成”参数由取值范围限制的“的直线
平面的表示,用点法式
整理得:
当
点积
double dot(Vector3 A, Vector3 B) { return A.x * B.x + A.y * B.y + A.z * B.z; }
长度
double length(Vector3 A) { return sqrt(dot(A, A)); }
向量夹角
double angle(Vector3 A, Vector3 B) { return acos(dot(A, B) / length(A) / length(B)); }
叉积
三维叉积的结果是一个向量
叉积同时垂直于
Vector3 cross(Vector3 A, Vector3 B) {
return Vector3(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x);
}
通过向量叉积,可以进行一些拓展的基础问题。
过不共线的三点的平面,法向量为
三角形的有向面积的两倍
double area2(Point3 A, Point3 B, Point3 C) { return length(cross(B - A, C - A)); }
点、线、面
点到直线的距离
double distance_to_line(Point3 p, Point3 p0, Vector3 v) {
return length(cross(p - p0, v)) / length(v);
}
点在直线上的投影
Point3 line_projection(Point3 p, Point3 p0, Vector3 v) {
return p0 + v * dot(p - p0, v) / dot(v, v);
}
点到平面的距离

把
double distance_to_plane(Point3 p, Point3 p0, Vector3 n) {
return fabs(dot(p - p0, n) / length(n));
} //点 p 到平面 p0-n 的距离,如果不取绝对值,得到的是有向距离
点在平面上的投影点
设
Point3 plane_projection(Point3 p, Point3 p0, Vector3 n) {
return p - n * dot(p - p0, n) / length(n);
}
直线和直线的交点
Point3 line_intersection(Point3 p, Vector3 v, Point3 q, Vector3 w) {
Vector3 u = p - q;
double t = length(cross(w, u)) / length(cross(v, w));
return p + v * t;
}
直线和平面的交点
设平面方程为
如果分母为
如果平面用一般式
Point3 line_plane_intersection(Point3 p, Vector3 v, Point3 p0, Vector3 n) {
Vector3 u = p - p0;
double t = dot(n, u) / dot(n, v);
return p - v * t;
}
体
四面体的体积
已知
double volume6(Point3 A, Point3 B, Point3 C, Point3 D) {
return dot(D - A, cross(B - A, C - A));
}