fj_math/
segment.rs

1use std::fmt;
2
3use crate::Scalar;
4
5use super::Point;
6
7/// A line segment, defined by its two end points
8///
9/// The dimensionality of the segment is defined by the const generic `D`
10/// parameter.
11#[derive(Clone, Copy, Eq, Default, PartialEq, Hash, Ord, PartialOrd)]
12#[repr(C)]
13pub struct Segment<const D: usize> {
14    points: [Point<D>; 2],
15}
16
17impl<const D: usize> Segment<D> {
18    /// Construct a segment from two points
19    ///
20    /// # Panics
21    ///
22    /// Panics, if the points are coincident.
23    pub fn from_points(points: [impl Into<Point<D>>; 2]) -> Self {
24        let points = points.map(Into::into);
25        let [a, b] = points;
26
27        assert!(a != b, "Invalid segment; both points are identical: {a:?}");
28
29        Self { points }
30    }
31
32    /// Access the points of the segment
33    pub fn points(&self) -> [Point<D>; 2] {
34        self.points
35    }
36
37    /// Compute the center point of the segment
38    pub fn center(&self) -> Point<D> {
39        let [a, b] = self.points();
40        a + (b - a) / Scalar::TWO
41    }
42
43    /// Create a segment with the same points in the opposite order
44    pub fn reverse(mut self) -> Self {
45        self.points.reverse();
46        self
47    }
48}
49
50impl Segment<2> {
51    /// Convert the 2-dimensional segment to a Parry segment
52    pub fn to_parry(self) -> parry2d_f64::shape::Segment {
53        self.points.map(|point| point.to_na()).into()
54    }
55}
56
57impl Segment<3> {
58    /// Convert the 3-dimensional segment to a Parry segment
59    pub fn to_parry(self) -> parry3d_f64::shape::Segment {
60        self.points.map(|point| point.to_na()).into()
61    }
62}
63
64impl<P, const D: usize> From<[P; 2]> for Segment<D>
65where
66    P: Into<Point<D>>,
67{
68    fn from(points: [P; 2]) -> Self {
69        Self::from_points(points)
70    }
71}
72
73impl<const D: usize> fmt::Debug for Segment<D> {
74    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75        write!(f, "[{:?} -> {:?}]", self.points[0], self.points[1])
76    }
77}