Skip to content

Commit f961a71

Browse files
committed
Fix #472 don't assume u,v derivatives are orthogonal in ClosestPointNewton
1 parent 2ace69f commit f961a71

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

src/srf/ratpoly.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -501,21 +501,27 @@ bool SSurface::ClosestPointNewton(Vector p, double *u, double *v, bool mustConve
501501
}
502502
}
503503

504-
Vector tu, tv;
504+
Vector tu, tv, tx, ty;
505505
TangentsAt(*u, *v, &tu, &tv);
506+
// since tu and tv may not be orthogonal, use y in place of v.
507+
// |y| = |v|sin(theta) where theta is the angle between tu and tv.
508+
ty = tu.Cross(tv).Cross(tu).ScaledBy(1.0/tu.MagSquared());
509+
tx = tv.Cross(tu).Cross(tv).ScaledBy(1.0/tv.MagSquared());
506510

507511
// Project the point into a plane through p0, with basis tu, tv; a
508512
// second-order thing would converge faster but needs second
509513
// derivatives.
510514
Vector dp = p.Minus(p0);
511-
double du = dp.Dot(tu), dv = dp.Dot(tv);
512-
*u += du / (tu.MagSquared());
513-
*v += dv / (tv.MagSquared());
515+
double du = dp.Dot(tx),
516+
dv = dp.Dot(ty);
517+
*u += du / (tu.Magnitude() * tx.Magnitude());
518+
*v += dv / (tv.Magnitude() * ty.Magnitude());
514519

515520
if (*u < 0.0) *u = 0.0;
516521
else if (*u > 1.0) *u = 1.0;
517522
if (*v < 0.0) *v = 0.0;
518523
else if (*v > 1.0) *v = 1.0;
524+
519525
}
520526

521527
if(mustConverge) {

0 commit comments

Comments
 (0)