atan
2026/4/14大约 5 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — atan
atan
定义
atan() 是反正切函数(arc tangent)——它是 tan() 的"反过来的操作"。
如果 tan() 是"给我一个角度,告诉我正切值是多少",那 atan() 就是"我知道正切值了,告诉我角度是多少"。
打个比方:你看到一座山坡,量了一下"每走 1 米水平距离,海拔升高 2 米"(正切值 = 2)。你想知道这个坡的角度是多少,就可以用 atan(2) 来算——结果大约是 63.4 度,一个相当陡的坡。
注意:atan() 只能告诉你角度的绝对大小,无法判断方向(正还是负、左还是右)。因为 tan(45度) 和 tan(45度+180度) 的值相同,atan() 无法区分它们。如果你需要完整的方向信息,应该用 atan2()。
角度单位是弧度,不是度数
atan() 返回的结果是弧度,不是度数。如果需要度数,用 rad_to_deg() 转换。
函数签名
C#
// 使用 Godot 的 Mathf(推荐,返回 float)
public static float Atan(float s)GDScript
func atan(s: float) -> float参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
s | float | 是 | 正切值,可以是任意实数(正数、负数、零都可以) |
返回值
类型: float
返回一个弧度值,范围在 -PI/2 到 PI/2 之间(即 -90 度到 90 度)。
| 输入 | 输出(弧度) | 输出(约等于度数) | 说明 |
|---|---|---|---|
| 0.0 | 0.0 | 0 度 | tan(0) = 0 的逆运算 |
| 1.0 | PI/4 | 45 度 | tan(45度) = 1 的逆运算 |
| -1.0 | -PI/4 | -45 度 | tan(-45度) = -1 的逆运算 |
| 很大的数 | 接近 PI/2 | 接近 90 度 | 正切值越大,角度越接近 90 度 |
代码示例
基础用法:从正切值反推角度
C#
using Godot;
public partial class AtanExample : Node
{
public override void _Ready()
{
// 已知正切值,反推角度
float a1 = Mathf.Atan(0f);
GD.Print("atan(0) = " + Mathf.RadToDeg(a1) + " 度");
// 运行结果: atan(0) = 0 度
float a2 = Mathf.Atan(1f);
GD.Print("atan(1) = " + Mathf.RadToDeg(a2) + " 度");
// 运行结果: atan(1) = 45 度
float a3 = Mathf.Atan(-1f);
GD.Print("atan(-1) = " + Mathf.RadToDeg(a3) + " 度");
// 运行结果: atan(-1) = -45 度
float a4 = Mathf.Atan(100f);
GD.Print("atan(100) = " + Mathf.RadToDeg(a4) + " 度");
// 运行结果: atan(100) = 89.42706 度(非常接近 90 度)
}
}GDScript
extends Node
func _ready():
# 已知正切值,反推角度
var a1 = atan(0.0)
print("atan(0) = ", rad_to_deg(a1), " 度")
# 运行结果: atan(0) = 0 度
var a2 = atan(1.0)
print("atan(1) = ", rad_to_deg(a2), " 度")
# 运行结果: atan(1) = 45 度
var a3 = atan(-1.0)
print("atan(-1) = ", rad_to_deg(a3), " 度")
# 运行结果: atan(-1) = -45 度
var a4 = atan(100.0)
print("atan(100) = ", rad_to_deg(a4), " 度")
# 运行结果: atan(100) = 89.42706 度(非常接近 90 度)实际场景:计算斜坡的角度
C#
using Godot;
public partial class SlopeAngle : Node
{
public override void _Ready()
{
// 已知斜坡的水平距离和垂直高度差
float horizontalDist = 100f;
float verticalRise = 30f;
// 计算正切值 = 垂直 / 水平
float slope = verticalRise / horizontalDist;
// 用 atan 反推出角度
float angle = Mathf.Atan(slope);
GD.Print($"水平: {horizontalDist}m, 垂直: {verticalRise}m");
GD.Print($"坡度: {Mathf.RadToDeg(angle):F1} 度");
// 运行结果: 水平: 100m, 垂直: 30m
// 运行结果: 坡度: 16.7 度
}
}GDScript
extends Node
func _ready():
# 已知斜坡的水平距离和垂直高度差
var horizontal_dist := 100.0
var vertical_rise := 30.0
# 计算正切值 = 垂直 / 水平
var slope := vertical_rise / horizontal_dist
# 用 atan 反推出角度
var angle := atan(slope)
print("水平: %dm, 垂直: %dm" % [horizontal_dist, vertical_rise])
print("坡度: %.1f 度" % rad_to_deg(angle))
# 运行结果: 水平: 100m, 垂直: 30m
# 运行结果: 坡度: 16.7 度进阶用法:理解 atan 与 atan2 的区别
C#
using Godot;
public partial class AtanVsAtan2 : Node
{
public override void _Ready()
{
// 情况一:点在右上角 (x=1, y=1)
float slope1 = 1f / 1f; // y/x = 1
float angleAtan1 = Mathf.Atan(slope1);
float angleAtan21 = Mathf.Atan2(1f, 1f);
GD.Print($"点(1,1): atan={Mathf.RadToDeg(angleAtan1):F1} 度, atan2={Mathf.RadToDeg(angleAtan21):F1} 度");
// 运行结果: 点(1,1): atan=45.0 度, atan2=45.0 度
// 情况二:点在左下角 (x=-1, y=-1)
float slope2 = -1f / -1f; // y/x = 1(和情况一一样!)
float angleAtan2 = Mathf.Atan(slope2);
float angleAtan22 = Mathf.Atan2(-1f, -1f);
GD.Print($"点(-1,-1): atan={Mathf.RadToDeg(angleAtan2):F1} 度, atan2={Mathf.RadToDeg(angleAtan22):F1} 度");
// 运行结果: 点(-1,-1): atan=45.0 度, atan2=-135.0 度
GD.Print("结论: atan 无法区分对角方向的点,而 atan2 可以精确判断方向");
// 运行结果: 结论: atan 无法区分对角方向的点,而 atan2 可以精确判断方向
}
}GDScript
extends Node
func _ready():
# 情况一:点在右上角 (x=1, y=1)
var slope1 := 1.0 / 1.0 # y/x = 1
var angle_atan1 := atan(slope1)
var angle_atan2_1 := atan2(1.0, 1.0)
print("点(1,1): atan=%.1f 度, atan2=%.1f 度" % [rad_to_deg(angle_atan1), rad_to_deg(angle_atan2_1)])
# 运行结果: 点(1,1): atan=45.0 度, atan2=45.0 度
# 情况二:点在左下角 (x=-1, y=-1)
var slope2 := -1.0 / -1.0 # y/x = 1(和情况一一样!)
var angle_atan2 := atan(slope2)
var angle_atan2_2 := atan2(-1.0, -1.0)
print("点(-1,-1): atan=%.1f 度, atan2=%.1f 度" % [rad_to_deg(angle_atan2), rad_to_deg(angle_atan2_2)])
# 运行结果: 点(-1,-1): atan=45.0 度, atan2=-135.0 度
print("结论: atan 无法区分对角方向的点,而 atan2 可以精确判断方向")
# 运行结果: 结论: atan 无法区分对角方向的点,而 atan2 可以精确判断方向注意事项
- 无法判断完整方向:
atan()只能返回 -90 度到 90 度之间的角度。它无法区分"右上角"和"左下角"这两个方向,因为它们的正切值相同。在游戏开发中,大多数情况应该用atan2()代替。 - 输入无限制:和
asin()、acos()不同,atan()可以接受任意实数输入,不存在"无效范围"的问题。 - 返回的是弧度:结果需要用
rad_to_deg()转换才能得到度数。 - 适合已知斜率的场景:当你手头只有一个比值(坡度、斜率),不需要判断方向时,
atan()就够用了。 - C# 中的选择:推荐使用
Mathf.Atan()(返回float),而不是Math.Atan()(返回double)。
