// MoonGeo - 工具函数
// ==================== 基本数学运算 ====================
///|
/// 计算平方
pub fn square(x : Double) -> Double {
x * x
}
///|
/// 计算立方
pub fn cube(x : Double) -> Double {
x * x * x
}
///|
/// 计算绝对值
pub fn abs(x : Double) -> Double {
if x < 0.0 {
-x
} else {
x
}
}
///|
/// 计算最大值
pub fn max(a : Double, b : Double) -> Double {
if a > b {
a
} else {
b
}
}
///|
/// 计算最小值
pub fn min(a : Double, b : Double) -> Double {
if a < b {
a
} else {
b
}
}
///|
/// 安全除法,分母为零时返回默认值
pub fn safe_div(num : Double, den : Double, fallback : Double) -> Double {
if abs(den) <= EPSILON {
fallback
} else {
num / den
}
}
///|
/// 判断两个浮点数是否近似相等
pub fn approx_equal(a : Double, b : Double, tolerance : Double) -> Bool {
abs(a - b) < tolerance
}
///|
/// 限制值在范围内
pub fn clamp(value : Double, min_val : Double, max_val : Double) -> Double {
if value < min_val {
min_val
} else if value > max_val {
max_val
} else {
value
}
}
// ==================== 三角函数 ====================
///|
/// 角度转弧度
pub fn deg_to_rad(deg : Double) -> Double {
deg * PI / 180.0
}
///|
/// 弧度转角度
pub fn rad_to_deg(rad : Double) -> Double {
rad * 180.0 / PI
}
///|
/// 正弦函数近似 (泰勒级数)
pub fn sin_approx(x : Double) -> Double {
let mut a = x
while a > PI {
a = a - 2.0 * PI
}
while a < -PI {
a = a + 2.0 * PI
}
let x2 = a * a
let x3 = x2 * a
let x5 = x3 * x2
let x7 = x5 * x2
a - x3 / 6.0 + x5 / 120.0 - x7 / 5040.0
}
///|
/// 余弦函数近似 (泰勒级数)
pub fn cos_approx(x : Double) -> Double {
let mut a = x
while a > PI {
a = a - 2.0 * PI
}
while a < -PI {
a = a + 2.0 * PI
}
let x2 = a * a
let x4 = x2 * x2
let x6 = x4 * x2
1.0 - x2 / 2.0 + x4 / 24.0 - x6 / 720.0
}
///|
/// 正切函数近似
pub fn tan_approx(x : Double) -> Double {
let sin_x = sin_approx(x)
let cos_x = cos_approx(x)
if abs(cos_x) < EPSILON {
0.0
} else {
sin_x / cos_x
}
}
///|
/// 自然对数近似
pub fn ln_approx(x : Double) -> Double {
if x <= 0.0 {
return 0.0
}
if x == 1.0 {
return 0.0
}
if x > 1.0 {
return -ln_approx(1.0 / x)
}
let u = x - 1.0
let mut sum = u
let mut term = u
let mut i = 2
while i < 50 {
term = term * -u
sum = sum + term / i.to_double()
if abs(term) < EPSILON {
break
}
i = i + 1
}
sum
}
///|
/// 指数函数近似 (e^x)
pub fn exp_approx(x : Double) -> Double {
if x > 10.0 {
return 0.0 // 溢出
}
if x < -10.0 {
return 0.0
}
let mut sum = 1.0
let mut term = 1.0
let mut i = 1
while i < 20 {
term = term * x / i.to_double()
sum = sum + term
if abs(term) < EPSILON {
break
}
i = i + 1
}
sum
}