首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript 三角函數計算錯誤:弧度制與角度制轉換詳解

     編輯:程式設計綜合問答

問題現象

Math.cos(90)  // 期望 0,實際返回 -0.4480736161291701
Math.sin(180) // 期望 0,實際返回 -1.2246467991473532e-16

根本原因

JavaScript Math 對象所有三角函數參數均為弧度,而非角度。

  • 90° = π/2 ≈ 1.5708 弧度
  • Math.cos(1.5708) ≈ 6.123e-17 ≈ 0 (浮點數精度誤差)

標準轉換公式

// 角度轉弧度
function degToRad(degrees) {
    return degrees * Math.PI / 180;
}

// 弧度轉角度
function radToDeg(radians) {
    return radians * 180 / Math.PI;
}

// 使用示例
console.log(Math.cos(degToRad(90)));   // 6.123233995736766e-17 ≈ 0
console.log(Math.sin(degToRad(30)));   // 0.5
console.log(Math.tan(degToRad(45)));   // 0.9999999999999999 ≈ 1

封裝工具類(推薦)

const Trigonometry = {
    // 基礎轉換
    degToRad: deg => deg * Math.PI / 180,
    radToDeg: rad => rad * 180 / Math.PI,
    
    // 角度制三角函數
    sin: deg => Math.sin(deg * Math.PI / 180),
    cos: deg => Math.cos(deg * Math.PI / 180),
    tan: deg => Math.tan(deg * Math.PI / 180),
    
    // 反三角函數返回角度
    asin: val => Math.asin(val) * 180 / Math.PI,
    acos: val => Math.acos(val) * 180 / Math.PI,
    atan: val => Math.atan(val) * 180 / Math.PI,
    atan2: (y, x) => Math.atan2(y, x) * 180 / Math.PI,
    
    // 雙精度修正 (解決 1e-16 顯示問題)
    round: (val, precision = 10) => 
        Math.round(val * Math.pow(10, precision)) / Math.pow(10, precision)
};

// 使用
console.log(Trigonometry.cos(90));        // 0
console.log(Trigonometry.round(Trigonometry.sin(30))); // 0.5
console.log(Trigonometry.atan2(1, 1));    // 45

浮點數精度陷阱

表達式理論值JS 計算值修正後
Math.cos(Math.PI/2)06.123e-17Trigonometry.round(...) → 0
Math.sin(Math.PI)01.224e-160
Math.tan(Math.PI/4)10.99999999999999991

常見應用場景

1. Canvas 繪圖旋轉

ctx.rotate(Trigonometry.degToRad(45)); // 旋轉 45 度

2. 動畫軌跡計算

// 圓周運動
const x = centerX + radius * Trigonometry.cos(angle);
const y = centerY + radius * Trigonometry.sin(angle);

3. 地理距離計算 (Haversine 公式)

function getDistance(lat1, lon1, lat2, lon2) {
    const R = 6371; // 地球半徑 km
    const dLat = Trigonometry.degToRad(lat2 - lat1);
    const dLon = Trigonometry.degToRad(lon2 - lon1);
    const a = Math.sin(dLat/2)**2 + 
              Math.cos(Trigonometry.degToRad(lat1)) * 
              Math.cos(Trigonometry.degToRad(lat2)) * 
              Math.sin(dLon/2)**2;
    return 2 * R * Math.asin(Math.sqrt(a));
}

避坑提醒

  1. 永遠不要直接傳角度給 Math 三角函數
  2. 反三角函數返回值也是弧度,需轉換為角度
  3. 精度敏感場景:使用 toFixed() 或自定義 round() 修正顯示
  4. WebGL/Three.js 內部同樣使用弧度,傳參前必須轉換
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved