Skip to main content

apple_cf/cg/
point.rs

1//! `CGPoint` type for 2D coordinates
2
3use std::fmt;
4
5/// `CGPoint` representation
6///
7/// Represents a point in 2D space.
8///
9/// # Examples
10///
11/// ```
12/// use apple_cf::cg::CGPoint;
13///
14/// let p1 = CGPoint::new(0.0, 0.0);
15/// let p2 = CGPoint::new(3.0, 4.0);
16/// assert_eq!(p1.distance_to(&p2), 5.0);
17/// ```
18#[repr(C)]
19#[derive(Debug, Clone, Copy, PartialEq)]
20pub struct CGPoint {
21    pub x: f64,
22    pub y: f64,
23}
24
25impl std::hash::Hash for CGPoint {
26    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
27        self.x.to_bits().hash(state);
28        self.y.to_bits().hash(state);
29    }
30}
31
32impl Eq for CGPoint {}
33
34impl CGPoint {
35    /// Create a new point
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use apple_cf::cg::CGPoint;
41    ///
42    /// let point = CGPoint::new(100.0, 200.0);
43    /// assert_eq!(point.x, 100.0);
44    /// ```
45    #[must_use]
46    pub const fn new(x: f64, y: f64) -> Self {
47        Self { x, y }
48    }
49
50    /// Create a point at origin (0, 0)
51    ///
52    /// # Examples
53    ///
54    /// ```
55    /// use apple_cf::cg::CGPoint;
56    ///
57    /// let point = CGPoint::zero();
58    /// assert!(point.is_zero());
59    /// ```
60    #[must_use]
61    pub const fn zero() -> Self {
62        Self::new(0.0, 0.0)
63    }
64
65    /// Check if point is at origin (0, 0)
66    #[must_use]
67    pub const fn is_zero(&self) -> bool {
68        self.x == 0.0 && self.y == 0.0
69    }
70
71    /// Calculate distance to another point
72    #[must_use]
73    pub fn distance_to(&self, other: &Self) -> f64 {
74        let dx = self.x - other.x;
75        let dy = self.y - other.y;
76        dx.hypot(dy)
77    }
78
79    /// Calculate squared distance to another point (faster than `distance_to`)
80    #[must_use]
81    pub const fn distance_squared_to(&self, other: &Self) -> f64 {
82        let dx = self.x - other.x;
83        let dy = self.y - other.y;
84        dx * dx + dy * dy
85    }
86}
87
88impl Default for CGPoint {
89    fn default() -> Self {
90        Self::zero()
91    }
92}
93
94impl fmt::Display for CGPoint {
95    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96        write!(f, "({}, {})", self.x, self.y)
97    }
98}