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