点から直線までの最近点を得る
これも内積(Dot Product)で求まる。
|AX|を内積で求めるのがポイント。
線分PAを引くと、直角三角形PAXができる。
cosA = |AX| / |AP|
cosA|AP| = |AX|
|AX| = |AP|cosA ・・・① となる。
また、内積の公式は AP・AB = |AP| * |AB| * cosA ・・・②である。
②を変形すると、
|AP| = (AP・AB) / (|AB| * cosA)
①、②より、|AX| = (AP・AB) / (|AB| * cosA) * cosA
ゆえに、|AX| = (AP・AB) / |AB|・・・③
点Xの位置はAB上にあるので、
点X = A + (|AX| / |AB|) * ベクトルAB
点X = A + ( AP・AB / |AB|) / |AB| * ベクトルAB
したがって、
点X = (0,0,0) + (0*2 + 3*6 + 0*0 / / √40) / √40 * ベクトルAB
= (0,0,0) + (18/√40) / √40 * ベクトルAB
= (0,0,0) + 2.848/6.324 * ベクトルAB
= (0,0,0) + 0.450 * 2 + 0.450 * 6 + 0.450 * 0
≒ (0.9, 2.7, 0.0)
using System; using System.Windows.Media.Media3D; namespace Calc { public static class Logic { /// <summary> /// 点Pから直線ABまでの最近点Xを得る /// </summary> /// <param name="p">点P</param> /// <param name="a">点A(直線ABの1点目)</param> /// <param name="b">点B(直線ABの2点目)</param> /// <returns>最近点X</returns> static public Point3D GetNearestPoint(Point3D p, Point3D a, Point3D b) { Vector3D vAP = new Vector3D(p.X - a.X, p.Y - a.Y, p.Z - a.Z); Vector3D vAB = new Vector3D(b.X - a.X, b.Y - a.Y, b.Z - a.Z); double AXLength = Vector3D.DotProduct(vAP, vAB) / vAB.Length; Point3D X = a + (AXLength / vAB.Length) * vAB; return X; } } }