honeycomb_core/geometry/dim2/
vertex.rs1use crate::attributes::{AttrSparseVec, AttributeBind, AttributeError, AttributeUpdate};
6use crate::cmap::{OrbitPolicy, VertexIdType};
7use crate::geometry::{CoordsFloat, Vector2};
8
9#[derive(Debug, Clone, Copy, Default, PartialEq)]
53pub struct Vertex2<T: CoordsFloat>(pub T, pub T);
54
55unsafe impl<T: CoordsFloat> Send for Vertex2<T> {}
56unsafe impl<T: CoordsFloat> Sync for Vertex2<T> {}
57
58impl<T: CoordsFloat> Vertex2<T> {
59 pub fn into_inner(self) -> (T, T) {
61 (self.0, self.1)
62 }
63
64 pub fn x(&self) -> T {
66 self.0
67 }
68
69 pub fn y(&self) -> T {
71 self.1
72 }
73
74 pub fn average(lhs: &Vertex2<T>, rhs: &Vertex2<T>) -> Vertex2<T> {
92 let two = T::from(2.0).unwrap();
93 Vertex2((lhs.0 + rhs.0) / two, (lhs.1 + rhs.1) / two)
94 }
95}
96
97impl<T: CoordsFloat> From<(T, T)> for Vertex2<T> {
100 fn from((x, y): (T, T)) -> Self {
101 Self(x, y)
102 }
103}
104
105impl<T: CoordsFloat> std::ops::Add<Vector2<T>> for Vertex2<T> {
110 type Output = Self;
112
113 fn add(self, rhs: Vector2<T>) -> Self::Output {
114 Self(self.0 + rhs.0, self.1 + rhs.1)
115 }
116}
117
118impl<T: CoordsFloat> std::ops::AddAssign<Vector2<T>> for Vertex2<T> {
119 fn add_assign(&mut self, rhs: Vector2<T>) {
120 self.0 += rhs.0;
121 self.1 += rhs.1;
122 }
123}
124
125impl<T: CoordsFloat> std::ops::Add<&Vector2<T>> for Vertex2<T> {
126 type Output = Self;
128
129 fn add(self, rhs: &Vector2<T>) -> Self::Output {
130 Self(self.0 + rhs.0, self.1 + rhs.1)
131 }
132}
133
134impl<T: CoordsFloat> std::ops::AddAssign<&Vector2<T>> for Vertex2<T> {
135 fn add_assign(&mut self, rhs: &Vector2<T>) {
136 self.0 += rhs.0;
137 self.1 += rhs.1;
138 }
139}
140
141impl<T: CoordsFloat> std::ops::Sub<Vector2<T>> for Vertex2<T> {
144 type Output = Self;
146
147 fn sub(self, rhs: Vector2<T>) -> Self::Output {
148 Self(self.0 - rhs.0, self.1 - rhs.1)
149 }
150}
151
152impl<T: CoordsFloat> std::ops::SubAssign<Vector2<T>> for Vertex2<T> {
153 fn sub_assign(&mut self, rhs: Vector2<T>) {
154 self.0 -= rhs.0;
155 self.1 -= rhs.1;
156 }
157}
158
159impl<T: CoordsFloat> std::ops::Sub<&Vector2<T>> for Vertex2<T> {
160 type Output = Self;
162
163 fn sub(self, rhs: &Vector2<T>) -> Self::Output {
164 Self(self.0 - rhs.0, self.1 - rhs.1)
165 }
166}
167
168impl<T: CoordsFloat> std::ops::SubAssign<&Vector2<T>> for Vertex2<T> {
169 fn sub_assign(&mut self, rhs: &Vector2<T>) {
170 self.0 -= rhs.0;
171 self.1 -= rhs.1;
172 }
173}
174
175impl<T: CoordsFloat> std::ops::Sub<Vertex2<T>> for Vertex2<T> {
176 type Output = Vector2<T>;
177
178 fn sub(self, rhs: Vertex2<T>) -> Self::Output {
179 Vector2(self.0 - rhs.0, self.1 - rhs.1)
180 }
181}
182
183impl<T: CoordsFloat> AttributeUpdate for Vertex2<T> {
184 fn merge(attr1: Self, attr2: Self) -> Result<Self, AttributeError> {
185 Ok(Self::average(&attr1, &attr2))
186 }
187
188 fn split(attr: Self) -> Result<(Self, Self), AttributeError> {
189 Ok((attr, attr))
190 }
191
192 fn merge_incomplete(attr: Self) -> Result<Self, AttributeError> {
194 Ok(attr)
195 }
196}
197
198impl<T: CoordsFloat> AttributeBind for Vertex2<T> {
199 type StorageType = AttrSparseVec<Self>;
200 type IdentifierType = VertexIdType;
201 const BIND_POLICY: OrbitPolicy = OrbitPolicy::Vertex;
202}