数学上,三维几何是3维欧式空间几何的传统名称。因为实际上这大致就是我们生活的空间。
我们在前面介绍过向量运算,其中很多内容也适合三维几何,如点+向量=点,向量+向量=向量,点+点没有定义。
首先是辅助宏的定义:
const double eps = 1e-10;
const double PI = acos(-1); // π
const double TWO_PI = 2*PI;
const int maxn = 100 + 5;
const int INF = 10000;
三维点的定义:
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 + (const Vector3 &A,const Vector3 &B)
{
return Vector3(A.x+B.x, A.y+B.y, A.z+B.z);
}
Vector3 operator - (const Vector3 &A,const Vector3 &B)
{
return Vector3(A.x-B.x, A.y-B.y, A.z-B.z);
}
Vector3 operator * (const Vector3 &A, double p)
{
return Vector3(A.x*p, A.y*p, A.z*p);
}
Vector3 operator / (const Vector3 &A, double p)
{
return Vector3(A.x/p, A.y/p, A.z/p);
}
bool operator == (const Vector3 &A,const Vector3 &B)
{
return (dcmp(A.x - B.x) == 0) && (dcmp(A.y - B.y) == 0) && (dcmp(A.z - B.z) == 0);
}
三维点积的定义和二维非常类似,而且也能用点积计算向量的长度和夹角。
double Dot(const Vector3 &A,const Vector3 &B)
{
return A.x*B.x + A.y*B.y + A.z*B.z;
}
向量的长度
double Length(const Vector3 &A)
{
return sqrt(Dot(A, A));
}
向量的夹角
double Angle(const Vector3 &A,const Vector3 &B)
{
return acos(Dot(A, B) / Length(A) / Length(B));
}
三维叉积:
三维空间里也有叉积的概念,但形式和二维叉积大不一样,它是一个向量,而不再是一个带符号的数。
v1 * v2 =
y1z2 – y2z1
z1x2 – z2x1
x1y2 – x2y1
一种在学术上不太严谨的说法,可以认为叉积同时垂直于v1和v2,方向遵循右手定则。当且仅当v1和v2平行时,叉积是0。
Vector3 Cross(const Vector3 &A,const Vector3 &B)
{
return Vector3(A.y*B.z - B.y*A.z, A.z*B.x - B.z*A.x, A.x*B.y - B.x*A.y);
}