478{
479 Q_UNUSED(shiftModifierActive);
480 Q_UNUSED(altModifierActive);
481
482 m_d->isTransforming =
true;
483
484 switch (
m_d->function) {
486 break;
488 QPointF diff = mousePos -
m_d->clickPos;
489 m_d->currentArgs.setTransformedCenter(
490 m_d->clickArgs.transformedCenter() + diff);
491 break;
492 }
493 case DRAG_HANDLE: {
496 if (
m_d->currentDraggingHandlePoint < HANDLE_MIDDLE_TOP) {
497
498 m_d->dstHandlePoints[
m_d->currentDraggingHandlePoint] = mousePos;
499 } else {
500
501 QPointF delta = mousePos -
m_d->dstHandlePoints[
m_d->currentDraggingHandlePoint];
502 switch(
m_d->currentDraggingHandlePoint) {
503 case HANDLE_MIDDLE_TOP:
504 m_d->dstHandlePoints[HANDLE_TOP_LEFT] += delta;
505 m_d->dstHandlePoints[HANDLE_TOP_RIGHT] += delta;
506 break;
507 case HANDLE_MIDDLE_BOTTOM:
508 m_d->dstHandlePoints[HANDLE_BOTTOM_LEFT] += delta;
509 m_d->dstHandlePoints[HANDLE_BOTTOM_RIGHT] += delta;
510 break;
511 case HANDLE_MIDDLE_LEFT:
512 m_d->dstHandlePoints[HANDLE_TOP_LEFT] += delta;
513 m_d->dstHandlePoints[HANDLE_BOTTOM_LEFT] += delta;
514 break;
515 case HANDLE_MIDDLE_RIGHT:
516 m_d->dstHandlePoints[HANDLE_TOP_RIGHT] += delta;
517 m_d->dstHandlePoints[HANDLE_BOTTOM_RIGHT] += delta;
518 break;
519 }
520 }
521
524 Eigen::Matrix3f result =
B *
A.inverse();
525
526
527
528 QPolygonF poly;
529 poly <<
m_d->dstHandlePoints[HANDLE_TOP_LEFT] <<
m_d->dstHandlePoints[HANDLE_TOP_RIGHT]
530 <<
m_d->dstHandlePoints[HANDLE_BOTTOM_RIGHT] <<
m_d->dstHandlePoints[HANDLE_BOTTOM_LEFT];
531
532
534 break;
535 }
536
537 m_d->transformIntoArgs(result);
538
539 break;
540 }
541 case DRAG_X_VANISHING_POINT:
542 case DRAG_Y_VANISHING_POINT: {
543
544 QMatrix4x4 m(
m_d->transform);
545
546 QPointF tl =
m_d->transaction.originalTopLeft();
547 QPointF tr =
m_d->transaction.originalTopRight();
548 QPointF bl =
m_d->transaction.originalBottomLeft();
549 QPointF br =
m_d->transaction.originalBottomRight();
550
551 QVector4D
v(1,0,0,0);
552 QVector4D otherV(0,1,0,0);
553
554 if (
m_d->function == DRAG_X_VANISHING_POINT) {
555 v = QVector4D(1,0,0,0);
556 otherV = QVector4D(0,1,0,0);
557 } else {
558 v = QVector4D(0,1,0,0);
559 otherV = QVector4D(1,0,0,0);
560 }
561
567 QPointF otherV_dst =
toQPointF(m * otherV);
568
571
572 QPointF far1_src;
573 QPointF far2_src;
574 QPointF near1_src;
575 QPointF near2_src;
576
577 QPointF far1_dst;
578 QPointF far2_dst;
579 QPointF near1_dst;
580 QPointF near2_dst;
581
582 if (
m_d->function == DRAG_X_VANISHING_POINT) {
583
584
586 far1_src = tl;
587 far2_src = bl;
588 near1_src = tr;
589 near2_src = br;
590
591 far1_dst = tl_dst;
592 far2_dst = bl_dst;
593 near1_dst = tr_dst;
594 near2_dst = br_dst;
595
596
597 } else {
598 far1_src = tr;
599 far2_src = br;
600 near1_src = tl;
601 near2_src = bl;
602
603 far1_dst = tr_dst;
604 far2_dst = br_dst;
605 near1_dst = tl_dst;
606 near2_dst = bl_dst;
607 }
608
609 } else {
610
612 far1_src = tl;
613 far2_src = tr;
614 near1_src = bl;
615 near2_src = br;
616
617 far1_dst = tl_dst;
618 far2_dst = tr_dst;
619 near1_dst = bl_dst;
620 near2_dst = br_dst;
621
622
623 } else {
624 far1_src = bl;
625 far2_src = br;
626 near1_src = tl;
627 near2_src = tr;
628
629 far1_dst = bl_dst;
630 far2_dst = br_dst;
631 near1_dst = tl_dst;
632 near2_dst = tr_dst;
633 }
634 }
635
636 QLineF l0(far1_dst, mousePos);
637 QLineF l1(far2_dst, mousePos);
638 QLineF l2(otherV_dst, near1_dst);
639 l0.intersects(l2, &near1_dst);
640 l1.intersects(l2, &near2_dst);
641
642 srcPoints << far1_src;
643 srcPoints << far2_src;
644 srcPoints << near1_src;
645 srcPoints << near2_src;
646
647 dstPoints << far1_dst;
648 dstPoints << far2_dst;
649 dstPoints << near1_dst;
650 dstPoints << near2_dst;
651
654 Eigen::Matrix3f result =
B *
A.inverse();
655
656 m_d->transformIntoArgs(result);
657 break;
658 }
659 }
660
661 m_d->recalculateTransformations();
662}
#define KIS_ASSERT_RECOVER_RETURN(cond)
qreal kisSquareDistance(const QPointF &pt1, const QPointF &pt2)
QPointF toQPointF(const ExpressionType &expr)
bool isPolygonTrulyConvex(const QVector< T > &polygon, bool ensureNoLoops=true)