Add more Vec operations
MODIFY
src/manual/core/vec.rs
src/manual/core/vec.rs
use std::{
+ array,
ffi::c_void,
- ops::{Deref, DerefMut},
+ ops::{Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
};
use crate::{
@@ -42,6 +43,16 @@ impl<T: Copy, const N: usize> Vec<T, N> {
pub fn all(v0: T) -> Self {
Self::from([v0; N])
}
+
+ /// per-element multiplication
+ #[inline]
+ pub fn mul(&self, v: Self) -> Self where T: Mul<Output=T> + Copy {
+ let mut out = *self;
+ out.iter_mut()
+ .zip(v.into_iter())
+ .for_each(|(dest, m)| *dest = *dest * m);
+ out
+ }
}
impl<T, const N: usize> From<[T; N]> for Vec<T, N> {
@@ -67,6 +78,156 @@ impl<T, const N: usize> DerefMut for Vec<T, N> {
}
}
+impl<T, const N: usize> IntoIterator for Vec<T, N> {
+ type Item = T;
+ type IntoIter = array::IntoIter<T, N>;
+
+ #[inline]
+ fn into_iter(self) -> array::IntoIter<T, N> {
+ IntoIterator::into_iter(self.0)
+ }
+}
+
+impl<F: num_traits::Float> Vec<F, 2> {
+ /// conjugation (makes sense for complex numbers and quaternions)
+ #[inline]
+ pub fn conj(&self) -> Self {
+ Self([self[0], -self[1]])
+ }
+}
+
+impl<F: num_traits::Float> Vec<F, 3> {
+ /// cross product of the two 3D vectors
+ #[inline]
+ pub fn cross(&self, v: Self) -> Self {
+ Self([
+ self[1] * v[2] - self[2] * v[1],
+ self[2] * v[0] - self[0] * v[2],
+ self[0] * v[1] - self[1] * v[0]
+ ])
+ }
+}
+
+impl<F: num_traits::Float> Vec<F, 4> {
+ /// conjugation (makes sense for complex numbers and quaternions)
+ #[inline]
+ pub fn conj(&self) -> Self {
+ Self([self[0], -self[1], -self[2], -self[3]])
+ }
+}
+
+impl<T: AddAssign, const N: usize> AddAssign for Vec<T, N> {
+ #[inline]
+ fn add_assign(&mut self, rhs: Self) {
+ self.iter_mut()
+ .zip(rhs.into_iter())
+ .for_each(|(out, v)| *out += v)
+ }
+}
+
+impl<T: Add<Output=T> + Copy, const N: usize> Add for Vec<T, N> {
+ type Output = Self;
+
+ #[inline]
+ fn add(mut self, rhs: Self) -> Self::Output {
+ self.iter_mut()
+ .zip(rhs.into_iter())
+ .for_each(|(out, v)| *out = *out + v);
+ self
+ }
+}
+
+impl<T: SubAssign, const N: usize> SubAssign for Vec<T, N> {
+ #[inline]
+ fn sub_assign(&mut self, rhs: Self) {
+ self.iter_mut()
+ .zip(rhs.into_iter())
+ .for_each(|(out, v)| *out -= v)
+ }
+}
+
+impl<T: Sub<Output=T> + Copy, const N: usize> Sub for Vec<T, N> {
+ type Output = Self;
+
+ #[inline]
+ fn sub(mut self, rhs: Self) -> Self::Output {
+ self.iter_mut()
+ .zip(rhs.into_iter())
+ .for_each(|(out, v)| *out = *out - v);
+ self
+ }
+}
+
+impl<Rhs: ValidVecType, T: MulAssign<Rhs>, const N: usize> MulAssign<Rhs> for Vec<T, N> {
+ #[inline]
+ fn mul_assign(&mut self, rhs: Rhs) {
+ self.iter_mut()
+ .for_each(|out| *out *= rhs)
+ }
+}
+
+impl<Rhs: ValidVecType, T: DivAssign<Rhs>, const N: usize> DivAssign<Rhs> for Vec<T, N> {
+ #[inline]
+ fn div_assign(&mut self, rhs: Rhs) {
+ self.iter_mut()
+ .for_each(|out| *out /= rhs)
+ }
+}
+
+impl<Rhs: ValidVecType, T: Mul<Rhs, Output=T> + Copy, const N: usize> Mul<Rhs> for Vec<T, N> {
+ type Output = Self;
+
+ #[inline]
+ fn mul(mut self, rhs: Rhs) -> Self::Output {
+ self.iter_mut()
+ .for_each(|out| *out = *out * rhs);
+ self
+ }
+}
+
+impl<Rhs: ValidVecType, T: Div<Rhs, Output=T> + Copy, const N: usize> Div<Rhs> for Vec<T, N> {
+ type Output = Self;
+
+ #[inline]
+ fn div(mut self, rhs: Rhs) -> Self::Output {
+ self.iter_mut()
+ .for_each(|out| *out = *out / rhs);
+ self
+ }
+}
+
+impl<T: Neg<Output=T> + Copy, const N: usize> Neg for Vec<T, N> {
+ type Output = Self;
+
+ #[inline]
+ fn neg(mut self) -> Self::Output {
+ self.iter_mut()
+ .for_each(|out| *out = -*out);
+ self
+ }
+}
+
+impl<T: Mul<Output=T> + Sub<Output=T> + Add<Output=T> + Copy> Mul for Vec<T, 4> {
+ type Output = Self;
+
+ #[inline]
+ fn mul(self, rhs: Self) -> Self::Output {
+ Self([
+ self[0] * rhs[0] - self[1] * rhs[1] - self[2] * rhs[2] - self[3] * rhs[3],
+ self[0] * rhs[1] + self[1] * rhs[0] + self[2] * rhs[3] - self[3] * rhs[2],
+ self[0] * rhs[2] - self[1] * rhs[3] + self[2] * rhs[0] + self[3] * rhs[1],
+ self[0] * rhs[3] + self[1] * rhs[2] - self[2] * rhs[1] + self[3] * rhs[0],
+ ])
+ }
+}
+
+impl<T: Mul<Output=T> + Sub<Output=T> + Add<Output=T> + Copy> MulAssign for Vec<T, 4> {
+ #[inline]
+ fn mul_assign(&mut self, rhs: Self) {
+ *self = *self * rhs;
+ }
+}
+
impl<T: ValidVecType, const N: usize> OpenCVType<'_> for Vec<T, N> {
type Arg = Self;
type ExternReceive = Self;

MODIFY
tests/vec.rs
tests/vec.rs
-use opencv::core::Vec3b;
+use opencv::core::{Vec2d, Vec2i, Vec3b, Vec3d, Vec4f, Vec4s};
#[test]
fn vec() {
@@ -14,3 +14,67 @@ fn vec() {
fn vec_deref() {
assert_eq!(vec![10, 20, 30], Vec3b::from([10, 20, 30]).to_vec());
}
+
+#[test]
+fn vec_conj() {
+ assert_eq!(Vec4f::from([1., -2., -3., -4.]), Vec4f::from([1., 2., 3., 4.]).conj());
+ assert_eq!(Vec2d::from([2., 4.]), Vec2d::from([2., -4.]).conj());
+}
+
+#[test]
+fn vec_cross() {
+ let a = Vec3d::from([10., 15., 20.]);
+ let b = Vec3d::from([-90., 85., -80.]);
+ assert_eq!(Vec3d::from([-2900., -1000., 2200.]), a.cross(b));
+}
+
+#[test]
+fn vec_mul() {
+ let mut a = Vec3d::from([10., 15., 20.]);
+ let b = Vec3d::from([-90., 85., -80.]);
+ assert_eq!(Vec3d::from([-900., 1275., -1600.]), a.mul(b));
+
+ a *= 3.;
+ let c = a * 2.;
+ assert_eq!(Vec3d::from([30., 45., 60.]), a);
+ assert_eq!(Vec3d::from([60., 90., 120.]), c);
+
+ let a = Vec4s::from([4, 19, 7, -4]);
+ let b = Vec4s::from([0, 8, -15, 43]);
+ assert_eq!(Vec4s::from([125, 273, -909, -169]), a * b);
+}
+
+#[test]
+fn vec_div() {
+ let mut a = Vec3d::from([10., 15., 20.]);
+ a /= 5.;
+ let c = a / 2.;
+ assert_eq!(Vec3d::from([2., 3., 4.]), a);
+ assert_eq!(Vec3d::from([1., 1.5, 2.]), c);
+}
+
+#[test]
+fn vec_add() {
+ let mut a = Vec2i::from([10, 15]);
+ let b = Vec2i::from([-90, 85]);
+ a += b;
+ let c = a + b;
+ assert_eq!(Vec2i::from([-80, 100]), a);
+ assert_eq!(Vec2i::from([-170, 185]), c);
+}
+
+#[test]
+fn vec_sub() {
+ let mut a = Vec2i::from([10, 15]);
+ let b = Vec2i::from([-90, 85]);
+ a -= b;
+ let c = a - b;
+ assert_eq!(Vec2i::from([100, -70]), a);
+ assert_eq!(Vec2i::from([190, -155]), c);
+}
+
+#[test]
+fn vec_neg() {
+ let a = Vec2i::from([10, -15]);
+ assert_eq!(Vec2i::from([-10, 15]), -a);
+}

Add more Vec operations