From b58e285a591d14ca6af77d3695d23d538fa60c5f Mon Sep 17 00:00:00 2001 From: vng Date: Fri, 26 Sep 2014 12:26:25 +0300 Subject: [PATCH] [animation] Fixed logic of angle and segment interpolation. --- anim/angle_interpolation.cpp | 30 ++++++++++++++++-------------- anim/angle_interpolation.hpp | 6 +----- anim/segment_interpolation.cpp | 23 +++++++++++++---------- anim/segment_interpolation.hpp | 11 ++++++----- map/animator.cpp | 4 ++-- map/location_state.cpp | 8 ++++---- 6 files changed, 42 insertions(+), 40 deletions(-) diff --git a/anim/angle_interpolation.cpp b/anim/angle_interpolation.cpp index 7d929afb15..24c2a2b3a9 100644 --- a/anim/angle_interpolation.cpp +++ b/anim/angle_interpolation.cpp @@ -2,8 +2,10 @@ #include "controller.hpp" #include "../geometry/angles.hpp" + #include "../base/logging.hpp" + namespace anim { AngleInterpolation::AngleInterpolation(double start, @@ -35,14 +37,14 @@ namespace anim if (!IsRunning()) return; - if (ts - m_startTime >= m_interval) + double const elapsed = ts - m_startTime; + if (elapsed >= m_interval) { End(); return; } - double elapsedSec = ts - m_startTime; - m_curAngle = m_outAngle = m_startAngle + m_dist * elapsedSec / m_interval; + m_curAngle = m_outAngle = m_startAngle + elapsed * m_speed; Task::OnStep(ts); } @@ -54,26 +56,27 @@ namespace anim Task::OnEnd(ts); } - double AngleInterpolation::EndAngle() const - { - return m_endAngle; - } - void AngleInterpolation::SetEndAngle(double val) { - CalcParams(m_curAngle, val, m_speed); + CalcParams(m_curAngle, val, fabs(m_speed)); m_startTime = GetController()->GetCurrentTime(); } void AngleInterpolation::CalcParams(double start, double end, double speed) { + ASSERT_GREATER(speed, 0.0, ()); + m_startAngle = start; m_speed = speed; - m_startTime = 0; - m_dist = ang::GetShortestDistance(start, end); + m_startTime = 0.0; + + double const dist = ang::GetShortestDistance(start, end); + if (dist < 0.0) + m_speed = -m_speed; + m_curAngle = m_startAngle; - m_endAngle = m_startAngle + m_dist; - m_interval = fabs(m_dist) / (2 * math::pi) * m_speed; + m_endAngle = m_startAngle + dist; + m_interval = dist / m_speed; } SafeAngleInterpolation::SafeAngleInterpolation(double start, double end, double speed) @@ -91,5 +94,4 @@ namespace anim { return m_angle; } - } diff --git a/anim/angle_interpolation.hpp b/anim/angle_interpolation.hpp index 300f6cade9..96353a118a 100644 --- a/anim/angle_interpolation.hpp +++ b/anim/angle_interpolation.hpp @@ -6,19 +6,15 @@ namespace anim { class AngleInterpolation : public Task { - private: - double m_startAngle; double m_curAngle; double & m_outAngle; double m_startTime; double m_endAngle; double m_interval; - double m_dist; double m_speed; public: - AngleInterpolation(double start, double end, double speed, @@ -30,7 +26,6 @@ namespace anim void OnStep(double ts); void OnEnd(double ts); - double EndAngle() const; void SetEndAngle(double val); private: @@ -40,6 +35,7 @@ namespace anim class SafeAngleInterpolation : public AngleInterpolation { typedef AngleInterpolation TBase; + public: SafeAngleInterpolation(double start, double end, double speed); diff --git a/anim/segment_interpolation.cpp b/anim/segment_interpolation.cpp index 0e8f9a4f4a..61b38802c6 100644 --- a/anim/segment_interpolation.cpp +++ b/anim/segment_interpolation.cpp @@ -1,7 +1,7 @@ #include "segment_interpolation.hpp" - #include "controller.hpp" + namespace anim { SegmentInterpolation::SegmentInterpolation(m2::PointD const & startPt, @@ -12,14 +12,20 @@ namespace anim m_endPt(endPt), m_outPt(outPt), m_interval(interval) - {} + { + m_speed = (m_endPt - m_startPt) / m_interval; + } void SegmentInterpolation::Reset(m2::PointD const & start, m2::PointD const & end, double interval) { + ASSERT_GREATER(interval, 0.0, ()); + m_startPt = start; - m_outPt = m_startPt; m_endPt = end; + m_outPt = m_startPt; m_interval = interval; + + m_speed = (m_endPt - m_startPt) / m_interval; m_startTime = GetController()->GetCurrentTime(); SetState(EReady); } @@ -33,7 +39,8 @@ namespace anim void SegmentInterpolation::OnStep(double ts) { - if (ts - m_startTime >= m_interval) + double const elapsed = ts - m_startTime; + if (elapsed >= m_interval) { End(); return; @@ -42,10 +49,7 @@ namespace anim if (!IsRunning()) return; - double elapsedSec = ts - m_startTime; - m2::PointD deltaPt = m_endPt - m_startPt; - - m_outPt = m_startPt + deltaPt * (elapsedSec / m_interval); + m_outPt = m_startPt + m_speed * elapsed; Task::OnStep(ts); } @@ -69,9 +73,8 @@ namespace anim Reset(GetCurrentValue(), dstPt, interval); } - const m2::PointD &SafeSegmentInterpolation::GetCurrentValue() const + m2::PointD const & SafeSegmentInterpolation::GetCurrentValue() const { return m_pt; } - } diff --git a/anim/segment_interpolation.hpp b/anim/segment_interpolation.hpp index 2f631ace6a..d1b0cf108c 100644 --- a/anim/segment_interpolation.hpp +++ b/anim/segment_interpolation.hpp @@ -1,22 +1,23 @@ #pragma once #include "task.hpp" + #include "../geometry/point2d.hpp" + namespace anim { class SegmentInterpolation : public Task { - private: - m2::PointD m_startPt; m2::PointD m_endPt; m2::PointD & m_outPt; - double m_startTime; double m_interval; - public: + m2::PointD m_speed; + double m_startTime; + public: SegmentInterpolation(m2::PointD const & startPt, m2::PointD const & endPt, double interval, @@ -32,6 +33,7 @@ namespace anim class SafeSegmentInterpolation : public SegmentInterpolation { typedef SegmentInterpolation TBase; + public: SafeSegmentInterpolation(m2::PointD const & startPt, m2::PointD const & endPt, @@ -44,4 +46,3 @@ namespace anim m2::PointD m_pt; }; } - diff --git a/map/animator.cpp b/map/animator.cpp index f13bf98406..e520c4a4fa 100644 --- a/map/animator.cpp +++ b/map/animator.cpp @@ -118,6 +118,6 @@ void Animator::StopChangeViewport() double Animator::GetRotationSpeed() const { - /// making full circle in 3 seconds. - return 1; + // making full circle in ~1 seconds. + return 6.0; } diff --git a/map/location_state.cpp b/map/location_state.cpp index 5ba3904114..3e92ddf122 100644 --- a/map/location_state.cpp +++ b/map/location_state.cpp @@ -61,10 +61,10 @@ public: double srcAngle, m2::PointD const & srcPixelBinding) : m_fw(fw) { - m_angleAnim.reset(new anim::SafeAngleInterpolation(srcAngle, srcAngle, 0.0)); - m_posAnim.reset(new anim::SafeSegmentInterpolation(srcPos, srcPos, 0.0)); + m_angleAnim.reset(new anim::SafeAngleInterpolation(srcAngle, srcAngle, 1.0)); + m_posAnim.reset(new anim::SafeSegmentInterpolation(srcPos, srcPos, 1.0)); m2::PointD invertedPxBinding(InvertPxBinding(srcPixelBinding)); - m_pxBindingAnim.reset(new anim::SafeSegmentInterpolation(invertedPxBinding, invertedPxBinding, 0.0)); + m_pxBindingAnim.reset(new anim::SafeSegmentInterpolation(invertedPxBinding, invertedPxBinding, 1.0)); } void SetDestinationParams(m2::PointD const & dstPos, double dstAngle) @@ -72,7 +72,7 @@ public: ASSERT(m_angleAnim != nullptr, ()); ASSERT(m_posAnim != nullptr, ()); double const posSpeed = m_fw->GetNavigator().ComputeMoveSpeed(m_posAnim->GetCurrentValue(), dstPos); - double const angleSpeed = m_fw->GetAnimator().GetRotationSpeed(); + double const angleSpeed = 1.5;//m_fw->GetAnimator().GetRotationSpeed(); m_angleAnim->ResetDestParams(dstAngle, angleSpeed); m_posAnim->ResetDestParams(dstPos, posSpeed);