9#include "kineticmodel.h"
12#include <QElapsedTimer>
14static const int KineticModelDefaultUpdateInterval = 15;
16class KineticModelPrivate
25 qreal velocityHeading;
27 qreal deaccelerationHeading;
32 bool changingPosition;
34 KineticModelPrivate();
37KineticModelPrivate::KineticModelPrivate()
43 , deacceleration(0, 0)
44 , deaccelerationHeading(0)
47 , changingPosition(true)
52KineticModel::KineticModel(
QObject *parent)
54 , d_ptr(new KineticModelPrivate)
57 d_ptr->ticker.setInterval(KineticModelDefaultUpdateInterval);
60KineticModel::~KineticModel()
65bool KineticModel::hasVelocity()
const
67 return !d_ptr->velocity.isNull();
70int KineticModel::duration()
const
72 return d_ptr->duration;
75void KineticModel::setDuration(
int ms)
80QPointF KineticModel::position()
const
82 return d_ptr->position;
85void KineticModel::setPosition(
const QPointF& position)
87 setPosition( position.
x(), position.
y() );
90void KineticModel::setPosition(qreal posX, qreal posY)
92 d_ptr->position.setX(
posX );
93 d_ptr->position.setY(
posY );
95 int elapsed = d_ptr->timestamp.elapsed();
102 qreal delta =
static_cast<qreal
>( elapsed ) / 1000.0;
107 d_ptr->lastPosition = d_ptr->position;
109 d_ptr->changingPosition =
true;
110 d_ptr->timestamp.start();
113void KineticModel::setHeading(qreal heading)
115 d_ptr->heading = heading;
117 int elapsed = d_ptr->timestamp.elapsed();
118 qreal delta =
static_cast<qreal
>( elapsed ) / 1000.0;
120 qreal
lastSpeed = d_ptr->velocityHeading;
121 qreal
currentSpeed = delta ? ( d_ptr->heading - d_ptr->lastHeading ) / delta : 0;
123 d_ptr->lastHeading = d_ptr->heading;
125 d_ptr->changingPosition =
false;
126 d_ptr->timestamp.start();
129void KineticModel::jumpToPosition(
const QPointF& position)
131 jumpToPosition( position.
x(), position.
y() );
134void KineticModel::jumpToPosition(qreal posX, qreal posY)
136 d_ptr->position.setX(
posX );
137 d_ptr->position.setY(
posY );
140int KineticModel::updateInterval()
const
142 return d_ptr->ticker.interval();
145void KineticModel::setUpdateInterval(
int ms)
147 d_ptr->ticker.setInterval(
ms);
150void KineticModel::stop()
155 d->timestamp.start();
157 d->velocityHeading = 0;
160void KineticModel::start()
165 const int elapsed = d->timestamp.elapsed();
166 if ( elapsed > 2 * d->ticker.interval() ) {
172 d->deacceleration = d->velocity * 1000 / ( 1 + d_ptr->duration );
173 if (d->deacceleration.x() < 0) {
174 d->deacceleration.setX( -d->deacceleration.x() );
176 if (d->deacceleration.y() < 0) {
177 d->deacceleration.setY( -d->deacceleration.y() );
180 d->deaccelerationHeading =
qAbs(d->velocityHeading) * 1000 / ( 1 + d_ptr->duration );
182 if (!d->ticker.isActive())
186void KineticModel::update()
190 int elapsed =
qMin(
static_cast<int>(d->timestamp.elapsed()), 100 );
191 qreal delta =
static_cast<qreal
>(elapsed) / 1000.0;
194 if (d->changingPosition) {
195 d->position += d->velocity * delta;
198 if (d->velocity.x() <
vstep.x() && d->velocity.x() >= -
vstep.x()) {
199 d->velocity.setX( 0 );
201 if (d->velocity.x() > 0)
202 d->velocity.setX( d->velocity.x() -
vstep.x() );
204 d->velocity.setX( d->velocity.x() +
vstep.x() );
207 if (d->velocity.y() <
vstep.y() && d->velocity.y() >= -
vstep.y()) {
208 d->velocity.setY( 0 );
210 if (d->velocity.y() > 0)
211 d->velocity.setY( d->velocity.y() -
vstep.y() );
213 d->velocity.setY( d->velocity.y() +
vstep.y() );
216 stop = d->velocity.isNull();
218 emit positionChanged( d->position.x(), d->position.y() );
220 d->heading += d->velocityHeading * delta;
221 qreal
vstep = d->deaccelerationHeading * delta;
222 if ((d->velocityHeading <
vstep && d->velocityHeading >= -
vstep) || !
vstep) {
223 d->velocityHeading = 0;
225 d->velocityHeading += d->velocityHeading > 0 ? -1 *
vstep :
vstep;
228 stop = !d->velocityHeading;
230 emit headingChanged( d->heading );
238 d->timestamp.start();
241#include "moc_kineticmodel.cpp"
void stop(Ekos::AlignState mode)
void update(Part *part, const QByteArray &data, qint64 dataSize)
T qobject_cast(QObject *object)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)