已知空間兩點組成的直線求線上某點的Z值,爲何會有這種看起來比較奇怪的求值需求呢?由於真正三維空間的幾何計算是比較麻煩的,不少時候須要投影到二維,再反推到三維空間上去。ios
複習下空間直線方程:已知空間上一點\(M0(x0,y0,z0)\)和方向向量\(S(m,n,p)\),則直線方程的點向式爲:
\[ \frac{X-x0}{m}=\frac{Y-y0}{n}=\frac{Z-z0}{p} \]spa
根據該公式能夠解決該計算幾何問題,具體實現代碼以下:3d
#include<iostream> using namespace std; //三維double矢量 struct Vec3d { double x, y, z; Vec3d() { x = 0.0; y = 0.0; z = 0.0; } Vec3d(double dx, double dy, double dz) { x = dx; y = dy; z = dz; } void Set(double dx, double dy, double dz) { x = dx; y = dy; z = dz; } }; bool CalLinePointZ(const Vec3d & v1, const Vec3d & v2, Vec3d & vp) { const double eps = 0.0000001; //方向向量 Vec3d s(v2.x-v1.x, v2.y - v1.y, v2.z - v1.z); //此時沒法求值 if (abs(s.x) == eps && abs(s.y) == eps) { return false; } double t = 0; if (abs(s.x) > eps && abs(s.y) == eps) { double t = (vp.x - v1.x) / s.x; } else if (abs(s.x) == eps && abs(s.y) > eps) { double t = (vp.y - v1.y) / s.y; } else { double tx = (vp.x - v1.x) / s.x; double ty = (vp.y - v1.y) / s.y; //說明點不可能在直線上 if (abs(tx - ty) > eps) { return false; } t = tx; } vp.z = t * s.z + v1.z; return true; } int main() { Vec3d v1(0.0, 0.0, 3.7); Vec3d v2(5.0, 5.0, 4.5); Vec3d vp; vp.x = 4.6; vp.y = 4.6; vp.z = 0.0; if (CalLinePointZ(v1, v2, vp)) { cout << "該點的高程:" << vp.z << endl; } return 0; }
注意根據方向向量的值作特殊狀況判斷,當直線的方向向量\(S(m,n,p)\)的\(m=n=0\)時,是沒法正確求值的。code