如下圖所示,我們要計算的是c點到直線ab的距離。
首先我們要認識到,雖然在數學上,【點】與【向量】是兩種不同的名詞,但在實際的計算中是可以直接把【點】的坐標視為從坐標系【原點】到【點】的【向量】。有了這個前提,線段ab其實可以簡單地表示為向量n,其他的向量同理可得。用向量解決這個問題的關鍵是求出v在n上的投影向量vn。
經過推導,得到等式 (注意【點乘】和【乘以】的區別)
為了便於計算,可以把等式寫為這樣
【點乘】的計算優先級高於【乘以】,所以該等式是通過計算出投影向量vn的【模】,然后再乘以n的標准化向量
也就是vn的方向,最后得到vn
。前面提到過,【點】和【向量】可視為等價的,也就是說【向量】也可以代表【點】的坐標,所以求出了vn,也就等價於求出了c到ab的垂線與ab(ab的延長線)相交的點的坐標。然后我們利用兩點間的距離公式即可以求出c到ab的距離。下面直接上代碼。
using System; using System.Numerics; namespace _3dMath { class VectorCalculate{ public VectorCalculate(Vector3 point_a, Vector3 point_b, Vector3 point_c) { _point_a = point_a; _point_b = point_b; _point_c = point_c; } public float DistanceCalculate() { Vector3 vec_ab = _point_b - _point_a; Vector3 vec_ac = _point_c - _point_a; float distance = 0.0f; Vector3 vec_Normalize = Vector3.Normalize(vec_ab); float projection_length = Vector3.Dot(vec_ac, vec_Normalize); //計算出投影向量的模 Vector3 vec_Projection = Vector3.Multiply(projection_length, vec_Normalize); //計算出投影向量 distance = Vector3.Distance(vec_ac, vec_Projection); return distance; } private Vector3 _point_a; private Vector3 _point_b; private Vector3 _point_c; } class Test{ static void Main(string[] arg) { Vector3 point_a = new Vector3(1.0f, 1.0f, 1.0f); Vector3 point_b = new Vector3(5.0f, 2.0f, 1.0f); Vector3 point_c = new Vector3(2.0f, 3.0f, 1.0f); //Vector3 point_c = new Vector3(-1.0f, 2.0f, 0.0f); VectorCalculate vec_Calculate = new VectorCalculate(point_a, point_b, point_c); float res = vec_Calculate.DistanceCalculate(); Console.WriteLine("The distance is: {0}", res); } } }
最后,如果各位發現內容有不嚴謹的地方,希望能夠在評論區指出,歡迎討論。