Krita Source Code Documentation
Loading...
Searching...
No Matches
KisDistanceInformation Class Reference

#include <kis_distance_information.h>

+ Inheritance diagram for KisDistanceInformation:

Public Member Functions

int currentDabSeqNo () const
 
const KisSpacingInformationcurrentSpacing () const
 
const KisTimingInformationcurrentTiming () const
 
qreal getNextPointPosition (const QPointF &start, const QPointF &end, qreal startTime, qreal endTime)
 
qreal getSpacingInterval () const
 
qreal getTimingUpdateInterval () const
 
bool hasLastDabInformation () const
 
bool hasLastPaintInformation () const
 
bool isStarted () const
 
 KisDistanceInformation ()
 
 KisDistanceInformation (const KisDistanceInformation &rhs)
 
 KisDistanceInformation (const KisDistanceInformation &rhs, int levelOfDetail)
 
 KisDistanceInformation (const QPointF &lastPosition, qreal lastAngle)
 
 KisDistanceInformation (const QPointF &lastPosition, qreal lastAngle, qreal spacingUpdateInterval, qreal timingUpdateInterval, int currentDabSeqNo)
 
 KisDistanceInformation (qreal spacingUpdateInterval, qreal timingUpdateInterval, int currentDabSeqNo=0)
 
qreal lastDrawingAngle () const
 
const KisPaintInformationlastPaintInformation () const
 
QPointF lastPosition () const
 
void lockCurrentDrawingAngle (const KisPaintInformation &info) const
 
boost::optional< qreal > lockedDrawingAngleOptional () const
 
qreal maxPressure () const
 
bool needsSpacingUpdate () const
 
bool needsTimingUpdate () const
 
KisDistanceInformationoperator= (const KisDistanceInformation &rhs)
 
void overrideLastValues (const QPointF &lastPosition, qreal lastAngle)
 
 Private ()
 
void registerPaintedDab (const KisPaintInformation &info, const KisSpacingInformation &spacing, const KisTimingInformation &timing)
 
qreal scalarDistanceApprox () const
 
void updateSpacing (const KisSpacingInformation &spacing)
 
void updateTiming (const KisTimingInformation &timing)
 
 ~KisDistanceInformation ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Public Attributes

QPointF accumDistance
 
qreal accumTime
 
int currentDabSeqNo
 
qreal lastAngle
 
bool lastDabInfoValid
 
qreal lastMaxPressure = 0.0
 
KisPaintInformation lastPaintInformation
 
bool lastPaintInfoValid
 
QPointF lastPosition
 
int levelOfDetail
 
boost::optional< qreal > lockedDrawingAngleOptional
 
KisSpacingInformation spacing
 
qreal spacingUpdateInterval
 
qreal timeSinceSpacingUpdate
 
qreal timeSinceTimingUpdate
 
KisTimingInformation timing
 
qreal timingUpdateInterval
 
qreal totalDistance
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Private Member Functions

qreal getNextPointPositionAnisotropic (const QPointF &start, const QPointF &end)
 
qreal getNextPointPositionIsotropic (const QPointF &start, const QPointF &end)
 
qreal getNextPointPositionTimed (qreal startTime, qreal endTime)
 
void resetAccumulators ()
 

Private Attributes

Private *const m_d
 

Detailed Description

This structure keeps track of distance and timing information during a stroke, e.g. the time or distance moved since the last dab.

Definition at line 29 of file kis_distance_information.cpp.

Constructor & Destructor Documentation

◆ KisDistanceInformation() [1/6]

KisDistanceInformation::KisDistanceInformation ( )

Definition at line 233 of file kis_distance_information.cpp.

234 : m_d(new Private)
235{
236}

◆ KisDistanceInformation() [2/6]

KisDistanceInformation::KisDistanceInformation ( qreal spacingUpdateInterval,
qreal timingUpdateInterval,
int currentDabSeqNo = 0 )

Definition at line 238 of file kis_distance_information.cpp.

241 : m_d(new Private)
242{
243 m_d->spacingUpdateInterval = spacingUpdateInterval;
244 m_d->timingUpdateInterval = timingUpdateInterval;
245 m_d->currentDabSeqNo = currentDabSeqNo;
246}

