Skip to content
Permalink
Browse files

Fix divide by zero in slerp, also center spline length arc points (#3072

)
  • Loading branch information...
ericchristoffersen authored and liversedge committed Apr 15, 2019
1 parent a1f3a98 commit d20291031a0cb06df88aeac0d953918e69f1d397
Showing with 17 additions and 9 deletions.
  1. +6 −2 src/FileIO/LocationInterpolation.cpp
  2. +11 −7 src/FileIO/LocationInterpolation.h
@@ -128,8 +128,12 @@ geolocation xyz::togeolocation() const

xyz Slerper::Slerp(double frac)
{
double scale = sin(frac * m_angle) / m_sin_angle;
return m_x0_norm.scale(sin((1 - frac) * m_angle) / m_sin_angle).add(m_x1_norm.scale(scale));
if (m_sin_angle != 0.0)
{
double scale = sin(frac * m_angle) / m_sin_angle;
return m_x0_norm.scale(sin((1 - frac) * m_angle) / m_sin_angle).add(m_x1_norm.scale(scale));
}
return m_x0_norm;
}

// Precompute invariant values needed to geoslerp
@@ -633,9 +633,9 @@ template <typename T_TwoPointInterpolator> class DistancePointInterpolator
d1 = workitem.d1;

// Step 1
const double quarterspan = (d1 - d0) / 4;
const double inter0 = d0 + quarterspan;
const double inter1 = d0 + quarterspan + quarterspan;
const double thirdspan = (d1 - d0) / 3;
const double inter0 = d0 + thirdspan;
const double inter1 = d0 + thirdspan + thirdspan;

// Step 2
const xyz pm1 = this->Interpolate(d0);
@@ -645,18 +645,22 @@ template <typename T_TwoPointInterpolator> class DistancePointInterpolator

// Step 3
double linearDistance = p2.DistanceFrom(pm1);
if (linearDistance == 0.0)
if (linearDistance < 0.000001)
break;

// Step 4
double quadDistance = p2.DistanceFrom(p1) + p1.DistanceFrom(p0) + p0.DistanceFrom(pm1);
double span0 = p0.DistanceFrom(pm1);
double span1 = p1.DistanceFrom(p0);
double span2 = p2.DistanceFrom(p1);

double arcDistance = span0 + span1 + span2;

// Step 5
double difference = fabs(quadDistance / linearDistance) - 1.0;
double difference = fabs(arcDistance / linearDistance) - 1.0;

// 5A: Settle for quaddistance if threshold met or no more room on worklist.
if (difference < thresholdLimit || worklist.EmptySlots() < 3) {
finalLength += quadDistance;
finalLength += arcDistance;
} else {
// 5B: otherwise push the 3 new subsegments onto worklist.
worklist.Push(CalcSplineLengthBracketPair(d0, inter0));

0 comments on commit d202910

Please sign in to comment.
You can’t perform that action at this time.