Coverage Report

Created: 2026-04-29 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nalgebra-0.34.2/src/geometry/reflection.rs
Line
Count
Source
1
use crate::base::constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint};
2
use crate::base::{Const, Matrix, Unit, Vector};
3
use crate::dimension::{Dim, U1};
4
use crate::storage::{Storage, StorageMut};
5
use simba::scalar::ComplexField;
6
7
use crate::geometry::Point;
8
9
/// A reflection wrt. a plane.
10
pub struct Reflection<T, D, S> {
11
    axis: Vector<T, D, S>,
12
    bias: T,
13
}
14
15
impl<T: ComplexField, S: Storage<T, Const<D>>, const D: usize> Reflection<T, Const<D>, S> {
16
    /// Creates a new reflection wrt. the plane orthogonal to the given axis and that contains the
17
    /// point `pt`.
18
    pub fn new_containing_point(axis: Unit<Vector<T, Const<D>, S>>, pt: &Point<T, D>) -> Self {
19
        let bias = axis.dotc(&pt.coords);
20
        Self::new(axis, bias)
21
    }
22
}
23
24
impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
25
    /// Creates a new reflection wrt. the plane orthogonal to the given axis and bias.
26
    ///
27
    /// The bias is the position of the plane on the axis. In particular, a bias equal to zero
28
    /// represents a plane that passes through the origin.
29
0
    pub fn new(axis: Unit<Vector<T, D, S>>, bias: T) -> Self {
30
0
        Self {
31
0
            axis: axis.into_inner(),
32
0
            bias,
33
0
        }
34
0
    }
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Const<2>, nalgebra::base::array_storage::ArrayStorage<f64, 2, 1>>>::new
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Const<3>, nalgebra::base::array_storage::ArrayStorage<f64, 3, 1>>>::new
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorage<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>>::new
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorage<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<6>>>>::new
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>>::new
35
36
    /// The reflection axis.
37
    #[must_use]
38
    pub const fn axis(&self) -> &Vector<T, D, S> {
39
        &self.axis
40
    }
41
42
    /// The reflection bias.
43
    ///
44
    /// The bias is the position of the plane on the axis. In particular, a bias equal to zero
45
    /// represents a plane that passes through the origin.
46
    #[must_use]
47
    pub fn bias(&self) -> T {
48
        self.bias.clone()
49
    }
50
51
    // TODO: naming convention: reflect_to, reflect_assign ?
52
    /// Applies the reflection to the columns of `rhs`.
53
0
    pub fn reflect<R2: Dim, C2: Dim, S2>(&self, rhs: &mut Matrix<T, R2, C2, S2>)
54
0
    where
55
0
        S2: StorageMut<T, R2, C2>,
56
0
        ShapeConstraint: SameNumberOfRows<R2, D>,
57
    {
58
0
        for i in 0..rhs.ncols() {
59
0
            // NOTE: we borrow the column twice here. First it is borrowed immutably for the
60
0
            // dot product, and then mutably. Somehow, this allows significantly
61
0
            // better optimizations of the dot product from the compiler.
62
0
            let m_two: T = crate::convert(-2.0f64);
63
0
            let factor = (self.axis.dotc(&rhs.column(i)) - self.bias.clone()) * m_two;
64
0
            rhs.column_mut(i).axpy(factor, &self.axis, T::one());
65
0
        }
66
0
    }
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Const<2>, nalgebra::base::array_storage::ArrayStorage<f64, 2, 1>>>::reflect::<nalgebra::base::dimension::Const<2>, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Const<2>, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Const<3>, nalgebra::base::array_storage::ArrayStorage<f64, 3, 1>>>::reflect::<nalgebra::base::dimension::Const<3>, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Const<3>, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>
67
68
    // TODO: naming convention: reflect_to, reflect_assign ?
69
    /// Applies the reflection to the columns of `rhs`.
70
0
    pub fn reflect_with_sign<R2: Dim, C2: Dim, S2>(&self, rhs: &mut Matrix<T, R2, C2, S2>, sign: T)
71
0
    where
72
0
        S2: StorageMut<T, R2, C2>,
