!ベクトルによる平面幾何の計算 - 点、直線(線分)
LET cEps=1e-13 !精度
!ベクトル(a1,a2)とベクトル(b1,b2)との演算
DEF fnDot(a1,a2, b1,b2)=a1*b1+a2*b2 !内積
DEF fnCross(a1,a2, b1,b2)=fnDot(-a2,a1,b1,b2) !擬似外積、パープ内積 a1*b2-a2*b1
DEF fnABS(a,b)=SQR(a*a+b*b) !絶対値、大きさ
DIM a(2),b(2),c(2),d(2) !点A、B、C、D
DATA 4, 4 !A
DATA -1, 1 !B
DATA -3, 2 !C
DATA 3,-4 !D
MAT READ A
MAT READ B
MAT READ C
MAT READ D
SET WINDOW -5,5,-5,5 !グラフを描く
DRAW grid
SET TEXT HEIGHT 0.4
PLOT LINES: A(1),A(2); B(1),B(2) !線分AB
PLOT TEXT ,AT A(1),A(2): "A"
PLOT TEXT ,AT B(1),B(2): "B"
PLOT LINES: C(1),C(2); D(1),D(2) !線分CD
PLOT TEXT ,AT C(1),C(2): "C"
PLOT TEXT ,AT D(1),D(2): "D"
DIM s(2),t(2),u(2),v(2) !作業用
!点Aと点Bを通る直線と点Cと点Dを通る直線との直交・平行判定
!内積が0なら、直交。 外積が0なら、平行。
MAT s=b-a
MAT t=d-c
IF fnDot(s(1),s(2),t(1),t(2))=0 THEN PRINT "直交"
IF fnCross(s(1),s(2),t(1),t(2))=0 THEN PRINT "平行"
!点Aと点Bを通る直線と点Cと点Dを通る直線との交点
MAT s=b-a
MAT t=d-c
LET DD=fnCross(t(1),t(2),s(1),s(2))
IF DD<>0 THEN
MAT u=c-a
MAT v=( fnCross(t(1),t(2),u(1),u(2))/DD ) * s
MAT v=a+v
MAT PRINT v; !交点
ELSE
PRINT "平行です。"
END IF
!点Aと点Bを結ぶ線分と点Cと点Dを結ぶ線分との交点
MAT s=b-a
MAT t=c-a
LET d1=fnCross(s(1),s(2),t(1),t(2))
!MAT s=b-a
MAT t=d-a
LET d2=fnCross(s(1),s(2),t(1),t(2))
MAT s=d-c
MAT t=a-c
LET d3=fnCross(s(1),s(2),t(1),t(2))
!MAT s=d-c
MAT t=b-c
LET d4=fnCross(s(1),s(2),t(1),t(2))
IF d1*d2<=0 AND d3*d4<=0 THEN
MAT u=b-a
MAT u=( ABS(d3)/(ABS(d3)+ABS(d4)) ) * u
MAT u=a+u
MAT PRINT u; !交点
ELSE
PRINT "交差なし"
END IF
!点Cと、点Aと点Bを通る直線との位置関係
MAT s=b-a
MAT t=c-a
LET DD=fnCross(s(1),s(2),t(1),t(2))
IF DD=0 THEN
PRINT "線上"
ELSEIF DD>0 THEN
PRINT "左側"
ELSE
PRINT "右側"
END IF
!点Cが、点Aと点Bを結ぶ線分上にあるかどうかの判定
!三角不等式 |a-b|≦|a-c|+|c-b|
MAT s=a-c
MAT t=c-b
MAT u=a-b
IF fnABS(s(1),s(2))+fnAbs(t(1),t(2))<fnABS(u(1),u(2))+cEps THEN PRINT "線上"
!点Cと、点Aと点Bを通る直線との距離
MAT s=b-a
MAT t=c-a
PRINT ABS(fnCross(s(1),s(2),t(1),t(2))) / fnABS(s(1),s(2))
!点Cと、点Aと点Bを結ぶ線分との距離(最近接点)
MAT s=b-a
MAT t=c-a
MAT u=c-b
IF fnDot(s(1),s(2),t(1),t(2))<cEps THEN !点A外側
PRINT fnABS(t(1),t(2)) !点Aとの距離
ELSEIF fnDot(-s(1),-s(2),u(1),u(2))<cEps THEN !点B外側
PRINT fnABS(u(1),u(2)) !点Bとの距離
ELSE !線分AB内
PRINT ABS(fnCross(s(1),s(2),u(1),u(2))) / fnABS(s(1),s(2)) !垂線
END IF
END
!投稿(記述例)、数学、ベクトルと図形方程式、アルゴリズム、ゲーム、当たり判定