cgmath
cgmath copied to clipboard
New Transformation API
Ok, so I have been experimting with a new transformation API. Here is one idea:
/// A type that can be interpreted as a geometric transformation.
pub trait Transformation: One + ScalarMul where
Self::Scalar: BaseFloat,
{
type Vector: InnerSpace<Scalar = Self::Scalar>;
type Point: EuclideanSpace<Scalar = Self::Scalar, Diff = Self::Vector>;
fn transform_vector(&self, vector: Self::Vector) -> Self::Vector;
fn transform_point(&self, point: Self::Point) -> Self::Point;
}
/// A transformation that can apply a translation.
pub trait Translation: Transformation where
Self::Scalar: BaseFloat,
{
fn from_translation(translation: Self::Vector) -> Self;
}
/// A transformation that can apply a uniform scale factor.
pub trait UniformScale: Transformation where
Self::Scalar: BaseFloat,
{
fn from_scale(factor: Self::Scalar) -> Self;
}
/// A transformation that can apply a scale factor that is different in each
/// dimension.
pub trait NonUniformScale: UniformScale where
Self::Scalar: BaseFloat,
{
fn from_non_uniform_scale(scale: Self::Vector) -> Self;
}
/// A transformation that can apply a rotation.
pub trait Rotation: Transformation where
Self::Scalar: BaseFloat,
{
type Angle: Angle<Unitless = Self::Scalar>;
}
/// A transformation that can apply a rotation in 2-dimensional space.
pub trait Rotation2d: Rotation where
Self::Scalar: BaseFloat,
Self: From<<Self as Rotation>::Angle>,
{}
/// A transformation that can apply a rotation in 3-dimensional space.
pub trait Rotation3d: Rotation where
Self::Scalar: BaseFloat,
Self: From<Euler<<Self as Rotation>::Angle>>,
{
fn from_axis_angle(axis: Self::Vector, angle: Self::Angle) -> Self;
fn from_angle_x(theta: Self::Angle) -> Self;
fn from_angle_y(theta: Self::Angle) -> Self;
fn from_angle_z(theta: Self::Angle) -> Self;
}
Thoughts? Any ideas for improvements?
Still need to figure out how inversion fits into this...
cc. #347 #337
You can have a default implementation for transform_vector
, based on the transform_point
one.
I don't think that building traits on top just to have more constructors is an elegant solution. Imagine, how many traits would the old Decomposed
struct need to implement - Transform
, Translation
, Scale
, NonUniformScale
, Rotation
, Rotation3d
, maybe more.
Yeah, I'm not sure - just playing around still. :/