73
0
        ShapeConstraint: SameNumberOfRows<R2, D>,
74
    {
75
0
        for i in 0..rhs.ncols() {
76
0
            // NOTE: we borrow the column twice here. First it is borrowed immutably for the
77
0
            // dot product, and then mutably. Somehow, this allows significantly
78
0
            // better optimizations of the dot product from the compiler.
79
0
            let m_two = sign.clone().scale(crate::convert(-2.0f64));
80
0
            let factor = (self.axis.dotc(&rhs.column(i)) - self.bias.clone()) * m_two;
81
0
            rhs.column_mut(i).axpy(factor, &self.axis, sign.clone());
82
0
        }
83
0
    }
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorage<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>>::reflect_with_sign::<nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorage<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<6>>>>::reflect_with_sign::<nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<6>>>
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>>::reflect_with_sign::<nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Dyn, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>
84
85
    /// Applies the reflection to the rows of `lhs`.
86
0
    pub fn reflect_rows<R2: Dim, C2: Dim, S2, S3>(
87
0
        &self,
88
0
        lhs: &mut Matrix<T, R2, C2, S2>,
89
0
        work: &mut Vector<T, R2, S3>,
90
0
    ) where
91
0
        S2: StorageMut<T, R2, C2>,
92
0
        S3: StorageMut<T, R2>,
93
0
        ShapeConstraint: DimEq<C2, D> + AreMultipliable<R2, C2, D, U1>,
94
    {
95
0
        lhs.mul_to(&self.axis, work);
96
97
0
        if !self.bias.is_zero() {
98
0
            work.add_scalar_mut(-self.bias.clone());
99
0
        }
100
101
0
        let m_two: T = crate::convert(-2.0f64);
102
0
        lhs.gerc(m_two, work, &self.axis, T::one());
103
0
    }
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Const<2>, nalgebra::base::array_storage::ArrayStorage<f64, 2, 1>>>::reflect_rows::<nalgebra::base::dimension::Const<2>, nalgebra::base::dimension::Const<2>, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Const<2>, nalgebra::base::dimension::Const<2>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>, nalgebra::base::array_storage::ArrayStorage<f64, 2, 1>>
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Const<2>, nalgebra::base::array_storage::ArrayStorage<f64, 2, 1>>>::reflect_rows::<nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<2>, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<2>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Const<3>, nalgebra::base::array_storage::ArrayStorage<f64, 3, 1>>>::reflect_rows::<nalgebra::base::dimension::Const<2>, nalgebra::base::dimension::Const<3>, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Const<2>, nalgebra::base::dimension::Const<3>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>, nalgebra::base::array_storage::ArrayStorage<f64, 2, 1>>
Unexecuted instantiation: <nalgebra::geometry::reflection::Reflection<f64, nalgebra::base::dimension::Const<3>, nalgebra::base::array_storage::ArrayStorage<f64, 3, 1>>>::reflect_rows::<nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<3>, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<3>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>, nalgebra::base::matrix_view::ViewStorageMut<f64, nalgebra::base::dimension::Dyn, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<1>, nalgebra::base::dimension::Const<2>>>
104
105
    /// Applies the reflection to the rows of `lhs`.
106
0
    pub fn reflect_rows_with_sign<R2: Dim, C2: Dim, S2, S3>(
107
0
        &self,
108
0
        lhs: &mut Matrix<T, R2, C2, S2>,
109
0
        work: &mut Vector<T, R2, S3>,
110
0
        sign: T,
111
0
    ) where
112
0
        S2: StorageMut<T, R2, C2>,
113
0
        S3: StorageMut<T, R2>,
114
0
        ShapeConstraint: DimEq<C2, D> + AreMultipliable<R2, C2, D, U1>,
115
    {
116
0
        lhs.mul_to(&self.axis, work);
117
118
0
        if !self.bias.is_zero() {
119
0
            work.add_scalar_mut(-self.bias.clone());
120
0
        }
121
122
0
        let m_two = sign.clone().scale(crate::convert(-2.0f64));
123
0
        lhs.gerc(m_two, work, &self.axis, sign);
124
0
    }
125
}