已知長方形面板放正時,上方二頂點座標分別為 A(0,0) 及 B(500,0),欲在面板內
C(x1,x2) 點上打雷射光(如圖一),由於面板被輸送帶送上機台時不一定會放正,
如圖二、圖三,原面板放正時的 A、B 點會分別對應到機台相機偵測到的 A'(a1,a2)、
B'(b1,b2) 點,機台影像軟體需算出 C 點對應的 C'(c1,c2) 點並在該點打雷射光,
執行程式時,請依序輸入座標 C(x1,x2)、A'(a1,a2)、B'(b1,b2),輸入完後自動算出
C'(c1,c2)點座標,其中,c1, c2 取到小數點第四位。

         
圖一
圖二
圖三

輸入說明
     輸入 6 個數字,分別代表座標 C(x1,x2)、A'(a1,a2)、B'(b1,b2)的點座標,
     各數字間以逗號隔開。

輸出說明
     輸出 2 個數字代表 C'(c1,c2)點座標,數字間以逗號隔開,輸出數值以
     四捨五入取到小數點以下第四位。

範例
輸入輸出
300,500,50,50,550,50 350.0000,550.0000
300,500,50,50,548.0973,93.5779 305.2805,574.2441

學理說明:




今題意已知故定座標分別為 A ( 0 , 0 ) ,B ( 500 ,0 )
並提供新的 A' 與 B' 座標,則
圖四
圖五
圖六

如圖四
A' 與 A 座標關係為
A'x = Ax + dx ,A'y = Ay + dy
dx = A'x - Ax ,dy = A'y - Ay

同理 B' 與 B 的新座標為
B'x = Bx + dx ,B'y = By + dy
今使 A' 與 A 重合 (如圖五)
則 A'x - dx ,A'y - dy 即為所求。

同理 B' 將移到新的座標
B'x - dx ,B'y - dy (如圖五)

當綠框逆時針旋轉θ,將使 C' 與 C 點重合。
(如圖六)
則 C' 與 C 的關係式為
C'x = Cx∙cosθ - Cy∙sinθ
C'y = Cx∙sinθ + Cy∙cosθ

Youtube 影音說明

     因座標值往下的數值是遞增,這原本就是電腦螢幕的座標表示方式,
然而,數學狄卡爾座標體系往下是負(遞減),推導公式時是否衝突?
答案是不會的,因為把本題圖像(圖六)垂直翻轉,就是狄卡爾直角座標(圖七)。

圖七
圖八
圖九

演算法步驟:

步驟一、
計算 dx 與 dy。
dx = x' - x , dy = y' - y

步驟二、
將 A' 點與 A 點重合後 B' 的新座標。
B"x = B'x - dx , B"y = B'y - dy

步驟三、
計算 夾角θ ,
此題計算夾角時,注意 θ 是否可能90o( 如圖十) ? 若題意沒保證非90o則要防範。

圖十

If ( A'x = B'x ) Then "分母為零表示垂直
    th = π/2
Else
    th = Atan( (A'y-B'y) / (A'x-B'x) )
EndIf

備註:取 π/2 的方法有幾種,參考看看。
1) 3.14159 / 2 '此法較不精確
2) Math.Atan(1) * 2 '取反三角 Atan(1) 為 π/4
3) Math.PI / 2 '直接使用內部定義

步驟四、
計算新的 C" 座標。
先旋轉 : C"x = Cx * Cos(th) - Cy * Sin(th) ,c"y = Cx * Sin(th) + Cy * Cos(th)
再移位 : C"x = C"x + dx ,C"y = C"y + dy



家豪版

Dim coordinate As Array, i As Integer
Dim c_x As Double, c_y As Double, th As Double, dx As Double, dy As Double, B__x As Double, B__y As Double
coordinate = TextBox1.Text.Split(",")
dx = coordinate(A_x) - Ax : dy = coordinate(A_y) - Ay
B__x = coordinate(B_x) - dx : B__y = coordinate(B_y) - dy
If (B__x = 0) Then
    th = Math.PI * 2
Else
    th = Math.Atan(B__y / B__x)
End If
c_x = coordinate(Cx) * Math.Cos(th) - coordinate(Cy) * Math.Sin(th) + dx
c_y = coordinate(Cx) * Math.Sin(th) + coordinate(Cy) * Math.Cos(th) + dy
TextBox2.Text = Format(c_x, ".0000") & " , " & Format(c_y, ".0000")



昊朋版


黃翰版