Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        /// <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次元上の点を得る
             */
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// 点が直線上に乗っているかどうかを判定します
 /// </summary>
 /// <param name="point"></param>
 /// <returns>true -> 乗っている, false -> 乗っていない</returns>
 public bool IsOn(Vector3d point) =>
 Tolerance.IsIgnorable(GetDistance(point));