CC++ & Algorithm

C++中的三角函数 sin 和 cos

困难32
语言版本:C++Python
概述:用三角形和圆来理解sin和cos,并学会在C++中计算它们。

从三角形到圆:用C++的sin和cos计算角度位置

在学习编程时,你可能会遇到需要计算角度、方向或物体运动的情况。比如,让一个小球沿着圆形轨迹运动,或者计算一个角色在屏幕上的坐标。这些都需要用到两个重要的数学函数:sin(正弦)和cos(余弦)。在C++中,我们可以直接用 <cmath> 库里的 sin()cos() 函数搞定它。


什么是 sin 和 cos?先看直角三角形

在数学课上,我们学过直角三角形:一个角是直角,另外两个角是锐角。假设你有一个直角三角形,其中一个锐角是 theta(用符号 θ 表示)。那么,sin(θ) 就是对边除以斜边,cos(θ) 就是邻边除以斜边。

比如,一个直角三角形中,斜边长为 5,30度角对边的长度是 2.5,邻边长度大约是 4.33。那么:

  • sin(30°) = 对边 / 斜边 = 2.5 / 5 = 0.5
  • cos(30°) = 邻边 / 斜边 ≈ 4.33 / 5 ≈ 0.866

这很好理解,但编程中我们更常用一个更直观的模型——单位圆


单位圆:旋转角度看 sin 和 cos

想象一个半径为1的圆,圆心在坐标原点 (0,0)。从圆心出发,沿着x轴正方向画一条半径(指向右边),然后逆时针旋转 θ 角度,得到另一条半径。这条半径与圆的交点,它的 x 坐标就是 cos(θ),y 坐标就是 sin(θ)。

           y
           ↑
           |   . (cosθ, sinθ)
           |  /
           | /
           |/ θ
      -----+------→ x
           |

所以,sin 和 cos 其实就是旋转一个角度后,点在圆上的位置。这个特性在游戏开发中非常有用:如果你想在屏幕上画一个圆上的点,或者让一个角色绕另一个角色旋转,都可以用 sincos 计算坐标。

生活例子:假设你骑旋转木马,马绕中心转圈。从正上方看,马的位置可以用它到中心的连线与正东方向的夹角来描述。如果马离中心有1米(半径),那么马的 x 坐标(东方向)就是 cos(角度),y 坐标(北方向)就是 sin(角度)。


C++ 中的角度单位:弧度

在 C++ 中,sin()cos() 函数接受的参数是弧度,而不是我们熟悉的“度”。就像温度有摄氏和华氏一样,角度也有两种单位:

  • :一圈是360度,我们课堂常用。
  • 弧度:一圈是 2π 弧度(π ≈ 3.14159265),数学和编程中更常用。

换算关系:180度 = π 弧度,所以:

  • 弧度 = 度数 × π / 180
  • 度数 = 弧度 × 180 / π

<cmath> 库中定义了一个常量 M_PI 表示 π 的值。如果你用的是某些编译器(比如 Windows 下的 VS),可能没有定义 M_PI,可以自己定义一个:

const double PI = 3.14159265358979323846;

所以,计算30度的正弦值,要写成:

double rad = 30.0 * M_PI / 180.0;   // 将30度转换为弧度
double result = sin(rad);

新手最容易犯的错误

1. 忘记包含头文件

// 错误:没有 #include <cmath>
sin(0.5);   // 编译报错

正确做法:在文件开头加上 #include <cmath>

2. 度数当作弧度直接传

double s = sin(30);   // 想求sin30°,但传入了30弧度(约1719度)
// 结果不是0.5,而是一个奇怪的小数

正确做法:先转换单位。

3. 忘记 M_PI 可能未定义

某些编译器(如 MSVC)不提供 M_PI,会报错“标识符未定义”。安全写法:自己定义 π,或者用 acos(-1.0) 来获取 π 的精确值(因为 arccos(-1)=π)。

const double PI = acos(-1.0);   // 更精确的π
double rad = deg * PI / 180.0;

4. 混淆 sincos 对应的坐标

