use fj_math::{Circle, Line, Point, Scalar, Transform, Vector};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum Curve {
Circle(Circle<2>),
Line(Line<2>),
}
impl Curve {
pub fn circle_from_radius(radius: impl Into<Scalar>) -> Self {
Self::circle_from_center_and_radius(Point::origin(), radius)
}
pub fn circle_from_center_and_radius(
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
) -> Self {
Self::Circle(Circle::from_center_and_radius(center, radius))
}
pub fn u_axis() -> Self {
let a = Point::origin();
let b = a + Vector::unit_u();
let (self_, _) = Self::line_from_points([a, b]);
self_
}
pub fn v_axis() -> Self {
let a = Point::origin();
let b = a + Vector::unit_v();
let (self_, _) = Self::line_from_points([a, b]);
self_
}
pub fn line_from_points(
points: [impl Into<Point<2>>; 2],
) -> (Self, [Point<1>; 2]) {
let (line, coords) = Line::from_points(points);
(Self::Line(line), coords)
}
pub fn line_from_points_with_coords(
points: [(impl Into<Point<1>>, impl Into<Point<2>>); 2],
) -> Self {
Self::Line(Line::from_points_with_line_coords(points))
}
pub fn point_from_path_coords(
&self,
point: impl Into<Point<1>>,
) -> Point<2> {
match self {
Self::Circle(circle) => circle.point_from_circle_coords(point),
Self::Line(line) => line.point_from_line_coords(point),
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum GlobalPath {
Circle(Circle<3>),
Line(Line<3>),
}
impl GlobalPath {
pub fn x_axis() -> Self {
Self::Line(Line::from_origin_and_direction(
Point::origin(),
Vector::unit_x(),
))
}
pub fn y_axis() -> Self {
Self::Line(Line::from_origin_and_direction(
Point::origin(),
Vector::unit_y(),
))
}
pub fn z_axis() -> Self {
Self::Line(Line::from_origin_and_direction(
Point::origin(),
Vector::unit_z(),
))
}
pub fn circle_from_radius(radius: impl Into<Scalar>) -> Self {
let radius = radius.into();
Self::Circle(Circle::from_center_and_radius(Point::origin(), radius))
}
pub fn line_from_points(
points: [impl Into<Point<3>>; 2],
) -> (Self, [Point<1>; 2]) {
let (line, coords) = Line::from_points(points);
(Self::Line(line), coords)
}
pub fn origin(&self) -> Point<3> {
match self {
Self::Circle(circle) => circle.center() + circle.a(),
Self::Line(line) => line.origin(),
}
}
pub fn point_from_path_coords(
&self,
point: impl Into<Point<1>>,
) -> Point<3> {
match self {
Self::Circle(circle) => circle.point_from_circle_coords(point),
Self::Line(line) => line.point_from_line_coords(point),
}
}
pub fn vector_from_path_coords(
&self,
vector: impl Into<Vector<1>>,
) -> Vector<3> {
match self {
Self::Circle(circle) => circle.vector_from_circle_coords(vector),
Self::Line(line) => line.vector_from_line_coords(vector),
}
}
#[must_use]
pub fn transform(self, transform: &Transform) -> Self {
match self {
Self::Circle(curve) => {
Self::Circle(transform.transform_circle(&curve))
}
Self::Line(curve) => Self::Line(transform.transform_line(&curve)),
}
}
}