References currentDabSeqNo, m_d, spacingUpdateInterval, and timingUpdateInterval.

◆ KisDistanceInformation() [3/6]

KisDistanceInformation::KisDistanceInformation ( const QPointF & lastPosition,
qreal lastAngle )

Definition at line 248 of file kis_distance_information.cpp.

250 : m_d(new Private)
251{
252 m_d->lastPosition = lastPosition;
253 m_d->lastAngle = lastAngle;
254
255 m_d->lastDabInfoValid = true;
256}

References lastAngle, lastPosition, and m_d.

◆ KisDistanceInformation() [4/6]

KisDistanceInformation::KisDistanceInformation ( const QPointF & lastPosition,
qreal lastAngle,
qreal spacingUpdateInterval,
qreal timingUpdateInterval,
int currentDabSeqNo )
Parameters
spacingUpdateIntervalThe amount of time allowed between spacing updates, in milliseconds. Use LONG_TIME to only allow spacing updates when a dab is painted.
timingUpdateIntervalThe amount of time allowed between time-based spacing updates, in milliseconds. Use LONG_TIME to only allow timing updates when a dab is painted.

Definition at line 258 of file kis_distance_information.cpp.

264{
265 m_d->spacingUpdateInterval = spacingUpdateInterval;
266 m_d->timingUpdateInterval = timingUpdateInterval;
267 m_d->currentDabSeqNo = currentDabSeqNo;
268}

References currentDabSeqNo, m_d, spacingUpdateInterval, and timingUpdateInterval.

◆ KisDistanceInformation() [5/6]

KisDistanceInformation::KisDistanceInformation ( const KisDistanceInformation & rhs)

Definition at line 270 of file kis_distance_information.cpp.

271 : m_d(new Private(*rhs.m_d))
272{
273
274}

◆ KisDistanceInformation() [6/6]

KisDistanceInformation::KisDistanceInformation ( const KisDistanceInformation & rhs,
int levelOfDetail )

Definition at line 276 of file kis_distance_information.cpp.

277 : m_d(new Private(*rhs.m_d))
278{
279 KIS_ASSERT_RECOVER_NOOP(!m_d->lastPaintInfoValid &&
280 "The distance information "
281 "should be cloned before the "
282 "actual painting is started");
283
284 m_d->levelOfDetail = levelOfDetail;
285
287 m_d->lastPosition = t.map(m_d->lastPosition);
288}
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97

References KIS_ASSERT_RECOVER_NOOP, levelOfDetail, m_d, and KisLodTransform::map().

◆ ~KisDistanceInformation()

KisDistanceInformation::~KisDistanceInformation ( )

Definition at line 305 of file kis_distance_information.cpp.

306{
307 delete m_d;
308}

References m_d.

Member Function Documentation

◆ currentDabSeqNo()

int KisDistanceInformation::currentDabSeqNo ( ) const

◆ currentSpacing()

const KisSpacingInformation & KisDistanceInformation::currentSpacing ( ) const

Definition at line 310 of file kis_distance_information.cpp.

311{
312 return m_d->spacing;
313}

References m_d.

◆ currentTiming()

const KisTimingInformation & KisDistanceInformation::currentTiming ( ) const

Definition at line 326 of file kis_distance_information.cpp.

327{
328 return m_d->timing;
329}

References m_d.

◆ getNextPointPosition()

qreal KisDistanceInformation::getNextPointPosition ( const QPointF & start,
const QPointF & end,
qreal startTime,
qreal endTime )

Definition at line 405 of file kis_distance_information.cpp.

