public Vector3d?GetIntersection(Plane plane) { if (Tolerance.IsIgnorable(Length)) { return(null); } // 直線と平面との交差判定 var line = new Line(StartPoint, Vector); var intersection = line.GetIntersection(plane); if (!intersection.HasValue) { return(null); } // 交点が StartPoint と EndPoint の間にあるか否かを判定する // 直線の方程式は x = o + b v => b = ((x - o) | v) / (v | v) var factor = Vector3d.DotProduct(intersection.Value - StartPoint, Vector) / Vector3d.DotProduct(Vector, Vector); if (factor < 0d || 1d < factor) { return(null); } return(intersection.Value); }
public Vector3d?GetIntersection(Plane plane) { // 直線と平面が平行かどうか (直線の方向ベクトルと平面の法線ベクトルが直交するかどうか) var v_dot_n = Vector3d.DotProduct(Vector, plane.Normal); if (Tolerance.IsIgnorable(v_dot_n)) { return(null); } // 直線の方程式 x = o_{l} + b V // 平面の方程式 (x - o_{p} | N) = 0 // 両者を連立させて, // (o_{l} + b V - o_{p} | N) = 0 // (o_{l} - o_{p} | N) + b (V | N) = 0 // (V | N) != 0 ならば, // b = (o_{p} - o_{l} | N) / (V | N) // 直線の式に代入し,交点 x_{c} は // x_{c} = o_{l} + ((o_{p} - o_{l} | N) / (V | N)) V var factor = Vector3d.DotProduct(plane.Origin - Origin, plane.Normal) / v_dot_n; var intersection = Origin + factor * Vector; return(intersection); }
/// <summary> /// 2つの直線の交点を取得します /// [契約] 平行な関係にある場合 (重なる場合・端点でつながる場合含む) は交点はなしと考えます /// </summary> /// <param name="line"></param> /// <param name="areParallel">平行かどうか(true -> 平行, false -> 非平行)</param> /// <returns></returns> public Vector3d?GetIntersection(Line line, out bool areParallel) { double aMin, bMin; var distance = GetDistance(line, out aMin, out bMin, out areParallel); if (areParallel || !Tolerance.IsIgnorable(distance)) { return(null); } return(Origin + aMin * Vector); /* * // 平行でない -> ねじれの位置になければ, 平面が1つ決まる * var points = new Vector3d[] { * Origin, * Origin + Vector, * line.Origin, * line.Origin + line.Vector * }; * var plane = Plane.From3Points( points[ 0 ], points[ 1 ], points[ 2 ] ); * if (!plane.IsOn( points[ 3 ] )) * return null; * * // 4点が1つの平面に乗る -> 2つの直線はねじれの位置にはない * // 平面上へと座標変換して2次元で交点計算する (精度がよい) * // l1 : p = o1 + a v1 * // l2 : q = o2 + b v2 * // o1 + a v1 = o2 + b v2 * // v2 に直交するベクトルを構成し (v2 を 90度回転する) 内積で未知数を1つ減らし求める * // 計算後,逆座標変換して3次元上の点を得る */ }
/// <summary> /// 点が線分上に乗っているかどうかを判定します /// </summary> /// <param name="point"></param> /// <returns></returns> public bool IsOn(Vector3d point) { double projectedParameter; var projectedPoint = new Line(this).GetProjectedPoint(point, out projectedParameter); // 点と射影点との距離が誤差を除いて 0 か? if (!Tolerance.IsIgnorable((point - projectedPoint).Norm)) { return(false); } // 射影点が線分上にあるか? return(0d <= projectedParameter && projectedParameter <= 1d); }
/// <summary> /// 点が直線上に乗っているかどうかを判定します /// </summary> /// <param name="point"></param> /// <returns>true -> 乗っている, false -> 乗っていない</returns> public bool IsOn(Vector3d point) => Tolerance.IsIgnorable(GetDistance(point));