2직선의 교점을 구한다

평면에서 두 직선의 위치 관계





평면상의 2 직선의 위치 관계는,
  • 교차점이 있다
  • 평행(교점 없음)
  • 겹치는(교점은 무한)

  • 중 하나.

    2직선의 교점을 구하는 방법



    직선 방정식 일반형의 형태로 표현된 2 직선,
    $a_1x+b_1y+c_1=0\\\및\\\a_2x+b_2y+c_2=0$
    의 교점을 구한다.



    이 2 직선에 교점이 있다고 가정해, 그 교점을 $P(x_0, y_0)$ 라고 하면,
    교차점 $P$ 는 2 직선 양쪽에 있기 때문에, 2 직선의 2 개의 식의 연립 방정식,
    $$\begin{cases}
    a_1x+b_1y+c_1=0\\cdots\①\\
    a_2x+b_2y+c_2=0\\cdots\②
    \end{cases}$$
    을 풀어서 구할 수 있다.

    2직선의 교점을 구한다



    ①② 의 식의 $y$ 를 소거한다.
    ① 의 양변에 $b_2$ 를, ② 의 양변에 $b_1$ 를 곱하고,
    $$\begin{cases}
    a_1b_2x+b_1b_2y+b_2c_1=0\\cdots\①'\\
    a_2b_1x+b_1b_2y+b_1c_2=0\\cdots\②'
    \end{cases}$$
    ① '에서 ②'를 당겨 정리하면,
    $$(a_1b_2-a_2b_1)x+b_2c_1-b_1c_2=0$$
    $$(a_1b_2-a_2b_1)x=(b_1c_2-b_2c_1)\\cdots\③$$
    ①② 의 식의 $x$ 를 소거한다.
    ② 의 양변에 $a_1$ 를, ① 의 양변에 $a_2$ 를 곱하고,
    $$\begin{cases}
    a_1a_2x+a_1b_2y+a_1c_2=0\\cdots\②''\\
    a_1a_2x+a_2b_1y+a_2c_1=0\\cdots\①''
    \end{cases}$$
    ② ''에서 ①''을 당겨 정리하면,
    $$(a_1b_2-a_2b_1)y+a_1c_2-a_2c_1=0$$
    $$(a_1b_2-a_2b_1)y=(a_2c_1-a_1c_2)\\cdots\④$$
    된다. 식 ③ ④에서,
    $$a_1b_2-a_2b_1\neq0\\즉\\\frac{a_1}{a_2}\neq\frac{b_1}{b_2}$$
    그렇다면 2 직선 교차점이 존재하고 좌표는
    $$x=\frac{b_1c_2-b_2c_1}{a_1b_2-a_2b_1}\\,\\y=\frac{a_2c_1-a_1c_2}{a_1b_2-a_2b_1}$$
    된다. 또한,
    $$a_1b_2-a_2b_1=0\\그리고\\b_1c_2-b_2c_1\neq0\\,\\a_2c_1-a_1c_2\neq0$$
    즉,
    $$\frac{a_1}{a_2}=\frac{b_1}{b_2}\neq\frac{c_1}{c_2}$$
    의 경우, 이 연립 방정식은 불가능하고 해는 존재하지 않는다.
    이것은, 2 직선의 관계가 평행인 것을 나타내고 있다.
    또한,
    $$a_1b_2-a_2b_1=0\\그리고\\b_1c_2-b_2c_1=0\\,\\a_2c_1-a_1c_2=0$$
    즉,
    $$\frac{a_1}{a_2}=\frac{b_1}{b_2}=\frac{c_1}{c_2}$$
    그렇다면이 연립 방정식은 부정하고 해는 무한히 존재한다.
    이것은, 2 직선의 관계가 겹치고 있는 것을 나타내고 있다.

    2 직선, $a_1x+b_1y+c_1=0\\\와\\\a_2x+b_2y+c_2=0$ 의 교차점은
    $$\left(\frac{b_1c_2-b_2c_1}{a_1b_2-a_2b_1}\\,\\\frac{a_2c_1-a_1c_2}{a_1b_2-a_2b_1}\right)\\\\\\\그러나 a_1b_1-a_ neq0$$

    2선분을 선택, 교점을 출력하는 프로그램


    ;; 2線分を選択して、交点を出力する
    (defun c:SelectTwoLineAndOutputIntersection
        (/ lineSeg1 lineSeg2 line1 line2 ip)
        (setq lineSeg1 (editor:EntselLine "線分1を選択")
              lineSeg2 (editor:EntselLine "線分2を選択")
        )
        ;; 線分1を含む直線の方程式を取得
        (setq line1
            (line:GetEquation
                (line:GetStartPoint lineSeg1)
                (line:GetEndPoint lineSeg1)
            )
        )
        ;; 線分2を含む直線の方程式を取得
        (setq line2
            (line:GetEquation
                (line:GetStartPoint lineSeg2)
                (line:GetEndPoint lineSeg2)
            )
        )
        ;; 交点を出力
        (if (setq ip (line:GetIntersection line1 line2))
            (progn
                (princ "\n交点の座標 : ") (princ ip)
            )
            (princ "\n2つの線分は平行です。\n")
        )
        (princ)
    )
    

    Subfunctions


    ;;;; == Subfunctions ==
    ;; 図形のDXF定義データの値を取得
    (defun entity:GetDxf (g e)
        (cond
            ((= (type e) 'ENAME) (cdr (assoc g (entget e))))
            ((listp e) (cdr (assoc g e))) 
        )
    )
    ;; 図形のタイプを取得
    (defun entity:GetType (e) (entity:GetDxf 0 e))
    ;; 線分図形をentsel 選択
    (defun editor:EntselLine (msg / lineSeg)
        ;; 線分を選択
        (while (null lineSeg)
            (setvar 'ERRNO 0)
            (setq lineSeg (car (entsel (strcat "\n" msg " :\n"))))
            (cond
                ;; 空振り
                ((= 7 (getvar 'ERRNO))
                 (princ "\n... 空振り! 再選択 ...\n")
                 (setq lineSeg nil)
                )
                ;; 空Enter
                ((= 52 (getvar 'ERRNO))
                 (princ "\n... 空Enter! 再選択 ...\n")
                 (setq lineSeg nil)
                )
                ;; 図形が選択された
                (lineSeg
                 (if (/= "LINE" (entity:GetType lineSeg))
                     (progn
                         (princ "\n... 線分ではありません! 再選択 ...\n")
                         (setq lineSeg nil)
                     )
                     (princ "\n... 線分が選択されました。\n")
                 )
                )
            )
        )
        lineSeg
    )
    ;; 線分の始点を取得 // ss:line:sp
    (defun line:GetStartPoint (e) (entity:GetDxf 10 e))
    ;; 線分の終点を取得 // ss:line:ep
    (defun line:GetEndPoint (e) (entity:GetDxf 11 e))
    ;; 2点から直線の方程式を求める ax + by + c = 0
    (defun line:GetEquation (p q / x1 y1 x2 y2 l)
        (setq x1 (car p) y1 (cadr p)
              x2 (car q) y2 (cadr q)
               l (distance p q)
        )
        (if (> l 1.0e-08)
            (mapcar
                (function
                    (lambda (x) (/ x l))
                )
                (list (- y2 y1) (- x1 x2) (- (* x2 y1) (* x1 y2)))
            )
        )
    )
    
    ;; 2直線の交点を求める
    ;; 2直線が平行の場合は nil を返す
    (defun line:GetIntersection (l1 l2 / a1 b1 c1 a2 b2 c2 d)
        (if (zerop
                (setq a1 (car   l1)
                      b1 (cadr  l1)
                      c1 (caddr l1)
                      a2 (car   l2)
                      b2 (cadr  l2)
                      c2 (caddr l2)
                      d (- (* a1 b2) (* a2 b1))
                )
            )
            nil
            (list
                (/ (- (* b1 c2) (* b2 c1)) d)
                (/ (- (* a2 c1) (* a1 c2)) d)
            )
        )
    )
    

    2선분을 선택, 교점을 출력하는 프로그램(inters 함수 사용)



    AutoLISP 함수의 inters를 사용한 프로그램
    ;; inters 関数を使った場合
    (defun c:c:SelectTwoLineAndOutputInters (/ lineSeg1 lineSeg2 ip)
        (setq lineSeg1 (editor:EntselLine "線分1を選択")
              lineSeg2 (editor:EntselLine "線分2を選択")
        )
        ;; 交点を取得して出力
        (if (setq ip (inters
                         (line:GetStartPoint lineSeg1)
                         (line:GetEndPoint lineSeg1)
                         (line:GetStartPoint lineSeg2)
                         (line:GetEndPoint lineSeg2)
                         nil
                      )
            )
            (progn
                (princ "\n交点の座標 : ") (princ ip)
            )
            (princ "\n2つの線分は平行です。\n")
        )
        (princ)
    )
    

    좋은 웹페이지 즐겨찾기