409{
410 // Compute interpolation factor based on distance.
411 qreal distanceFactor = -1.0;
412 if (m_d->spacing.isDistanceSpacingEnabled()) {
413 distanceFactor = m_d->spacing.isIsotropic() ?
416 }
417
418 // Compute interpolation factor based on time.
419 qreal timeFactor = -1.0;
420 if (m_d->timing.isTimedSpacingEnabled()) {
421 timeFactor = getNextPointPositionTimed(startTime, endTime);
422 }
423
424 // Return the distance-based or time-based factor, whichever is smallest.
425 qreal t = -1.0;
426 if (distanceFactor < 0.0) {
427 t = timeFactor;
428 } else if (timeFactor < 0.0) {
429 t = distanceFactor;
430 } else {
431 t = qMin(distanceFactor, timeFactor);
432 }
433
434 // If we aren't ready to paint a dab, accumulate time for the spacing/timing updates that might
435 // be needed between dabs.
436 if (t < 0.0) {
437 m_d->timeSinceSpacingUpdate += endTime - startTime;
438 m_d->timeSinceTimingUpdate += endTime - startTime;
439 }
440
441 // If we are ready to paint a dab, reset the accumulated time for spacing/timing updates.
442 else {
443 m_d->timeSinceSpacingUpdate = 0.0;
444 m_d->timeSinceTimingUpdate = 0.0;
445 }
446
447 return t;
448}
qreal getNextPointPositionAnisotropic(const QPointF &start, const QPointF &end)
qreal getNextPointPositionIsotropic(const QPointF &start, const QPointF &end)
qreal getNextPointPositionTimed(qreal startTime, qreal endTime)

References getNextPointPositionAnisotropic(), getNextPointPositionIsotropic(), getNextPointPositionTimed(), and m_d.

◆ getNextPointPositionAnisotropic()

qreal KisDistanceInformation::getNextPointPositionAnisotropic ( const QPointF & start,
const QPointF & end )
private

Definition at line 492 of file kis_distance_information.cpp.

494{
495 if (start == end) {
496 return -1;
497 }
498
499 qreal a_rev = 1.0 / qMax(MIN_DISTANCE_SPACING, m_d->spacing.distanceSpacing().x());
500 qreal b_rev = 1.0 / qMax(MIN_DISTANCE_SPACING, m_d->spacing.distanceSpacing().y());
501
502 qreal x = m_d->accumDistance.x();
503 qreal y = m_d->accumDistance.y();
504
505 qreal gamma = pow2(x * a_rev) + pow2(y * b_rev) - 1;
506
507 // If the distance accumulator is already past the spacing ellipse, have a point painted
508 // immediately. This can happen if the spacing info has been modified since the last
509 // interpolation attempt.
510 if (gamma >= 0.0) {
512 return 0.0;
513 }
514
515 static const qreal eps = 2e-3; // < 0.2 deg
516
517 qreal currentRotation = m_d->spacing.rotation();
518 if (m_d->spacing.coordinateSystemFlipped()) {
519 currentRotation = 2 * M_PI - currentRotation;
520 }
521
522 QPointF diff = end - start;
523
524 if (currentRotation > eps) {
525 QTransform rot;
526 // since the ellipse is symmetrical, the sign
527 // of rotation doesn't matter
528 rot.rotateRadians(currentRotation);
529 diff = rot.map(diff);
530 }
531
532 qreal dx = qAbs(diff.x());
533 qreal dy = qAbs(diff.y());
534
535 qreal alpha = pow2(dx * a_rev) + pow2(dy * b_rev);
536 qreal beta = x * dx * a_rev * a_rev + y * dy * b_rev * b_rev;
537 qreal D_4 = pow2(beta) - alpha * gamma;
538
539 qreal t = -1.0;
540
541 if (D_4 >= 0) {
542 qreal k = (-beta + qSqrt(D_4)) / alpha;
543
544 if (k >= 0.0 && k <= 1.0) {
545 t = k;
547 } else {
548 m_d->accumDistance += KisAlgebra2D::abs(diff);
549 }
550 } else {
551 warnKrita << "BUG: No solution for elliptical spacing equation has been found. This shouldn't have happened.";
552 }
553
554 return t;
555}
const qreal eps
#define warnKrita
Definition kis_debug.h:87
const qreal MIN_DISTANCE_SPACING
T pow2(const T &x)
Definition kis_global.h:166
#define M_PI
Definition kis_global.h:111
Point abs(const Point &pt)

References KisAlgebra2D::abs(), eps, m_d, M_PI, MIN_DISTANCE_SPACING, pow2(), resetAccumulators(), and warnKrita.

