Пример #1
0
        /// <summary>
        /// a1-a2のベクトル(a1起点)とb2-b1のベクトル(b2起点)の交点を計算する
        /// 但し、平行ではなく交点がa1-a2とb2-b1の直線上に見つからないか、線分上に存在しない場合はa2,b1の中点を返す
        /// </summary>
        /// <param name="a1"></param>
        /// <param name="a2"></param>
        /// <param name="b1"></param>
        /// <param name="b2"></param>
        /// <returns></returns>
        public static Coordinate vectorIntersection(Coordinate a1, Coordinate a2, Coordinate b1, Coordinate b2)
        {
            Coordinate coord = CoordinateUtility.intersection(a1, a2, b1, b2);

            if (CoordinateUtility.getDistance(a1, coord) < CoordinateUtility.getDistance(a2, coord) || CoordinateUtility.getDistance(b2, coord) < CoordinateUtility.getDistance(b1, coord))
            {
                // 交点座標がa1またはb2に近いに近い場合
                if (!CoordinateUtility.checkPointAndLineSegment(a1, a2, coord) && !CoordinateUtility.checkPointAndLineSegment(b1, b2, coord))
                {
                    coord.x = (a2.x + b1.x) / 2.0f;
                    coord.y = (a2.y + b1.y) / 2.0f;
                }
            }

            return(coord);
        }
Пример #2
0
        /// <summary>
        /// a1座標、a2座標を通過する直線とb1座標、b2座標を通過する直線の交点を計算します。
        /// </summary>
        /// <param name="a1"></param>
        /// <param name="a2"></param>
        /// <param name="b1"></param>
        /// <param name="b2"></param>
        /// <returns></returns>
        public static Coordinate intersection(Coordinate a1, Coordinate a2, Coordinate b1, Coordinate b2)
        {
            // 交点座標
            Coordinate cross_coord = new Coordinate();

            if (a1.x == b1.x && a1.y == b1.y)
            {
                // a1とb1が同じ座標の場合
                cross_coord.x = a1.x;
                cross_coord.y = a1.x;

                return(cross_coord);
            }
            else if (a1.x == b2.x && a1.y == b2.y)
            {
                // a1とb2が同じ座標の場合
                cross_coord.x = a1.x;
                cross_coord.y = a1.y;

                return(cross_coord);
            }
            else if (a2.x == b1.x && a2.y == b1.y)
            {
                // a2とb1が同じ座標の場合
                cross_coord.x = a2.x;
                cross_coord.y = a2.y;

                return(cross_coord);
            }
            else if (a2.x == b2.x && a2.y == b2.y)
            {
                // a2とb2が同じ座標の場合
                cross_coord.x = a2.x;
                cross_coord.y = a2.y;

                return(cross_coord);
            }

            // a1-a2, b1-b2の各長さが0でないかチェックする
            var distance_a = CoordinateUtility.getDistance(a1, a2);
            var distance_b = CoordinateUtility.getDistance(b1, b2);

            if (distance_a == 0 || distance_b == 0)
            {
                throw new ArgumentException("distance is 0");
            }

            // aベクトル、bベクトルを作成
            Vector2 vec_a = CoordinateUtility.getVector2(a1, a2);
            Vector2 vec_b = CoordinateUtility.getVector2(b1, b2);

            // a1-a2, b1-b2の向きが同じ方向か間逆の方向かをチェックする
            Boolean parallel = CoordinateUtility.checkParallel(vec_a, vec_b);

            if (parallel)
            {
                throw new ArgumentException("this relationship is parallel");
            }

            // a1-a2, b1-b2の各直線の傾き、切片を計算する
            float[] line_a = CoordinateUtility.getLineVariable(a1, a2);
            float[] line_b = CoordinateUtility.getLineVariable(b1, b2);

            if (float.IsNaN(line_a[0]))
            {
                // a1-a2がY軸に平行な直線の場合
                cross_coord.x = a1.x;
                cross_coord.y = line_b[0] * cross_coord.x + line_b[1]; //  y=ax+b
            }
            else if (float.IsNaN(line_b[0]))
            {
                // b1-b2がY軸に平行な直線の場合
                cross_coord.x = b1.x;
                cross_coord.y = line_a[0] * cross_coord.x + line_a[1]; //  y=ax+b
            }
            else if (line_a[0] == 0.0f)
            {
                // a1-a2がX軸に平行な直線の場合
                cross_coord.x = (line_a[1] - line_b[1]) / line_b[0]; //  x=(y-b)/a
                cross_coord.y = line_a[1];
            }
            else if (line_b[0] == 0.0f)
            {
                // b1-b2がX軸に平行な直線の場合
                cross_coord.x = (line_b[1] - line_a[1]) / line_a[0]; //  x=(y-b)/a
                cross_coord.y = line_b[1];
            }
            else
            {
                // 逆行列から交点を求める
                // m11, m12
                // m21, m22
                // m31=0, m32=0
                // の構造

                // y = p1*x + q1
                // y = p2*x + q2
                // を以下のように展開(行列)
                // |p1 -1||x| = |-p1|
                // |p2 -1||y| = |-p2|
                // x,yは逆行列を求めて右辺との行列の積で計算できる

                Matrix3x2 matrix = new Matrix3x2(line_a[0], -1.0f, line_b[0], -1.0f, 0.0f, 0.0f);
                // 逆行列
                Matrix3x2 matrix_invert;
                Matrix3x2.Invert(matrix, out matrix_invert);

                cross_coord.x = matrix_invert.M11 * -line_a[1] + matrix_invert.M12 * -line_b[1];
                cross_coord.y = matrix_invert.M21 * -line_a[1] + matrix_invert.M22 * -line_b[1];
            }

            return(cross_coord);
        }