

直線が、x軸又はy軸に平行の時、場合分けの対応が必要ですか？何ケースに分ければいいですか？  
よろしくお願いします。  
以下のエラーが、 例7ででます。  
UnboundLocalError: local variable 'a' referenced before assignment

(オリジナルポスト)2本の線分が交差しているか調べる  
<https://qiita.com/tydesign/items/405f1345a437b03b6403>  
(参考)「2本の線分が交差しているか調べる」を参考にpycharmでやってみた。＞ sympyのintersection(entity1, entity2)  
<https://qiita.com/mrrclb48z/items/c1fe2d1f3e7cd12d07cd>

[code]

    from sympy import *
    var('Ax Ay Bx By Cx Cy Dx Dy Kx Ky')
    var('a b c d e f')
    var('x y')
    def myKoutenLine(lineSeg):
        (myAx, myAy), (myBx, myBy), (myCx, myCy), (myDx, myDy) = lineSeg
        if (myAx != myBx and myCx != myDx):
           a=1.0
           d=1.0
        ans = solve([a * Ax + b * Ay + c,  \
                     a * Bx + b * By + c,  \
                     d * Cx + e * Cy + f,  \
                     d * Dx + e * Dy + f,  \
                     a * Kx + b * Ky + c,  \
                     d * Kx + e * Ky + f], \
                    [Kx, Ky,b, c, e, f])
        myKx = ans[0][0].subs({Ax: myAx, Ay: myAy, Bx: myBx, By: myBy, Cx: myCx, Cy: myCy, Dx: myDx, Dy: myDy})
        myKy = ans[0][1].subs({Ax: myAx, Ay: myAy, Bx: myBx, By: myBy, Cx: myCx, Cy: myCy, Dx: myDx, Dy: myDy})
        return myKx,myKx
    # 例1
    lineSeg=((2,3),(11,12),(10, 5),(3,11))
    print('# 例1 ',lineSeg,'->',myKoutenLine(lineSeg))
    # 例7(追加)
    lineSeg=((-10,0),(10,0),(0,-10),( 0,10))
    print('# 例7(追加) ',lineSeg,'->',myKoutenLine(lineSeg))
    
    
[/code]


CC BY-SA 4.0
2021-06-29T12:05:56.870
77856
2021-07-22T10:49:44.717
17199
question
python アルゴリズム sympy
2本の直線の交点計算をsolveでやってみたい。


※ [ヘルプセンター] [よくある質問] に次のように記されています  
どんな質問を聞けば良いですか？  
プログラミングに関する質問はもちろん何でも大歓迎です！ただし以下のことに気をつけてください。

  * 内容が具体的で詳細であること
  * 質問内容をわかりやすく説明すること
  * 誰か一人でも世の中の他のプログラマーに役に立つような内容であること

何を行おうとしているのか, など分かりづらかったために  
こちらで適当に補足してみました

* * *

* * *

#### 概要

記事:
「[2本の線分が交差しているか調べる](https://qiita.com/tydesign/items/405f1345a437b03b6403)」によると

  * AutoLISP を用い, 交差判定の方法に「[3点の回転方向を調べる](https://qiita.com/tydesign/items/d41ac74b5effd87141b8)」を利用している

これを,  
Pythonで(同様に？) 2本の線分が交差しているか調べるために,
数式処理ライブラリー『[SymPy](https://www.sympy.org/)』を利用する

  1. intersection メソッドによる, 交差判定
  2. 線分ではなく直線の交点を求め, (なんやかやして)判定する

* * *

#### どんな場合分けが必要か？ (質問から)

(1) に関して, intersection メソッド呼び出すだけなので, コーディングミスしてないか確認は必要だけど,
交差判定の方法を実装するわけではなく, 必要ないでしょう

(2) では, 線分ではなく直線を用いるので, 交点が線分に含まれているかどうか … 実装によるのでは？

* * *

#### intersection メソッドを利用するコード

Qiita 記事のコードを簡素化してみました  
(質問には現れないが, 以下の処理で一部利用するので)

[code]

    from sympy import Segment
    
    def myKousaHantei(p1, p2, p3, p4):
        seg_p12 = Segment(p1, p2)
        seg_p34 = Segment(p3, p4)
        pt_i = seg_p12.intersection(seg_p34)
        if pt_i:
            return pt_i[0]   # 曲線ではないので, 交点は最大でも 1つ
    
    p1,p2,p3,p4 = ((2,3), (11,12), (10, 5), (3,11))
    myKousaHantei(p1,p2,p3,p4)
    
[/code]

[![実行結果](https://i.stack.imgur.com/YZBfU.png)](https://i.stack.imgur.com/YZBfU.png)

#### 直線の交点を求めるコード

SymPy には `Segment` (線分)の他に `Line` (直線)もあり  
指定の 2点を通る, もしくは 1点と角度を指定することで得られる

[code]

    from sympy import Line, solve, symbols
    from sympy.plotting import plot
    
    p1,p2,p3,p4 = ((2,3), (11,12), (10, 5), (3,11))
    ln_p12 = Line(p1, p2)
    ln_p34 = Line(p3, p4)
    
    expr_a = ln_p12.equation()
    display(expr_a)
    expr_b = ln_p34.equation()
    display(expr_b)
    print(f'交点座標: {solve([expr_a, expr_b])}')
    
    x,y = symbols('x y')
    plot(solve(ln_p12.equation(x, y), y)[0], solve(ln_p34.equation(x, y), y)[0])
    
[/code]

[![実行結果＆グラフ](https://i.stack.imgur.com/kanNx.png)](https://i.stack.imgur.com/kanNx.png)  
直線からそれぞれ方程式を得ることができ

  * `-9*x + 9*y - 9 = 0`
  * `-6*x - 7*y + 95 = 0`

交点の座標は `{x: 88/13, y: 101/13}` と分かる

* * *

質問のエラー発生部分については

  * グローバル変数なのにローカル変数として変更しようとした
  * SymPy の Symbol として定義してるにも拘らず, 数値を代入している

などの問題があり, 直接のエラー原因は前者だけど何を行いたいか今ひとつ分かりづらいところ


CC BY-SA 4.0
2021-07-21T09:46:49.377
78342
2021-07-22T10:49:44.717
2021-07-22T10:49:44.717
43025
43025
77856
answer