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

11 篇文章 1 订阅

需求:
不采用QGraphicsView本身的平移和旋转是因为所有的item是自定义封装的,存在交互上的数据变化,如果采用Qt自带的转换会导致交互数据出现错乱
实现思想:
放弃了坐标系的概念,采用虚拟坐标系代替–坐标系不存在,但是体现在所有item的数据上;
所有的数据都是原始坐标系,只是记录相对坐标系的值。
实现步骤:
当前坐标系的点----》需要被转换的坐标系的点----》原始坐标系的点

简单点就是:在相对坐标系(100,100)中,点(10,10)(注:该点是实际相对坐标系的点的位置) ---->在原始坐标系中的点的坐标为(110,110)---->相对坐标系(200,200)中的点(210,210)。最后的结果是原始坐标值的数值,但是我记录了相对坐标系的值。如果想知道该点在原始坐标系中的值,可以通过记录的相对坐标值进行转换

代码注释不多。主要是实现该功能的思想。

#define Pi 3.1415926
const qreal deg2rad = qreal(0.0174532925199)   //  pi/180

struct 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;
}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庐州李大爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值