Hello 天文

自動翻譯,請以簡體中文原文校核。

計算機算出了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 章

通用演算法與數值計算 · 全部互動課程