I am trying to create a sweeping surface, for which I need the frenet frame of a curve. I am trying to compute this for arbitrary curves but for testing I am just using the parametric unit half circle. i.e. $C(t) = (\cos(t), \sin(t), 0)$
I am computing my derivatives using central differences, i.e.:
pub fn frenet_trihedron(x: f32, f: &dyn Fn(f32) -> Vec3) -> (Vec3, Vec3, Vec3)
{
let h = 1e-6 as f32;
let normal = (-2.0 * f(x) + f(x + h) + f(x - h)) / (h * h);
let tangent = (f(x + h) - f(x - h)) / (2.0 * h);
let tangent = tangent.normalize();
let normal = normal.normalize();
let binormal = tangent.cross(&normal);
println!("t {}, n {}, b {}", tangent, normal, binormal);
(tangent, normal, binormal)
}
This however seems to yield very impossible results, for example:
t
┌ ┐
│ -0.8274758 │
│ 0.56150144 │
│ 0 │
└ ┘
, n
┌ ┐
│ 0 │
│ 1 │
│ 0 │
└ ┘
, b
┌ ┐
│ 0 │
│ 0 │
│ -0.8274758 │
└ ┘
That normal is not orthogonal to the tangent not even close What am I doing wrong?
This is the calling code:
let f = |v| Vec3::new(f32::cos(v * PI), f32::sin(v * PI), 0.0);
let (t, n, b) = frenet_trihedron(v, &|x| f(x));
It seems the error is being cause by floating point imprecision. Using 1e-3
asmy epsilon yields remarkably better results. so maybe f32 is just not precise enough.
frenet_trihedron
function. $\endgroup$v
that produced your example output? This will tell at least tell us (and you) if the bug is the wrong calculation oft
orn
(or both). This is an important debugging principle: narrow down the position of the error. $\endgroup$