• Qt QGraphicsItem对象setPos(),setScale(),setRotation()操作后Item坐标和Scene坐标的变化


     1     // 创建 item
     2  
     3     CustomItem *pItem = new CustomItem();
     4  
     5     pItem->setRect(20, 20, 60, 60);
     6  
     7  
     8  
     9     // 将 item 添加至场景中
    10  
    11     CustomScene scene;
    12  
    13     scene.setSceneRect(0, 0, 400, 300);
    14  
    15     scene.addItem(pItem);
    16  
    17    
    18  
    19     // 为视图设置场景
    20  
    21     QGraphicsView view;
    22  
    23     view.setScene(&scene);
    24  

    矩形左上角:

    Item pos: QPointF(23,19)

    scene pos: QPointF(23,19)

    矩形右下角:

    Item pos: QPointF(80,79)

    scene pos: QPointF(80,79)

    注:由于是用点击屏幕相应位置获取的坐标,可能存在一些误差。

    void QGraphicsItem::setPos(const QPointF &pos)

    Sets the position of the item to pos, which is in parent coordinates. For items with no parent, pos is in scene coordinates.

    The position of the item describes its origin (local coordinate (0, 0)) in parent coordinates.

    一 setPos操作之后的情况

    1 pItem->setRect(20, 20, 60, 60);
    2 pItem->setPos(50,50);
    所以setPos(50,50)是把item坐标点(0,0)设置为与scene坐标点(50,50)重合,那么矩形左上角的item坐标点为(20,20),则其scene坐标点即为(20+50,20+50)=(70,70);矩形右下角的item坐标点为(80,80),则其scene坐标点即为(80+50,80+50)=(130,130)。

    可理解为下图:

    矩形左上角:

    Item pos: QPointF(21,20)

    scene pos: QPointF(71,70)

    矩形右下角:

    Item pos: QPointF(78,79)

    scene pos: QPointF(128,129)

     

    void QGraphicsItem::setScale(qreal factor)

    Sets the scale factor of the item. The default scale factor is 1.0 (i.e., the item is not scaled). A scale factor of 0.0 will collapse the item to a single point. If you provide a negative scale factor, the item will be flipped and mirrored (i.e., rotated 180 degrees).

    The item is scaled around its transform origin point, which by default is (0, 0). You can select a different transformation origin by calling setTransformOriginPoint().

    The scale is combined with the item's rotation(), transform() and transformations() to map the item's coordinate system to the parent item.

    二 setScale()操作之后的情况

    1 pItem->setRect(20, 20, 60, 60);
    2 pItem->setPos(50,50);
    3 pItem->setScale(2);

    可以理解为下图所示:

    矩形左上角:

    Item pos: QPointF(20.5,20)

    scene pos: QPointF(91,90)

    矩形右下角:

    Item pos: QPointF(79,78)

    scene pos: QPointF(208,206)

     

    可以看出setScale(2)后,左上角和右下角的ItemPos并没有改变。item坐标点(0,0)仍然设置为与scene坐标点(50,50)重合,矩形左上角的item坐标点为(20,20),当放大两倍后左上角离itempos (0,0)的距离则变为20*2=40,及在scene坐标系中,矩形左上角的坐标为(50+20*2,50+20*2)=(90,90)。同理,矩形右下角的坐标在scene坐标系中变为(50+20*2+60*2,50+20*2+60*2)=(210,210)。

     

    三 接着添加setRotation()之后的情况

    void QGraphicsItem::setRotation(qreal angle)

    Sets the clockwise rotation angle, in degrees, around the Z axis. The default value is 0 (i.e., the item is not rotated). Assigning a negative value will rotate the item counter-clockwise. Normally the rotation angle is in the range (-360, 360), but it's also possible to assign values outside of this range (e.g., a rotation of 370 degrees is the same as a rotation of 10 degrees).

    The item is rotated around its transform origin point, which by default is (0, 0). You can select a different transformation origin by calling setTransformOriginPoint().

    The rotation is combined with the item's scale(), transform() and transformations() to map the item's coordinate system to the parent item.

    1 pItem->setRect(20, 20, 60, 60);
    2 pItem->setPos(50,50);
    3 pItem->setScale(2);
    4 pItem->setRotation(45);

    可以理解为下图所示:

    矩形左上角:

    Item pos: QPointF(20.5061,21.2132)

    scene pos: QPointF(49,109)

    矩形右下角

    Item pos: QPointF(78.1353,78.8424)

    scene pos: QPointF(49,272)

     

    矩形中心点scenepos: QPointF(50,191.421)

     

    可以看出放大之后旋转(默认是以itempos(0,0) (即是以scenepos(50,50))为轴进行旋转),左上角和右下角的ItemPos仍然没有改变。setScale(2)对于item坐标系中除了矩形区域外的其余部分没有影响。旋转之后,矩形在scene坐标系中的坐标发生了大幅度变化,因为scene坐标系并没有旋转。在scene坐标系中,矩形左上角坐标即为(50,50+20*sin45*2)=(50,106.569),右下角坐标为(50,106.569+60*2*sin45*2)=(50,276.274)。

     

    四 接着setTransformOriginPoint()后的情况

    void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)

    Sets the origin point for the transformation in item coordinates.

    1 pItem->setRect(20, 20, 60, 60);
    2 pItem->setPos(50,50);
    3 pItem->setScale(2);
    4 pItem->setRotation(45);
    5 pItem->setTransformOriginPoint(20,20);

    可理解为下图所示:

    矩形左上角:

    Item pos: QPointF(20.3536,21.0607)

    scene pos: QPointF(69,72)

    矩形右下角:

    Item pos: QPointF(78.6899,78.6899)

    scene pos: QPointF(70,236)

     

    矩形中心点scenepos: QPointF(70,154.853)

     

    可以看出修改TransformOriginPoint之后,新的TransformOriginPoint(20,20)与原本的默认TransformOriginPoint(0,0)之间的那一部分将不再受到pItem->setRotation(45)旋转的影响,而(20,20)之后的区域仍然基于新的变换原点正常变化。所以,在scene坐标系中,矩形左上角的坐标为(50+20,50+20)=(70,70),矩形右下角的坐标为(50+20,50+20+60*2*sin45*2)约等于(70,240)。

    1 pItem->setPos(50,50);
    2 pItem->setScale(2);
    3 pItem->setRotation(45);
    4 pItem->setTransformOriginPoint(50,50);

     

    可理解为示意图如下:

    矩形左上角

    Item pos: QPointF(20.3015,21.0086)

    scene pos: QPointF(99,17)

    矩形右下角

    Item pos: QPointF(78.9914,78.9914)

    scene pos: QPointF(100,182)

     

    矩形中心点scenepos: QPointF(100,100)

     

    可以看出setTransformOriginPoint(50,50)之后是以矩形的中心(缩放旋转前最初的中心坐标即为(50,50))为旋转轴心进行旋转和缩放的,且矩形中心的scenepos为(50+50,50+50)=(100,100)。则旋转缩放后在scene坐标系中,矩形的各点坐标可根据其相对于矩形中心的距离来求得,例如矩形左上角的坐标即为(100,100-60*2*sin45)=(100,15.147),矩形右下角的坐标即为(100,100+60*2*sin45)=(100,184.8)。

  • 相关阅读:
    点击按钮倒计时
    js实现-小框框全选
    CSS文字,文本,背景,盒模型等记录
    xps9560黑苹果展示
    面试——谈谈你对抽象和接口的理解(小知识大考点)
    谈谈你对Java 面向对象思想的理解
    谈谈你对Java 平台的理解
    HashMap1.7 问题总结
    2.3.2 InnoDB内存
    2.3 InnoDB 体系架构
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13528904.html
Copyright © 2020-2023  润新知