opencv/manual/core/
point3.rs

1use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
2
3use num_traits::{NumCast, NumOps, ToPrimitive, Zero};
4
5use crate::core::{Point_, VecN};
6use crate::opencv_type_simple_generic;
7
8/// [docs.opencv.org](https://docs.opencv.org/master/df/d6c/classcv_1_1Point3__.html)
9#[repr(C)]
10#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd)]
11pub struct Point3_<T> {
12	pub x: T,
13	pub y: T,
14	pub z: T,
15}
16
17impl<T> Point3_<T> {
18	#[inline]
19	pub const fn new(x: T, y: T, z: T) -> Self {
20		Self { x, y, z }
21	}
22
23	#[inline]
24	pub fn from_vec3(vec: VecN<T, 3>) -> Self {
25		let [x, y, z] = vec.0;
26		Self::new(x, y, z)
27	}
28
29	#[inline]
30	pub fn from_point(pt: Point_<T>) -> Self
31	where
32		T: Zero,
33	{
34		Self::new(pt.x, pt.y, T::zero())
35	}
36
37	#[inline]
38	pub fn cross(self, pt: Self) -> Self
39	where
40		T: NumOps + Copy,
41	{
42		Self::new(
43			self.y * pt.z - self.z * pt.y,
44			self.z * pt.x - self.x * pt.z,
45			self.x * pt.y - self.y * pt.x,
46		)
47	}
48
49	#[inline]
50	pub fn dot(self, pt: Self) -> T
51	where
52		T: NumOps,
53	{
54		self.x * pt.x + self.y * pt.y + self.z * pt.z
55	}
56
57	#[inline]
58	pub fn ddot(self, pt: Self) -> f64
59	where
60		f64: From<T>,
61	{
62		let self_x: f64 = From::from(self.x);
63		let self_y: f64 = From::from(self.y);
64		let self_z: f64 = From::from(self.z);
65		let pt_x: f64 = From::from(pt.x);
66		let pt_y: f64 = From::from(pt.y);
67		let pt_z: f64 = From::from(pt.z);
68		self_x * pt_x + self_y * pt_y + self_z * pt_z
69	}
70
71	#[inline]
72	pub fn norm(self) -> f64
73	where
74		f64: From<T>,
75	{
76		let self_x: f64 = From::from(self.x);
77		let self_y: f64 = From::from(self.y);
78		let self_z: f64 = From::from(self.z);
79		(self_x.powi(2) + self_y.powi(2) + self_z.powi(2)).sqrt()
80	}
81
82	/// Cast `Point3` to the other coord type
83	#[inline]
84	pub fn to<D: NumCast>(self) -> Option<Point3_<D>>
85	where
86		T: ToPrimitive,
87	{
88		Some(Point3_::new(D::from(self.x)?, D::from(self.y)?, D::from(self.z)?))
89	}
90
91	#[inline]
92	pub fn to_vec3(self) -> VecN<T, 3> {
93		VecN::<_, 3>::from_array([self.x, self.y, self.z])
94	}
95}
96
97impl<T> From<(T, T, T)> for Point3_<T> {
98	#[inline]
99	fn from(s: (T, T, T)) -> Self {
100		Self::new(s.0, s.1, s.2)
101	}
102}
103
104impl<T> From<VecN<T, 3>> for Point3_<T> {
105	#[inline]
106	fn from(s: VecN<T, 3>) -> Self {
107		Self::from_vec3(s)
108	}
109}
110
111impl<T: Zero> From<Point_<T>> for Point3_<T> {
112	#[inline]
113	fn from(s: Point_<T>) -> Self {
114		Self::from_point(s)
115	}
116}
117
118impl<T> Add for Point3_<T>
119where
120	Self: AddAssign,
121{
122	type Output = Self;
123
124	fn add(mut self, rhs: Self) -> Self::Output {
125		self += rhs;
126		self
127	}
128}
129
130impl<T> Sub for Point3_<T>
131where
132	Self: SubAssign,
133{
134	type Output = Self;
135
136	fn sub(mut self, rhs: Self) -> Self::Output {
137		self -= rhs;
138		self
139	}
140}
141
142impl<T> Mul<T> for Point3_<T>
143where
144	Self: MulAssign<T>,
145{
146	type Output = Self;
147
148	fn mul(mut self, rhs: T) -> Self::Output {
149		self *= rhs;
150		self
151	}
152}
153
154impl<T> Div<T> for Point3_<T>
155where
156	Self: DivAssign<T>,
157{
158	type Output = Self;
159
160	fn div(mut self, rhs: T) -> Self::Output {
161		self /= rhs;
162		self
163	}
164}
165
166impl<T: AddAssign> AddAssign for Point3_<T> {
167	fn add_assign(&mut self, rhs: Point3_<T>) {
168		self.x += rhs.x;
169		self.y += rhs.y;
170		self.z += rhs.z;
171	}
172}
173
174impl<T: SubAssign> SubAssign for Point3_<T> {
175	fn sub_assign(&mut self, rhs: Point3_<T>) {
176		self.x -= rhs.x;
177		self.y -= rhs.y;
178		self.z -= rhs.z;
179	}
180}
181
182impl<T: MulAssign + Copy> MulAssign<T> for Point3_<T> {
183	fn mul_assign(&mut self, rhs: T) {
184		self.x *= rhs;
185		self.y *= rhs;
186		self.z *= rhs;
187	}
188}
189
190impl<T: DivAssign + Copy> DivAssign<T> for Point3_<T> {
191	fn div_assign(&mut self, rhs: T) {
192		self.x /= rhs;
193		self.y /= rhs;
194		self.z /= rhs;
195	}
196}
197
198opencv_type_simple_generic! { Point3_<Copy> }