Qt|关于QGraphicsView中的相对坐标系自定义实现

需求:
不采用QGraphicsView本身的平移和旋转是因为所有的item是自定义封装的,存在交互上的数据变化,如果采用Qt自带的转换会导致交互数据出现错乱
实现思想:
放弃了坐标系的概念,采用虚拟坐标系代替–坐标系不存在,但是体现在所有item的数据上;
所有的数据都是原始坐标系,只是记录相对坐标系的值。
实现步骤:
当前坐标系的点----》需要被转换的坐标系的点----》原始坐标系的点
【Qt|关于QGraphicsView中的相对坐标系自定义实现】简单点就是:在相对坐标系(100,100)中,点(10,10)(注:该点是实际相对坐标系的点的位置) ---->在原始坐标系中的点的坐标为(110,110)---->相对坐标系(200,200)中的点(210,210)。最后的结果是原始坐标值的数值,但是我记录了相对坐标系的值。如果想知道该点在原始坐标系中的值,可以通过记录的相对坐标值进行转换
代码注释不多。主要是实现该功能的思想。

#define Pi 3.1415926 const qreal deg2rad = qreal(0.0174532925199)//pi/180struct CoorDinate_Stru{ qreal x = 0; qreal y = 0; qreal angle = 0; //坐标系角度 qreal scale; //暂时不考虑 } QPointF conver_coordinate(CoorDinate_Stru stru_pre,CoorDinate_Stru stru,QPointF pointF) { double pre_x = stru_pre.x; double pre_y = stru_pre.y; double pre_angle = stru_pre.angle; double x = stru.x; double y = stru.y; double angle = stru.angle; //平移 先计算出点在新的坐标系中的坐标。pointF是之前坐标系(stru_pre)中的点,需要转换为新的坐标系(stru)中的点 pointF = QPointF(pointF.x()+(x - pre_x),pointF.y+(y-pre_y)); //此时坐标为转换后的新坐标的点 在 原始坐标系中的位置---未旋转的情况下 //此处偷个懒,采用了Qt的源码的部分代码 /* //Qt的源码计算 , 求一个角度的sin值和cos值qmatrix.cpp中的rotate()函数 qreal sina = 0; qreal cosa = 0; if (a == 90. || a == -270.) sina = 1.; else if (a == 270. || a == -90.) sina = -1.; else if (a == 180.) cosa = -1.; else{ qreal b = deg2rad*a; // convert to radians sina = qSin(b); // fast and convenient cosa = qCos(b); } */ double a = angle - pre_angle; //获取此坐标系相对原始坐标系的角度 double len = hypot(pointF.x()-x,pointF.y()-y); if(len == 0) return pointF; double b = acos((double)(pointF.x())-x)/len); if(pointF.y()-y < 0) b = 2*Pi - b; b = b / deg2rad; a = a + b; qreal sina = 0; qreal cosa = 0; if (a == 90. || a == -270.) sina = 1.; else if (a == 270. || a == -90.) sina = -1.; else if (a == 180.) cosa = -1.; else{ qreal c = deg2rad*a; // convert to radians sina = qSin(c); // fast and convenient cosa = qCos(c); } qreal dx = len * cosa; qreal dy = len * sina; QPointF p = QPointF(dx + x; dy + y); return p; }

    推荐阅读