在单位圆中:cos 是 x 坐标,sin 是 y 坐标。不要弄反了,否则画出的点会旋转 90 度。


完整示例:生成 0°~360° 的正余弦值表

下面的程序会打印从0°到360°(每隔15°)的 sin 和 cos 值,并展示它们的关系(比如 sin 和 cos 的最大值都是1,最小值-1)。

#include <iostream>
#include <cmath>   // 包含 sin、cos、M_PI
using namespace std;

int main() {
    const double PI = acos(-1.0);             // 自己定义圆周率π
    cout << "角度(度)  |  sin(θ)     |  cos(θ)" << endl;
    cout << "----------|-------------|-------------" << endl;
    
    for (int deg = 0; deg <= 360; deg += 15) {   // 每隔15度计算一次
        double rad = deg * PI / 180.0;          // 度转弧度
        double s = sin(rad);                    // 计算正弦值
        double c = cos(rad);                    // 计算余弦值
        // 输出时保留4位小数,让表格对齐
        cout << deg << "        | " << s << " | " << c << endl;
    }
    return 0;
}

运行这段代码,你会看到:

  • 当角度=0°,sin=0,cos=1
  • 当角度=90°,sin=1,cos=0
  • 当角度=180°,sin=0,cos=-1
  • 当角度=360°,又回到 sin=0,cos=1(一圈结束)

你可以用手机计算器验证一下,比如 30° 的 sin 是不是 0.5。注意:计算器通常需要切换到“度”模式,但 C++ 程序里必须用弧度。


实际应用场景

  1. 做圆周运动:假设你想让一个精灵在屏幕上绕着中心(400, 300)以半径200像素旋转,每帧让角度增加,然后利用 sin/cos 计算出精灵坐标:

    double angle = 0.0;              // 当前角度(弧度)
    double radius = 200.0;           // 旋转半径
    double centerX = 400.0, centerY = 300.0;
    double x = centerX + radius * cos(angle);
    double y = centerY + radius * sin(angle);
    
  2. 计算两点之间的方向:如果你知道两个点的坐标,可以用 atan2(y, x) 求夹角(这是另一个三角函数,常用于游戏)。而 sincos 则是反过来,已知角度和距离求坐标。

  3. 画波浪线或声波图形:比如用 sin 函数生成一条正弦曲线,在物理模拟中很常见。


相关知识点指引

  • 反三角函数asin()acos()atan()atan2(),用于根据 y/x 比值反求角度。
  • tan 和 atan:正切 tan(θ)=sin(θ)/cos(θ),用于计算斜率。
  • 向量与旋转:用 sin/cos 实现向量的旋转,是计算机图形学的基础。
  • 弧度制深入:了解为什么数学和编程更偏爱弧度(微分简单、自然)。
  • C++ 数学库的其他函数powsqrtexplog 等,都在 <cmath> 里。

如果你已经掌握了 sin 和 cos,下一步可以试试用它们来做一个“钟表指针”动画,或者模拟一个旋转的卫星。记得每次都要先转换角度到弧度哦!

例题精讲

1单选题

在C++中,sin()和cos()函数接受的角度参数单位是什么?

A度数(degree)
B弧度(radian)
C梯度(gradian)
D圆周率(pi)
2判断题

在C++中,sin(x)和cos(x)的返回值范围是[-1, 1]。

3填空题
以下代码试图输出sin(π/2)的值,请补充完整。

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double pi = acos(-1.0);
    double x = pi / 2;
    double result = ___(x);
    cout << result << endl;
    return 0;
}
4单选题

执行以下代码后,输出结果最接近哪个值? #include <iostream> #include <cmath> using namespace std; int main() { double result = cos(0.0); cout << result << endl; return 0; }

A0.0
B0.5
C1.0
D-1.0
5填空题
以下程序从输入读取一个角度值(度数),输出该角度的sin和cos值,保留两位小数。请补充空缺的表达式。

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

int main() {
    double degree;
    cin >> degree;
    double radian = degree * ___ / 180.0;
    double s = sin(radian);
    double c = cos(radian);
    cout << fixed << setprecision(2);
    cout << s << " " << c << endl;
    return 0;
}