計算機算出了32°,為什麼目標卻在相反方向?
兩個相反方向能有相同的斜率。只留下一個比值,就丟掉了你真正需要的符號。
你知道目標在左下方,但程式卻畫了一條朝右上的箭頭。算式也許沒敲錯:如果先把兩個負數相除,得到的正比值已經無法告訴你目標到底在哪個象限。
開啟互動課程 →
先猜一下
向右上和向左下的兩條線,y/x比值可能一樣嗎?
查看答案與解釋
可能 — 兩分量同時變號,比值不變,但方向相差180°。
再把體驗和科學連結起來
先認清目標所在的象限
藍色點的位置由x與y共同決定。單一參數atan只讀比值,兩個負號會在除法裡抵消。
atan(y/x)的回傳範圍只有−90°至90°
把兩個分量分別交給atan2
atan2(y,x)保留正負號,可以區分左下與右上;它的參數順序要依照語言文檔確認。
本項目使用 Math.atan2(y,x)
方向正確,還要用對角度單位
JavaScript三角函數輸入為弧度。把212這樣的度數直接交給sin,會把它誤認為212弧度。
弧度 = 度 × π/180
特殊情況不能靠假數蒙混過去
軸上方向可以定義,零向量卻不能。負數的向下取整與截斷也不同,曆法代碼尤其不能混用。
atan2(0,0)無幾何方向;floor(−7.83)=−8
把計算鏈展開
θ弧度 = atan2(y,x) θ度 = θ弧度 × 180/π θ圈内 = ((θ度 mod 360)+360) mod 360
atan2先傳y,再傳x;它保留象限資訊。 x=y=0時沒有幾何方向,即使程式回傳數值也不能當作方向。
試一試
先看原書左下方例,再把兩個分量都改成正數。斜率比值一樣,但方向必須相差半圈;最後試零向量。
動手看一遍 →
符號不用背
- atan(y/x)
- 只看比值,無法獨自區分相差180°的方向
- atan2(y,x)
- 分別保留兩個分量,判斷象限
- θ / θπ/180
- 角度值(度)/對應弧度值
- floor / trunc
- 向負無窮取整 / 向零截斷,兩者不是同一操作
演算法、精確度與適用範圍
補第1章正確象限與語言單位陷阱。使用原書A=−0.5712、B=−0.9139,界面y=A、x=B;atan(A/B)約32°而正確方向約212°。單參數atan在x=0時不作除法演示;atan2仍可判定軸上方向,但(0,0)沒有幾何方向,不能沿用JavaScript atan2(0,0)=0而偽造答案。右圖比較同一角度轉換成弧度後與誤把度數直接交給Math.sin的結果;同時顯示僅由cos反推時的0–180°範圍。負數floor/trunc取整與第7章一致。舊角度入門課已有度分秒負號、角度小時和繞圈;這裡不重複它。數學入口另實現原書大角歸一化測試、Horner多項式和數值週期項表求和,核對與直接展開一致;不把舊機型速度測試推論成現代JavaScript性能保證。安全分支與迭代上限的實踐另見一般求根課。
我的理解檢查
本項目用哪一種函數保留兩個分量的符號?
atan2(y,x) — atan2分別接收y和x,不先丟掉象限資訊。
θ以度表示時,可以直接Math.sin(θ)嗎?
不可以,先換弧度 — JavaScript的sin輸入是弧度。
兩個分量都為0,正確的方向要怎麼報告?
沒有定義 — 零向量沒有方向;函數傳回的數字不能取代幾何定義。
先保留方向分量與符號,再轉換單位;程式給出數字,不代表那個數字有正確的幾何意義。
Jean Meeus · Astronomical Algorithms, 2nd ed. · 第 1 章