Drawing a tubular path with Meshes.jl (blog post)

It is much simpler to define a tubular surface of directional curve, γ, using quaternions:

import ForwardDiff.derivative
import LinearAlgebra: norm, cross
import Rotations.UnitQuaternion

dγ(t)=derivative(γ, t) # t->̇γ(t)
ddγ(t)=derivative(dγ, t) #t->̈γ(t)

#get the tubular surface  parameterization:
function tube(γ::T, u::S, v::S; radius=0.1) where {S<:Real, T<:Function}
    tang = dγ(u)   #tangent(γ, u)
    ~iszero(tang) || error("null tangent vector!")
    unittan = tang/norm(tang)
    θ = acos(unittan[1])/2
    crossp= [0, -unittan[3], unittan[2]]  # cross product [1,0,0] x unittan
    quvect = sin(θ)*crossp/norm(crossp) #3-vector to define the quaternion 
                                          #q=(cos(θ), sin(θ)*unitvect)
    q = isapprox(θ, π/2) ? UnitQuaternion(0, 0, 1, 0) : isapprox(θ, 0) ? 
                   UnitQuaternion(1, 0 , 0, 0) : UnitQuaternion(cos(θ), quvect...)
    _, n₁, n₂,   = eachcol(q)
    return γ(u) + radius*cos(v) * n₁ + radius*sin(v) * n₂
end 

Example

1 Like