Results 1 to 3 of 3

Thread: QGraphicsItem resize with mouse position and keeping aspect ratio

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Mar 2021
    Posts
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: QGraphicsItem resize with mouse position and keeping aspect ratio

    I found a solution using vector math.(thanks to my colleague Dima Chernikov)

    ABCD - our picture.

    K' - cursor point.

    D2 - the point we are looking for(new position of D)

    gif example: https://media.giphy.com/media/uffXKj...vsR2/giphy.gif

    (circlePos_ == eBottomLeft) in code
    1488.jpg

    code: (I will most likely redo it later using templates. but now it is more clear for understanding)
    Qt Code:
    1. void MovableCircle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    2. {
    3. auto pos = mapToScene(event->pos() + _shiftMouseCoords);
    4.  
    5. qreal xl = pos.x();
    6. qreal yl = pos.y();
    7. auto rect = parentItem()->boundingRect();
    8.  
    9. QPointF a(rect.x(), rect.y());
    10. QPointF b(rect.x() + rect.width(), rect.y());
    11. QPointF c(rect.x() + rect.width(), rect.y() + rect.height());
    12. QPointF d(rect.x(), rect.y() + rect.height());
    13.  
    14.  
    15. if (circlePos_ == eTopRight) {
    16. Vec2d dc(c.x()-d.x(), c.y()-d.y());
    17. Vec2d cb(b.x()-c.x(), b.y()-c.y());
    18. Vec2d db(b.x()-d.x(), b.y()-d.y());
    19. Vec2d dk(pos.x()-d.x(), pos.y()-d.y());
    20.  
    21. auto dc_len = dc.length();
    22. auto cb_len = cb.length();
    23. auto db_len = db.length();
    24. auto dk_len = dk.length();
    25.  
    26. auto dkdb_dot = Vec2d<qreal>::dot(db, dk);
    27. auto cos_kdb = dkdb_dot/(db_len*dk_len);
    28. auto dd2_len = dk_len * cos_kdb;
    29.  
    30. auto x =(dd2_len * dc_len) / (std::sqrt(cb_len * cb_len + dc_len * dc_len));
    31. auto y = std::sqrt(dd2_len * dd2_len - x * x);
    32.  
    33. if (x < 10 || y < 10) return;
    34. pos.setX(d.x()+x);
    35. pos.setY(d.y()-y);
    36. }
    37.  
    38. if (circlePos_ == eBottomRight) {
    39. Vec2d ad(d.x()-a.x(), d.y()-a.y());
    40. Vec2d dc(c.x()-d.x(), c.y()-d.y());
    41. Vec2d ac(c.x()-a.x(), c.y()-a.y());
    42. Vec2d ak(pos.x()-a.x(), pos.y()-a.y());
    43.  
    44. auto ad_len = ad.length();
    45. auto dc_len = dc.length();
    46. auto ac_len = ac.length();
    47. auto ak_len = ak.length();
    48.  
    49. auto akac_dot = Vec2d<qreal>::dot(ac, ak);
    50. auto cos_kac = akac_dot/(ac_len*ak_len);
    51. auto ad2_len = ak_len * cos_kac;
    52.  
    53. auto x =(ad2_len * dc_len) / (std::sqrt(ad_len * ad_len + dc_len * dc_len));
    54. auto y = std::sqrt(ad2_len * ad2_len - x * x);
    55.  
    56. if (x < 10 || y < 10) return;
    57. pos.setX(a.x()+x);
    58. pos.setY(a.y()+y);
    59. }
    60.  
    61. if (circlePos_ == eTopLeft) {
    62. qDebug()<<this->parentItem()->boundingRect();
    63. Vec2d cb(b.x()-c.x(), b.y()-c.y());
    64. Vec2d ba(a.x()-b.x(), a.y()-b.y());
    65. Vec2d ca(a.x()-c.x(), a.y()-c.y());
    66. Vec2d ck(pos.x()-c.x(), pos.y()-c.y());
    67.  
    68. auto cb_len = cb.length();
    69. auto ba_len = ba.length();
    70. auto ca_len = ca.length();
    71. auto ck_len = ck.length();
    72.  
    73. auto ckca_dot = Vec2d<qreal>::dot(ca, ck);
    74. auto cos_kca = ckca_dot/(ca_len*ck_len);
    75. auto cd2_len = ck_len * cos_kca;
    76.  
    77. auto y =(cd2_len * cb_len) / (std::sqrt(ba_len * ba_len + cb_len * cb_len));
    78. auto x = std::sqrt(cd2_len * cd2_len - y * y);
    79.  
    80. if (x < 10 || y < 10) return;
    81. pos.setX(c.x()-x);
    82. pos.setY(c.y()-y);
    83. }
    84.  
    85. if (circlePos_ == eBottomLeft) {
    86. qDebug()<<this->parentItem()->boundingRect();
    87. Vec2d ba(a.x()-b.x(), a.y()-b.y());
    88. Vec2d ad(d.x()-a.x(), d.y()-a.y());
    89. Vec2d bd(d.x()-b.x(), d.y()-b.y());
    90. Vec2d bk(pos.x()-b.x(), pos.y()-b.y());
    91.  
    92. auto ba_len = ba.length();
    93. auto ad_len = ad.length();
    94. auto bd_len = bd.length();
    95. auto bk_len = bk.length();
    96.  
    97. auto bkbd_dot = Vec2d<qreal>::dot(bd, bk);
    98. auto cos_kdb = bkbd_dot/(bd_len*bk_len);
    99. auto bd2_len = bk_len * cos_kdb;
    100.  
    101. auto x =(bd2_len * ba_len) / (std::sqrt(ad_len * ad_len + ba_len * ba_len));
    102. auto y = std::sqrt(bd2_len * bd2_len - x * x);
    103.  
    104. if (x < 10 || y < 10) return;
    105. pos.setX(b.x()-x);
    106. pos.setY(b.y()+y);
    107. }
    108.  
    109. setPos(pos);
    110. emit circleMoved();
    111. }
    To copy to clipboard, switch view to plain text mode 

  2. The following user says thank you to angeleyes for this useful post:

    d_stranz (27th March 2021)

Similar Threads

  1. Replies: 2
    Last Post: 17th June 2020, 22:18
  2. Replies: 3
    Last Post: 2nd September 2016, 12:44
  3. Replies: 3
    Last Post: 26th May 2015, 23:14
  4. Replies: 2
    Last Post: 7th December 2013, 19:02
  5. keeping aspect ratio while resizing
    By franco.amato in forum Qt Programming
    Replies: 2
    Last Post: 19th November 2009, 20:12

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.