pub type ESign = i8;
const CONCAVE: i8 = -1;
const TANGENTIAL: i8 = 0;
const CONVEX: i8 = 1;
fn signum_enum(a: f64) -> ESign {
if a > 0.0 { CONVEX } else if a < 0.0 { CONCAVE } else { TANGENTIAL }
}
pub fn area_tri_signed_v2_alt_2x(v1: &[f64; 2], v2: &[f64; 2], v3: &[f64; 2]) -> f64 {
((v1[0] * (v2[1] - v3[1])) + (v2[0] * (v3[1] - v1[1])) + (v3[0] * (v1[1] - v2[1])))
}
pub fn span_tri_v2_sign(v1: &[f64; 2], v2: &[f64; 2], v3: &[f64; 2]) -> ESign {
return signum_enum(area_tri_signed_v2_alt_2x(v3, v2, v1));
}
我设法将它们变成通用函数,但最终我不得不复制类型边界。
use std::ops::{Mul, Sub, Add};
fn signum_enum<T: Default + PartialOrd>(a: T) -> ESign {
let zero = T::default();
if a > zero { CONVEX } else if a < zero { CONCAVE } else { TANGENTIAL }
}
pub fn area_tri_signed_v2_alt_2x<T: Default + PartialOrd + Copy + Mul<Output=T> + Sub<Output=T> + Add<Output=T>>(
v1: &[T; 2],
v2: &[T; 2],
v3: &[T; 2]) -> T
{
((v1[0] * (v2[1] - v3[1])) + (v2[0] * (v3[1] - v1[1])) + (v3[0] * (v1[1] - v2[1])))
}
pub fn span_tri_v2_sign<T: Default + PartialOrd + Copy + Mul<Output=T> + Sub<Output=T> + Add<Output=T>>(
v1: &[T; 2],
v2: &[T; 2],
v3: &[T; 2]) -> ESign
{
return signum_enum(area_tri_signed_v2_alt_2x(v3, v2, v1));
}
有没有办法在一个地方定义这些功能并在多个通用函数中重用它们?
答案 0 :(得分:2)
最简单的方法是定义一个新的特征,它需要你正在处理的所有边界:
pub trait Floatlike: Default + PartialOrd + Copy +
Mul<Output=Self> + Sub<Output=Self> + Add<Output=Self> {}
并由满足这些边界的所有类型实现:
impl<T> Floatlike for T where T: Default + PartialOrd + Copy +
Mul<Output=T> + Sub<Output=T> + Add<Output=T> {}
然后绑定在那个特性上:
pub fn area_tri_signed_v2_alt_2x<T: Floatlike>(...)
pub fn span_tri_v2_sign<T: Floatlike>(...)