From bc01fddd7fa0f1fb5adddb90cf8c67a3e395456c Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 11 Jun 2009 20:30:27 +0100 Subject: [PATCH] Handle segment lengths greater than curve lengths --- src/Points.cpp | 21 ++++++++++++++------- src/TrackCommon.cpp | 13 ++++++++++++- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Points.cpp b/src/Points.cpp index 021ffa4..6cfeb47 100644 --- a/src/Points.cpp +++ b/src/Points.cpp @@ -122,8 +122,10 @@ track::TravelToken Points::getTravelToken(track::Position aPosition, } void Points::transform(const track::TravelToken& aToken, double aDelta) const -{ - assert(aDelta < segmentLength(aToken)); +{ + const float len = segmentLength(aToken); + + assert(aDelta < len); if (myX == aToken.position.x && myY == aToken.position.y) { @@ -174,7 +176,12 @@ void Points::transform(const track::TravelToken& aToken, double aDelta) const // Curving onto the straight section float xTrans, yTrans, rotate; - const float fValue = 3.0f - aDelta; + // We have a slight problem in that the domain of the curve + // function is [0,3] but the delta is in [0,len] so we have + // to compress the delta into [0,3] here + const float curveDelta = aDelta * 3.0f / len; + + const float fValue = 3.0f - curveDelta; const float curveValue = hypTanCurveFunc(fValue); // Calculate the angle that the tangent to the curve at this @@ -183,23 +190,23 @@ void Points::transform(const track::TravelToken& aToken, double aDelta) const const float angle = radToDeg(atanf(grad)); if (myAxis == -axis::X && aToken.direction == axis::X) { - xTrans = aDelta - 2.0f; + xTrans = curveDelta - 3.0f + 1.0f; yTrans = amReflected ? curveValue : -curveValue; rotate = amReflected ? angle : -angle; } else if (myAxis == axis::X && aToken.direction == -axis::X) { - xTrans = 3.0f - aDelta; + xTrans = 3.0f - curveDelta; yTrans = amReflected ? -curveValue : curveValue; rotate = amReflected ? -angle : angle; } else if (myAxis == -axis::Y && aToken.direction == axis::Y) { xTrans = amReflected ? -curveValue : curveValue; - yTrans = aDelta - 2.0f; + yTrans = curveDelta - 3.0f + 1.0f; rotate = amReflected ? angle : -angle; } else if (myAxis == axis::Y && aToken.direction == -axis::Y) { xTrans = amReflected ? curveValue : -curveValue; - yTrans = 3.0f - aDelta; + yTrans = 3.0f - curveDelta; rotate = amReflected ? angle : -angle; } else diff --git a/src/TrackCommon.cpp b/src/TrackCommon.cpp index 27e808e..a205476 100644 --- a/src/TrackCommon.cpp +++ b/src/TrackCommon.cpp @@ -263,7 +263,18 @@ namespace { // The function that determines the curve of points and S-bends float hypTanCurveFunc(float x) { - return 0.5f * (1.0f + tanh(1.8f * x - 3.5f)); + const float linearAbove = 2.7f; + const float wantOneAt = 2.9f; + if (x <= linearAbove) + // Use the curvey function + return 0.5f * (1.0f + tanh(1.8f * x - 3.5f)); + else { + // Interpolate linearly + const float fLinearAbove = hypTanCurveFunc(linearAbove); + const float m = (1.0f - fLinearAbove) / (wantOneAt - linearAbove); + + return m*(x - linearAbove) + fLinearAbove; + } } // The above function reflected about the x-axis -- 2.39.2