Skip to main content

opencv/manual/core/
vec.rs

1use std::array;
2use std::ops::{Deref, DerefMut, MulAssign};
3
4use num_traits::{Float, NumCast, ToPrimitive};
5
6use crate::boxed_ref::{BoxedRef, BoxedRefMut};
7use crate::core::{ToInputArray, ToInputOutputArray, ToOutputArray, _InputArray, _InputOutputArray, _OutputArray};
8use crate::traits::{Boxed, OpenCVFromExtern, OpenCVIntoExternContainer, OpenCVType, OpenCVTypeExternContainer};
9use crate::{extern_receive, extern_send, sys, Result};
10
11mod operations;
12
13/// [docs.opencv.org](https://docs.opencv.org/master/d6/dcf/classcv_1_1Vec.html)
14/// Named `VecN` to avoid name clash with std's `Vec`.
15#[repr(C)]
16#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd)]
17pub struct VecN<T, const N: usize>(pub [T; N]);
18
19impl<T, const N: usize> Default for VecN<T, N>
20where
21	[T; N]: Default,
22{
23	#[inline]
24	fn default() -> Self {
25		Self(Default::default())
26	}
27}
28
29impl<T, const N: usize> VecN<T, N> {
30	#[inline]
31	pub const fn from_array(val: [T; N]) -> Self {
32		Self(val)
33	}
34
35	#[inline]
36	pub const fn all(v0: T) -> Self
37	where
38		T: Copy,
39	{
40		Self::from_array([v0; N])
41	}
42
43	/// per-element multiplication
44	#[inline]
45	pub fn mul(&self, v: Self) -> Self
46	where
47		T: MulAssign,
48		Self: Copy,
49	{
50		let mut out = *self;
51		out.iter_mut().zip(v).for_each(|(dest, m)| *dest *= m);
52		out
53	}
54
55	/// Cast `VecN` to the other element type
56	#[inline]
57	pub fn to<D: NumCast + Default + Copy>(self) -> Option<VecN<D, N>>
58	where
59		T: ToPrimitive,
60	{
61		let mut out = [D::default(); N];
62		for (dest, src) in out.iter_mut().zip(self) {
63			*dest = D::from(src)?;
64		}
65		Some(VecN(out))
66	}
67}
68
69impl<T, const N: usize> From<[T; N]> for VecN<T, N> {
70	#[inline]
71	fn from(s: [T; N]) -> Self {
72		Self::from_array(s)
73	}
74}
75
76impl<T, const N: usize> Deref for VecN<T, N> {
77	type Target = [T; N];
78
79	#[inline]
80	fn deref(&self) -> &Self::Target {
81		&self.0
82	}
83}
84
85impl<T, const N: usize> DerefMut for VecN<T, N> {
86	#[inline]
87	fn deref_mut(&mut self) -> &mut Self::Target {
88		&mut self.0
89	}
90}
91
92impl<T, const N: usize> IntoIterator for VecN<T, N> {
93	type Item = T;
94	type IntoIter = array::IntoIter<T, N>;
95
96	#[inline]
97	fn into_iter(self) -> array::IntoIter<T, N> {
98		self.0.into_iter()
99	}
100}
101
102impl<F: Float> VecN<F, 2> {
103	/// conjugation (makes sense for complex numbers and quaternions)
104	#[inline]
105	pub fn conj(&self) -> Self {
106		Self([self[0], -self[1]])
107	}
108}
109
110impl<F: Float> VecN<F, 3> {
111	/// cross product of the two 3D vectors
112	#[inline]
113	pub fn cross(&self, v: Self) -> Self {
114		Self([
115			self[1] * v[2] - self[2] * v[1],
116			self[2] * v[0] - self[0] * v[2],
117			self[0] * v[1] - self[1] * v[0],
118		])
119	}
120}
121
122impl<F: Float> VecN<F, 4> {
123	/// conjugation (makes sense for complex numbers and quaternions)
124	#[inline]
125	pub fn conj(&self) -> Self {
126		Self([self[0], -self[1], -self[2], -self[3]])
127	}
128}
129
130impl<T, const N: usize> OpenCVType<'_> for VecN<T, N> {
131	type Arg = Self;
132}
133
134impl<T, const N: usize> OpenCVFromExtern for VecN<T, N> {
135	type ExternReceive = Self;
136
137	#[inline]
138	unsafe fn opencv_from_extern(s: Self::ExternReceive) -> Self {
139		s
140	}
141}
142
143impl<T, const N: usize> OpenCVIntoExternContainer for VecN<T, N> {
144	type ExternContainer = Self;
145
146	#[inline]
147	fn opencv_into_extern_container_nofail(self) -> Self::ExternContainer {
148		self
149	}
150}
151
152impl<T, const N: usize> OpenCVTypeExternContainer for VecN<T, N> {
153	type ExternSend = *const Self;
154	type ExternSendMut = *mut Self;
155
156	#[inline]
157	fn opencv_as_extern(&self) -> Self::ExternSend {
158		self
159	}
160
161	#[inline]
162	fn opencv_as_extern_mut(&mut self) -> Self::ExternSendMut {
163		self
164	}
165}
166
167impl<T, const N: usize> ToInputArray for VecN<T, N>
168where
169	Self: VecExtern,
170{
171	#[inline]
172	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
173		unsafe { self.extern_input_array() }
174			.into_result()
175			.map(|ptr| unsafe { _InputArray::from_raw(ptr) }.into())
176	}
177}
178
179impl<T, const N: usize> ToInputArray for &VecN<T, N>
180where
181	VecN<T, N>: VecExtern,
182{
183	#[inline]
184	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
185		(*self).input_array()
186	}
187}
188
189impl<T, const N: usize> ToOutputArray for VecN<T, N>
190where
191	Self: VecExtern,
192{
193	#[inline]
194	fn output_array(&mut self) -> Result<BoxedRefMut<'_, _OutputArray>> {
195		unsafe { self.extern_output_array() }
196			.into_result()
197			.map(|ptr| unsafe { _OutputArray::from_raw(ptr) }.into())
198	}
199}
200
201impl<T, const N: usize> ToOutputArray for &mut VecN<T, N>
202where
203	VecN<T, N>: VecExtern,
204{
205	#[inline]
206	fn output_array(&mut self) -> Result<BoxedRefMut<'_, _OutputArray>> {
207		(*self).output_array()
208	}
209}
210
211impl<T, const N: usize> ToInputOutputArray for VecN<T, N>
212where
213	Self: VecExtern,
214{
215	#[inline]
216	fn input_output_array(&mut self) -> Result<BoxedRefMut<'_, _InputOutputArray>> {
217		unsafe { self.extern_input_output_array() }
218			.into_result()
219			.map(|ptr| unsafe { _InputOutputArray::from_raw(ptr) }.into())
220	}
221}
222
223impl<T, const N: usize> ToInputOutputArray for &mut VecN<T, N>
224where
225	VecN<T, N>: VecExtern,
226{
227	#[inline]
228	fn input_output_array(&mut self) -> Result<BoxedRefMut<'_, _InputOutputArray>> {
229		(*self).input_output_array()
230	}
231}
232
233#[doc(hidden)]
234pub trait VecExtern {
235	#[doc(hidden)]
236	unsafe fn extern_input_array(&self) -> sys::Result<extern_receive!(_InputArray)>;
237	#[doc(hidden)]
238	unsafe fn extern_output_array(&mut self) -> sys::Result<extern_receive!(_OutputArray)>;
239	#[doc(hidden)]
240	unsafe fn extern_input_output_array(&mut self) -> sys::Result<extern_receive!(_InputOutputArray)>;
241}
242
243macro_rules! vecn_extern {
244	($type: ty, $len: expr, $extern_input_array: ident, $extern_ouput_array: ident, $extern_input_array_output: ident) => {
245		unsafe extern "C" {
246			fn $extern_input_array(instance: extern_send!($crate::core::VecN<$type, $len>), ocvrs_return: *mut $crate::sys::Result<extern_receive!($crate::core::_InputArray)>);
247			fn $extern_ouput_array(instance: extern_send!(mut $crate::core::VecN<$type, $len>), ocvrs_return: *mut $crate::sys::Result<extern_receive!($crate::core::_OutputArray)>);
248			fn $extern_input_array_output(instance: extern_send!(mut $crate::core::VecN<$type, $len>), ocvrs_return: *mut $crate::sys::Result<extern_receive!($crate::core::_InputOutputArray)>);
249		}
250
251		impl $crate::core::VecExtern for $crate::core::VecN<$type, $len> {
252			#[inline]
253			unsafe fn extern_input_array(&self) -> $crate::sys::Result<extern_receive!($crate::core::_InputArray)> {
254				return_send!(via ocvrs_return);
255				unsafe { $extern_input_array(self, ocvrs_return.as_mut_ptr()); }
256				return_receive!(ocvrs_return => ret);
257				ret
258			}
259
260			#[inline]
261			unsafe fn extern_output_array(&mut self) -> $crate::sys::Result<extern_receive!($crate::core::_OutputArray)> {
262				return_send!(via ocvrs_return);
263				unsafe { $extern_ouput_array(self, ocvrs_return.as_mut_ptr()); }
264				return_receive!(ocvrs_return => ret);
265				ret
266			}
267
268			#[inline]
269			unsafe fn extern_input_output_array(&mut self) -> $crate::sys::Result<extern_receive!($crate::core::_InputOutputArray)> {
270				return_send!(via ocvrs_return);
271				unsafe { $extern_input_array_output(self, ocvrs_return.as_mut_ptr()); }
272				return_receive!(ocvrs_return => ret);
273				ret
274			}
275		}
276	}
277}
278
279vecn_extern!(
280	u8,
281	2,
282	cv_Vec2b_input_array,
283	cv_Vec2b_output_array,
284	cv_Vec2b_input_output_array
285);
286vecn_extern!(
287	f64,
288	2,
289	cv_Vec2d_input_array,
290	cv_Vec2d_output_array,
291	cv_Vec2d_input_output_array
292);
293vecn_extern!(
294	f32,
295	2,
296	cv_Vec2f_input_array,
297	cv_Vec2f_output_array,
298	cv_Vec2f_input_output_array
299);
300vecn_extern!(
301	i32,
302	2,
303	cv_Vec2i_input_array,
304	cv_Vec2i_output_array,
305	cv_Vec2i_input_output_array
306);
307vecn_extern!(
308	i16,
309	2,
310	cv_Vec2s_input_array,
311	cv_Vec2s_output_array,
312	cv_Vec2s_input_output_array
313);
314vecn_extern!(
315	u16,
316	2,
317	cv_Vec2w_input_array,
318	cv_Vec2w_output_array,
319	cv_Vec2w_input_output_array
320);
321
322vecn_extern!(
323	u8,
324	3,
325	cv_Vec3b_input_array,
326	cv_Vec3b_output_array,
327	cv_Vec3b_input_output_array
328);
329vecn_extern!(
330	f64,
331	3,
332	cv_Vec3d_input_array,
333	cv_Vec3d_output_array,
334	cv_Vec3d_input_output_array
335);
336vecn_extern!(
337	f32,
338	3,
339	cv_Vec3f_input_array,
340	cv_Vec3f_output_array,
341	cv_Vec3f_input_output_array
342);
343vecn_extern!(
344	i32,
345	3,
346	cv_Vec3i_input_array,
347	cv_Vec3i_output_array,
348	cv_Vec3i_input_output_array
349);
350vecn_extern!(
351	i16,
352	3,
353	cv_Vec3s_input_array,
354	cv_Vec3s_output_array,
355	cv_Vec3s_input_output_array
356);
357vecn_extern!(
358	u16,
359	3,
360	cv_Vec3w_input_array,
361	cv_Vec3w_output_array,
362	cv_Vec3w_input_output_array
363);
364
365vecn_extern!(
366	u8,
367	4,
368	cv_Vec4b_input_array,
369	cv_Vec4b_output_array,
370	cv_Vec4b_input_output_array
371);
372vecn_extern!(
373	f64,
374	4,
375	cv_Vec4d_input_array,
376	cv_Vec4d_output_array,
377	cv_Vec4d_input_output_array
378);
379vecn_extern!(
380	f32,
381	4,
382	cv_Vec4f_input_array,
383	cv_Vec4f_output_array,
384	cv_Vec4f_input_output_array
385);
386vecn_extern!(
387	i32,
388	4,
389	cv_Vec4i_input_array,
390	cv_Vec4i_output_array,
391	cv_Vec4i_input_output_array
392);
393vecn_extern!(
394	i16,
395	4,
396	cv_Vec4s_input_array,
397	cv_Vec4s_output_array,
398	cv_Vec4s_input_output_array
399);
400vecn_extern!(
401	u16,
402	4,
403	cv_Vec4w_input_array,
404	cv_Vec4w_output_array,
405	cv_Vec4w_input_output_array
406);
407
408vecn_extern!(
409	f64,
410	6,
411	cv_Vec6d_input_array,
412	cv_Vec6d_output_array,
413	cv_Vec6d_input_output_array
414);
415vecn_extern!(
416	f32,
417	6,
418	cv_Vec6f_input_array,
419	cv_Vec6f_output_array,
420	cv_Vec6f_input_output_array
421);
422vecn_extern!(
423	i32,
424	6,
425	cv_Vec6i_input_array,
426	cv_Vec6i_output_array,
427	cv_Vec6i_input_output_array
428);
429
430vecn_extern!(
431	i32,
432	8,
433	cv_Vec8i_input_array,
434	cv_Vec8i_output_array,
435	cv_Vec8i_input_output_array
436);
437
438vecn_extern!(
439	f64,
440	18,
441	cv_Vec18d_input_array,
442	cv_Vec18d_output_array,
443	cv_Vec18d_input_output_array
444);