use fields::VectorField;
use nalgebra::*;
use std::ops::{AddAssign, Mul, SubAssign};
pub struct ScaledVectorField<'a> {
field: &'a VectorField,
scalar: f32,
}
impl<'a> ScaledVectorField<'a> {
pub fn size(&self) -> Vector3<usize> {
self.field.size()
}
pub fn len(&self) -> usize {
self.field.len()
}
pub fn field(&self) -> &VectorField {
self.field
}
}
impl<'a> Mul<f32> for &'a VectorField {
type Output = ScaledVectorField<'a>;
fn mul(self, rhs: f32) -> ScaledVectorField<'a> {
ScaledVectorField {
field: self,
scalar: rhs,
}
}
}
impl<'a> Mul<&'a VectorField> for f32 {
type Output = ScaledVectorField<'a>;
fn mul(self, rhs: &'a VectorField) -> ScaledVectorField<'a> {
ScaledVectorField {
field: rhs,
scalar: self,
}
}
}
#[test]
fn test_add_assign_scaled_vector_field() {
let mut field_a: VectorField = VectorField::new(Vector3::new(2, 2, 1));
field_a[(0, 0, 0)] = Vector3::repeat(1.0);
field_a[(1, 0, 0)] = Vector3::repeat(2.0);
field_a[(0, 1, 0)] = Vector3::repeat(3.0);
field_a[(1, 1, 0)] = Vector3::repeat(4.0);
let cloned_a = field_a.clone();
let field_b: ScaledVectorField = 2.0 * &cloned_a;
field_a += &field_b;
assert!((field_a[(0usize, 0, 0)] - Vector3::repeat(3.0)).norm() < 1e-10);
assert!((field_a[(1usize, 0, 0)] - Vector3::repeat(6.0)).norm() < 1e-10);
assert!((field_a[(0usize, 1, 0)] - Vector3::repeat(9.0)).norm() < 1e-10);
assert!((field_a[(1usize, 1, 0)] - Vector3::repeat(12.0)).norm() < 1e-10);
}
impl<'a, 'b> AddAssign<&'b ScaledVectorField<'a>> for VectorField {
fn add_assign(&mut self, other: &'b ScaledVectorField) {
debug_assert!(self.size() == other.size());
for (self_element, other_element) in self.vectors_mut()
.iter_mut()
.zip(other.field().vectors().iter())
{
*self_element += other.scalar * other_element
}
}
}
#[test]
fn test_sub_assign_scaled_vector_field() {
let mut field_a: VectorField = VectorField::new(Vector3::new(2, 2, 1));
field_a[(0, 0, 0)] = Vector3::repeat(1.0);
field_a[(1, 0, 0)] = Vector3::repeat(2.0);
field_a[(0, 1, 0)] = Vector3::repeat(3.0);
field_a[(1, 1, 0)] = Vector3::repeat(4.0);
let cloned_a = field_a.clone();
let field_b: ScaledVectorField = -2.0 * &cloned_a;
field_a -= &field_b;
assert!((field_a[(0usize, 0, 0)] - Vector3::repeat(3.0)).norm() < 1e-10);
assert!((field_a[(1usize, 0, 0)] - Vector3::repeat(6.0)).norm() < 1e-10);
assert!((field_a[(0usize, 1, 0)] - Vector3::repeat(9.0)).norm() < 1e-10);
assert!((field_a[(1usize, 1, 0)] - Vector3::repeat(12.0)).norm() < 1e-10);
}
impl<'a, 'b> SubAssign<&'b ScaledVectorField<'a>> for VectorField {
fn sub_assign(&mut self, other: &'b ScaledVectorField) {
debug_assert!(self.size() == other.size());
for (self_element, other_element) in self.vectors_mut()
.iter_mut()
.zip(other.field().vectors().iter())
{
*self_element -= other.scalar * other_element
}
}
}
impl<'a> AddAssign<ScaledVectorField<'a>> for VectorField {
fn add_assign(&mut self, other: ScaledVectorField) {
*self += &other;
}
}
impl<'a> SubAssign<ScaledVectorField<'a>> for VectorField {
fn sub_assign(&mut self, other: ScaledVectorField) {
*self -= &other;
}
}