[animation] Fixed logic of angle and segment interpolation.

This commit is contained in:
vng 2014-09-26 12:26:25 +03:00 committed by Alex Zolotarev
parent d62f10356b
commit b58e285a59
6 changed files with 42 additions and 40 deletions

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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;
};
}

View file

@ -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;
}

View file

@ -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);