◆ getNextPointPositionIsotropic()

qreal KisDistanceInformation::getNextPointPositionIsotropic ( const QPointF & start,
const QPointF & end )
private

Definition at line 460 of file kis_distance_information.cpp.

462{
463 qreal distance = m_d->accumDistance.x();
464 qreal spacing = qMax(MIN_DISTANCE_SPACING, m_d->spacing.distanceSpacing().x());
465
466 if (start == end) {
467 return -1;
468 }
469
470 qreal dragVecLength = QVector2D(end - start).length();
471 qreal nextPointDistance = spacing - distance;
472
473 qreal t;
474
475 // nextPointDistance can sometimes be negative if the spacing info has been modified since the
476 // last interpolation attempt. In that case, have a point painted immediately.
477 if (nextPointDistance <= 0.0) {
479 t = 0.0;
480 }
481 else if (nextPointDistance <= dragVecLength) {
482 t = nextPointDistance / dragVecLength;
484 } else {
485 t = -1;
486 m_d->accumDistance.rx() += dragVecLength;
487 }
488
489 return t;
490}
qreal distance(const QPointF &p1, const QPointF &p2)

References distance(), m_d, MIN_DISTANCE_SPACING, resetAccumulators(), and spacing.

◆ getNextPointPositionTimed()

qreal KisDistanceInformation::getNextPointPositionTimed ( qreal startTime,
qreal endTime )
private

Definition at line 557 of file kis_distance_information.cpp.

