LCOV - code coverage report
Current view: top level - src/geometry - transformations.jl (source / functions) Hit Total Coverage
Test: on branch (detached from b856613) Lines: 0 31 0.0 %
Date: 2025-12-02 13:19:26 Functions: 0 0 -

          Line data    Source code
       1             : """
       2             : Affine map `f(x) = A * x - b`
       3             : 
       4             :     f = affinemap(A, b)
       5             :     f(x) == A * x - b
       6             : 
       7             :     g = linearmap(f)       # linear part A * x
       8             :     g = mapvector(f)       # same as linearmap(f)
       9             :     g = mapunitvector(f)   # plus normalization
      10             :     g = mapnormal(f)       # map unit normals inv(A)' * x
      11             : 
      12             : See also [`affinemap`](@ref), [`LinearMap`](@ref)
      13             : """
      14             : struct AffineMap{M, N, T, MN}
      15             :     A::SMatrix{M, N, T, MN}
      16             :     b::SVector{M, T}
      17             : end
      18             : 
      19             : """
      20             :     f = affinemap(A, b)
      21             :     f(x) == A * x - b
      22             : 
      23             :     affinemap(f) == f
      24             :     g = inv(f)
      25             : 
      26             : Construct [`AffineMap`](@ref)
      27             : 
      28             : See also  [`AffineMap`](@ref), [`linearmap`](@ref)
      29             : """
      30           0 : affinemap(A::SMatrix{M, N, T, MN},
      31             :           b::SVector{M, T}) where {M, N, T, MN} =
      32             :               AffineMap{M, N, T, MN}(A, b)
      33             : 
      34           0 : affinemap(t::AffineMap) = t
      35             : 
      36           0 : function Base.inv(t::AffineMap{M, N, T, MN}) where {M, N, T, MN}
      37           0 :     iA = inv(t.A)
      38           0 :     affinemap(iA, -(iA * t.b))
      39             : end
      40             : 
      41           0 : (t::AffineMap{M, N, T, MN})(x) where {M, N, T, MN} =
      42             :     t.A * x - t.b # possibly more stable: A * (x - x0)
      43             : 
      44             : """
      45             : Linear map `f(x) = A * x`
      46             : 
      47             :     f = linearmap(A)
      48             :     f(x) == A * x
      49             : 
      50             :     linearmap(f) == f
      51             : 
      52             :     g = f'               # adjoint
      53             :     g = inv(f)           # inverse for maps (for quadratic A)
      54             :     g = inv(f')
      55             :     g = mapunitvector(f) # plus normalization
      56             :     g = mapnormal(f)     # map unit normals inv(A)' * x
      57             : 
      58             : See also [`AffineMap`](@ref), [`linearmap`](@ref)
      59             : """
      60             : struct LinearMap{M, N, T, MN}
      61             :     A::SMatrix{M, N, T, MN}
      62             : end
      63             : 
      64           0 : Base.inv(t::LinearMap{N, N, T, NN}) where {N, T, NN} =
      65             :     linearmap(inv(t.A))
      66             : 
      67           0 : LinearAlgebra.adjoint(t::LinearMap{M, N, T, MN}) where {M, N, T, MN} =
      68             :     linearmap(t.A')
      69             : 
      70           0 : linearmap(A::SMatrix{M, N, T, MN}) where {M, N, T, MN} =
      71             :     LinearMap{M, N, T, MN}(A)
      72             : 
      73           0 : linearmap(t::AffineMap{M, N, T, MN}) where {M, N, T, MN} =
      74             :     linearmap(t.A)
      75             : 
      76           0 : linearmap(t::LinearMap) = t
      77             : 
      78             : """
      79             :     f = linearmap(A, b)
      80             :     f = linearmap(g::AffineMap)
      81             :     linearmap(f) == f
      82             :     f(x) == A * x
      83             : 
      84             : Construct [`LinearMap`](@ref)
      85             : 
      86             : See also  [`LinearMap`](@ref), [`affinemap`](@ref)
      87             : """ linearmap
      88             : 
      89           0 : (t::LinearMap{M, N, T, MN})(x) where {M, N, T, MN} = t.A * x
      90             : 
      91           0 : mapvector(t::AffineMap) = linearmap(t)
      92             : 
      93           0 : mapvector(t::LinearMap) = t
      94             : 
      95             : """
      96             :     f = affinemap(A, b)
      97             :     g = linearmap(f)
      98             :     g = mapvector(f)
      99             : 
     100             : Synomym for [`linearmap`](@ref)
     101             : 
     102             : See also [`LinearMap`](@ref), [`mapunitvector`](@ref),
     103             : [`mapnormal`](@ref)
     104             : """ mapvector
     105             : 
     106           0 : function _normalized(x)
     107           0 :     len = norm(x)
     108           0 :     (len == 0) && return x
     109           0 :     x / len
     110             : end
     111             : 
     112           0 : mapunitvector(t::AffineMap) = _normalized ∘ mapvector(t)
     113             : 
     114           0 : mapunitvector(t::LinearMap) = _normalized ∘ t'
     115             : 
     116             : """
     117             :     f = affinemap(A, b)
     118             :     g = mapunitvector(f)
     119             :     g = mapunitvector(linearmap(f))
     120             : 
     121             : *Nonlinear* map that composes [`linearmap`](@ref) and
     122             : *normalization* of result.
     123             : 
     124             : !!! note
     125             :     Null vectors are mapped to null vectors. They are
     126             :     *not* "normalized"!
     127             : 
     128             : See also [`LinearMap`](@ref), [`mapvector`](@ref),
     129             : [`mapnormal`](@ref)
     130             : """ mapunitvector
     131             : 
     132             : 
     133           0 : maptangentvector(t::AffineMap) = maptangentvector(linearmap(t))
     134             : 
     135           0 : maptangentvector(t::LinearMap) = linearmap((t.A[@SVector([1, 2]), :]))'
     136             : 
     137             : """
     138             : Same as [`mapvector`](@ref) but use only dimensions `1:2`.
     139             : 
     140             : Use case: [`tolocal`](@ref) maps to local `u,v,w` coordinates,
     141             : map `u, v` to 3d vector in tangent space.
     142             : 
     143             : See also [`mapvector`](@ref)
     144             : """ maptangentvector
     145             : 
     146           0 : maptangentunitvector(t::AffineMap) = _normalized ∘ maptangentvector(t)
     147             : 
     148           0 : maptangentuntvector(t::LinearMap) = _normalized ∘ maptangentuntvector(t)
     149             : 
     150             : """
     151             : Same as [`mapunitvector`](@ref) but use only dimensions `1:2`.
     152             : 
     153             : Use case: [`tolocal`](@ref) maps to local `u,v,w` coordinates,
     154             : map `u, v` to 3d ("normalized") unit vector in tangent space.
     155             : 
     156             : See also [`mapvector`](@ref)
     157             : """ maptangentunitvector
     158             : 
     159           0 : mapnormal(t::AffineMap{N, N, T, NN}) where {N, T, NN} =
     160             :     mapnormal(linearmap(t))
     161             : 
     162           0 : mapnormal(t::LinearMap{N, N, T, NN}) where {N, T, NN} =
     163             :     linearmap(inv(t.A)')
     164             : 
     165             : """
     166             :     f = affinemap(A, b)
     167             :     g = mapnormal(f)
     168             :     g = mapnormal(linearmap(f))
     169             : 
     170             : *Nonlinear* map that maps normal vectors `n` with `inv(A)' * n`
     171             : followed by *normalization*.
     172             : 
     173             : !!! note
     174             :     Null vectors are mapped to null vectors. They are
     175             :     *not* "normalized"!
     176             : 
     177             : See also [`LinearMap`](@ref), [`mapvector`](@ref),
     178             : [`mapunitvector`](@ref)
     179             : """ mapnormal
     180             : 
     181             : """
     182             :     t = affinemap(A, b)
     183             :     mapvattr(t, mesh, Val(:x))
     184             :     mapvattr(mapnormal(t), mesh, Val(:n))
     185             : 
     186             :     mapvattr(x -> 2x, mesh, val(:myattr))
     187             : 
     188             : Apply transformation on vertex attribute for all vertices.
     189             : 
     190             : See also [`vattr`](@ref), [`affinemap`](@ref), [`linearmap`](@ref),
     191             : [`mapunitvector`](@ref), [`normal`](@ref), [`maptangentvector`](@ref),
     192             : [`maptangentunitvector`](@ref)
     193             : """
     194           0 : function mapvattr!(f, mesh::Mesh, ax)
     195           0 :     x = vattr(mesh, ax)
     196             : 
     197           0 :     for v in vertices(mesh)
     198           0 :         x[v] = f(x[v])
     199           0 :     end
     200             : end
     201             : 
     202             : # TODO: compose maps with ∘

Generated by: LCOV version 1.16