■
Mrさんが出していた問いに反応してみる(id:supermr:20090314)
Q.SRCの画面上のマウスの座標が三角形ABCの中にあるかどうかを取得する関数を作りなさい。
の解
↓
マウスの位置を点Mとする。
この時、線分ABと直線CMが交点を持ち、線分CMが線分CDに含まれるならば点Mは三角形ABCの内部に存在する。(ただし、Dは線分ABと直線CMの交点)
証明とかは割愛。
ベクトル式も表現がめんどくさいのでカット
##三角形の三頂点の座標は A(AX,AY),B(BX,BY),C(CX,CY) で与えられているものとする。 #Call(判定,MouseX,MouseY) = 0 なら中にない。 #Call(判定,MouseX,MouseY) = 1 なら中にある。 #引数はMouseX,MouseYでなくても構わない 判定: XX = Args(1) YY = Args(2) R = (YY - CY) * (BX - AX) - (XX - CX) * (BY - AY) If R = 0 Then If AX = BX and AY = BY Then If (AX >= XX And XX >= CX) Or (AX <= XX And XX <= CX) Then If (AY >= YY And YY >= CY) Or (AY <= YY And YY <= CY) Then Return 1 EndIf EndIf ElseIf XX = CX And YY = CY Then Return 1 EndIf Return 0 Else U = ((CX - AX) * (BY - AY) - (CY - AY) * (BX - AX)) / R T = ((CX - AX) * (YY - CY) - (CY - AY) * (XX - CX)) / R EndIf If U >= 1 And T <= 1 And T >= 0 Then Return 1 EndIf Return 0 #使用例 スタート: Cls Font 12pt Regular AX = 260 AY = 100 BX = 100 BY = 340 CX = 340 CY = 340 M = "点AのX座標 点AのY座標 点BのX座標 点BのY座標 点CのX座標 点CのY座標" Mes = "右Click:Quit 左Click:Change" Do Call 描く MouseX MouseY Call 変更 If KeyState(2) Then break EndIf Loop Mes = "Push Space Key:Quit 左Click:Change" 目標X = -1 目標Y = -1 今X = 240 今Y = 240 Do If 目標X <> MouseX Or 目標Y <> MouseY Then 目標X = MouseX 目標Y = MouseY 基準X = 今X 基準Y = 今Y 刻み = 0.95 EndIf Incr 刻み 0.05 今X = 目標X - Int((目標X - 基準X) / 刻み) 今Y = 目標Y - Int((目標Y - 基準Y) / 刻み) Call 描く 今X 今Y Call 変更 If KeyState(32) Then break EndIf Loop Quit 描く: If Call(判定,Args(1),Args(2)) Then Color #00ff00 Line AX AY XX YY #00ff00 Line BX BY XX YY #00ff00 Line CX CY XX YY #00ff00 Else Color #ffffff Line AX AY XX YY #ffffff Line BX BY XX YY #ffffff Line CX CY XX YY #ffffff EndIf Polygon AX AY BX BY CX CY Paintstring 0 450 "X=$(XX),Y=$(YY)" Paintstring 200 450 Mes Refresh Wait 0.1 ClearPicture return 変更: If KeyState(1) Then Poi = List(AX,AY,BX,BY,CX,CY) Array P Poi "リスト" AutoTalk 0.1;三角形の頂点座標を変えます Suspend For i = 1 to 6 Input PP "$(lindex(M,i))を設定" P[i] If PP <> "" And IsNumeric(PP) And PP <= 480 And PP >= 0 Then P[i] = PP Else Incr i -1 EndIf Next AX = P[1] AY = P[2] BX = P[3] BY = P[4] CX = P[5] CY = P[6] Talk End Endif return