559{
560 // If start time is not before end time, do not interpolate.
561 if (!(startTime < endTime)) {
562 return -1.0;
563 }
564
565 qreal timedSpacingInterval = qBound(MIN_TIMED_INTERVAL, m_d->timing.timedSpacingInterval(),
567 qreal nextPointInterval = timedSpacingInterval - m_d->accumTime;
568
569 qreal t = -1.0;
570
571 // nextPointInterval can sometimes be negative if the spacing info has been modified since the
572 // last interpolation attempt. In that case, have a point painted immediately.
573 if (nextPointInterval <= 0.0) {
575 t = 0.0;
576 }
577 else if (nextPointInterval <= endTime - startTime) {
579 t = nextPointInterval / (endTime - startTime);
580 }
581 else {
582 m_d->accumTime += endTime - startTime;
583 t = -1.0;
584 }
585
586 return t;
587}
const qreal MAX_TIMED_INTERVAL
const qreal MIN_TIMED_INTERVAL

References m_d, MAX_TIMED_INTERVAL, MIN_TIMED_INTERVAL, and resetAccumulators().

◆ getSpacingInterval()

qreal KisDistanceInformation::getSpacingInterval ( ) const

Definition at line 450 of file kis_distance_information.cpp.

451{
452 return m_d->spacingUpdateInterval;
453}

References m_d.

◆ getTimingUpdateInterval()

qreal KisDistanceInformation::getTimingUpdateInterval ( ) const

Definition at line 455 of file kis_distance_information.cpp.

456{
457 return m_d->timingUpdateInterval;
458}

References m_d.

◆ hasLastDabInformation()

bool KisDistanceInformation::hasLastDabInformation ( ) const

Definition at line 342 of file kis_distance_information.cpp.

343{
344 return m_d->lastDabInfoValid;
345}

References m_d.

◆ hasLastPaintInformation()

bool KisDistanceInformation::hasLastPaintInformation ( ) const

Definition at line 357 of file kis_distance_information.cpp.

358{
359 return m_d->lastPaintInfoValid;
360}

References m_d.

◆ isStarted()

bool KisDistanceInformation::isStarted ( ) const
Returns
true if at least one dab has been painted with this distance information

Definition at line 377 of file kis_distance_information.cpp.

378{
379 return m_d->lastPaintInfoValid;
380}

References m_d.

◆ lastDrawingAngle()

qreal KisDistanceInformation::lastDrawingAngle ( ) const

Definition at line 352 of file kis_distance_information.cpp.

353{
354 return m_d->lastAngle;
355}

References m_d.

◆ lastPaintInformation()

const KisPaintInformation & KisDistanceInformation::lastPaintInformation ( ) const

◆ lastPosition()

QPointF KisDistanceInformation::lastPosition ( ) const

◆ lockCurrentDrawingAngle()

void KisDistanceInformation::lockCurrentDrawingAngle ( const KisPaintInformation & info) const

Lock current drawing angle for the rest of the stroke. The new value is blended into the result proportional to the length of the stroke.

Definition at line 600 of file kis_distance_information.cpp.

601{
602 qreal newAngle = info.drawingAngle(false);
603
604 if (m_d->lockedDrawingAngleOptional) {
605 newAngle = *m_d->lockedDrawingAngleOptional;
606 }
607
608 m_d->lockedDrawingAngleOptional = newAngle;
609}
qreal drawingAngle(bool considerLockedAngle=false) const

References KisPaintInformation::drawingAngle(), and m_d.

◆ lockedDrawingAngleOptional()

boost::optional< qreal > KisDistanceInformation::lockedDrawingAngleOptional ( ) const

◆ maxPressure()

qreal KisDistanceInformation::maxPressure ( ) const

Definition at line 372 of file kis_distance_information.cpp.

373{
374 return m_d->lastMaxPressure;
375}

References m_d.

◆ needsSpacingUpdate()

bool KisDistanceInformation::needsSpacingUpdate ( ) const

Returns true if this KisDistanceInformation should have its spacing information updated immediately (regardless of whether a dab is ready to be painted).

Definition at line 321 of file kis_distance_information.cpp.

322{
323 return m_d->timeSinceSpacingUpdate >= m_d->spacingUpdateInterval;
324}

References m_d.

◆ needsTimingUpdate()

bool KisDistanceInformation::needsTimingUpdate ( ) const

Returns true if this KisDistanceInformation should have its timing information updated immediately (regardless of whether a dab is ready to be painted).

Definition at line 337 of file kis_distance_information.cpp.

338{
339 return m_d->timeSinceTimingUpdate >= m_d->timingUpdateInterval;
340}

References m_d.

◆ operator=()

KisDistanceInformation & KisDistanceInformation::operator= ( const KisDistanceInformation & rhs)

Definition at line 290 of file kis_distance_information.cpp.

291{
292 *m_d = *rhs.m_d;
293 return *this;
294}

References m_d.

◆ overrideLastValues()

void KisDistanceInformation::overrideLastValues ( const QPointF & lastPosition,
qreal lastAngle )

Definition at line 296 of file kis_distance_information.cpp.

298{
299 m_d->lastPosition = lastPosition;
300 m_d->lastAngle = lastAngle;
301
302 m_d->lastDabInfoValid = true;
303}

References lastAngle, lastPosition, and m_d.

◆ Private()

◆ registerPaintedDab()

void KisDistanceInformation::registerPaintedDab ( const KisPaintInformation & info,
const KisSpacingInformation & spacing,
const KisTimingInformation & timing )
Parameters
spacingThe new effective spacing after the dab. (Painting a dab is always supposed to cause a spacing update.)
timingThe new effective timing after the dab. (Painting a dab is always supposed to cause a timing update.)

Definition at line 382 of file kis_distance_information.cpp.

385{
386 m_d->totalDistance +=
387 KisAlgebra2D::norm(info.pos() - m_d->lastPosition) *
388 KisLodTransform::lodToInvScale(m_d->levelOfDetail);
389
390 m_d->lastPaintInformation = info;
391 m_d->lastPaintInfoValid = true;
392
393 m_d->lastAngle = info.drawingAngle(false);
394 m_d->lastPosition = info.pos();
395 m_d->lastDabInfoValid = true;
396
397 m_d->spacing = spacing;
398 m_d->timing = timing;
399
400 m_d->currentDabSeqNo++;
401
402 m_d->lastMaxPressure = qMax(info.pressure(), m_d->lastMaxPressure);
403}
static qreal lodToInvScale(int levelOfDetail)
const QPointF & pos() const
qreal pressure() const
The pressure of the value (from 0.0 to 1.0)
qreal norm(const T &a)

References KisPaintInformation::drawingAngle(), KisLodTransformBase::lodToInvScale(), m_d, KisAlgebra2D::norm(), KisPaintInformation::pos(), KisPaintInformation::pressure(), spacing, and timing.

◆ resetAccumulators()

void KisDistanceInformation::resetAccumulators ( )
private

Definition at line 589 of file kis_distance_information.cpp.

590{
591 m_d->accumDistance = QPointF();
592 m_d->accumTime = 0.0;
593}

References m_d.

◆ scalarDistanceApprox()

qreal KisDistanceInformation::scalarDistanceApprox ( ) const

Definition at line 612 of file kis_distance_information.cpp.

613{
614 return m_d->totalDistance;
615}

References m_d.

◆ updateSpacing()

void KisDistanceInformation::updateSpacing ( const KisSpacingInformation & spacing)

Definition at line 315 of file kis_distance_information.cpp.

316{
317 m_d->spacing = spacing;
318 m_d->timeSinceSpacingUpdate = 0.0;
319}

References m_d, and spacing.

◆ updateTiming()

void KisDistanceInformation::updateTiming ( const KisTimingInformation & timing)

Definition at line 331 of file kis_distance_information.cpp.

332{
333 m_d->timing = timing;
334 m_d->timeSinceTimingUpdate = 0.0;
335}

References m_d, and timing.

Member Data Documentation

◆ accumDistance

QPointF KisDistanceInformation::accumDistance

Definition at line 47 of file kis_distance_information.cpp.

◆ accumTime

qreal KisDistanceInformation::accumTime

Definition at line 48 of file kis_distance_information.cpp.

◆ currentDabSeqNo

int KisDistanceInformation::currentDabSeqNo

Definition at line 72 of file kis_distance_information.cpp.

◆ lastAngle

qreal KisDistanceInformation::lastAngle

Definition at line 62 of file kis_distance_information.cpp.

◆ lastDabInfoValid

bool KisDistanceInformation::lastDabInfoValid

Definition at line 63 of file kis_distance_information.cpp.

◆ lastMaxPressure

qreal KisDistanceInformation::lastMaxPressure = 0.0

Definition at line 75 of file kis_distance_information.cpp.

◆ lastPaintInformation

const KisPaintInformation & KisDistanceInformation::lastPaintInformation

Definition at line 66 of file kis_distance_information.cpp.

◆ lastPaintInfoValid

bool KisDistanceInformation::lastPaintInfoValid

Definition at line 67 of file kis_distance_information.cpp.

◆ lastPosition

QPointF KisDistanceInformation::lastPosition

Definition at line 61 of file kis_distance_information.cpp.

◆ levelOfDetail

int KisDistanceInformation::levelOfDetail

Definition at line 73 of file kis_distance_information.cpp.

◆ lockedDrawingAngleOptional

boost::optional< qreal > KisDistanceInformation::lockedDrawingAngleOptional

Definition at line 70 of file kis_distance_information.cpp.

◆ m_d

Private* const KisDistanceInformation::m_d
private

Definition at line 179 of file kis_distance_information.h.

◆ spacing

KisSpacingInformation KisDistanceInformation::spacing

Definition at line 50 of file kis_distance_information.cpp.

◆ spacingUpdateInterval

qreal KisDistanceInformation::spacingUpdateInterval

Definition at line 51 of file kis_distance_information.cpp.

◆ timeSinceSpacingUpdate

qreal KisDistanceInformation::timeSinceSpacingUpdate

Definition at line 53 of file kis_distance_information.cpp.

◆ timeSinceTimingUpdate

qreal KisDistanceInformation::timeSinceTimingUpdate

Definition at line 58 of file kis_distance_information.cpp.

◆ timing

KisTimingInformation KisDistanceInformation::timing

Definition at line 55 of file kis_distance_information.cpp.

◆ timingUpdateInterval

qreal KisDistanceInformation::timingUpdateInterval

Definition at line 56 of file kis_distance_information.cpp.

◆ totalDistance

qreal KisDistanceInformation::totalDistance

Definition at line 69 of file kis_distance_information.cpp.


The documentation for this class was generated from the following files: