成为Qt绘图高手,你需要掌握这些
今天小豆君带大家来看看Qt的绘图知识。
1 物理坐标和逻辑坐标
在绘图中,离不开两个概念,物理坐标和逻辑坐标。
我先举一个例子,比方我要在纸上绘画出我眼前的风景,我会选择一个标准点,再以此为基础确定其它物体的位置,最后将其按照肯定的比例缩放画到纸上。
计算机绘图也是这个原理,这里的纸变成了屏幕,每个点就是像素,所以物理坐标可以了解为实实在在的屏幕坐标。而逻辑坐标即可以了解为真实场景的坐标。
而作画的标准点,我们把它称之为坐标原点,计算机绘图中不论是物理还是逻辑坐标,都规定其左上角为坐标原点(0,0),水平方向向右增长,垂直方向向下增长,这与我们常见的直角坐标系稍有不同,需要大家适应过来。
2 窗口和视口
在绘图中有窗口和视口的概念,我们可以这样了解:
窗口是用逻辑坐标来表示的,即我们看到的真实场景,在Qt中可以通过QPainter::setWindow(const QRect &rectangle)来设置窗口的绘图区域。
视口是用物理坐标来表示的,即显示器的像素,在Qt中可以通过QPainter::setViewport(const QRect &rectangle)来设置视口的绘图区域。
3 坐标变换
3.1 平移
正常情况下,原点是在左上角的,但是有时候为了计算方便,需要将原点进行水平或者垂直平移,原点发生了改变,那么其它物体的位置也就相应改变。
现在我设以下几个变量:
平移前水平方向坐标:x0
平移前垂直方向坐标:y0
平移后水平方向坐标:x
平移后垂直方向坐标:y
现在我要在水平和垂直方向分别平移dx,dy则:
x = x0 + dx;
y = y0 + dy;
写成三阶矩阵为(矩阵的概念可以查阅线性代数,理工科的应该都学过):
image
3.2 旋转
绕原点逆时针旋转θ度角
image
根据三角公式:
image
写成三阶矩阵为:
image
3.3 缩放
有时我们需要在x和y轴上进行缩放控制,那么公式很简单:
设在水平方向缩放k1倍,垂直方向缩放k2倍,则
x = k1 * x0
y = k2 * y0
写成三阶矩阵为:
image
3.4 扭曲
x = x0 + k1*y0
y = y0 + k2*x0
所谓扭曲,比方生活中当某个物体受到强力挤压时,它的表面就会发生扭曲,上面的公式是一个简单的扭曲算法,复杂的比方火焰的,烟雾,炮弹轰击发生的物体变形,甚至空间扭曲,想要看到更逼真的图像就需要更复杂的算法支持,有兴趣的可以查阅相关资料。
上面的公式写成三阶矩阵为:
image
4 Qt中的变换矩阵
Qt中的变换矩阵类叫做QTransform,还有一个类是QMatrix, QTransform与QMatrix不同,由于它是一个真正的3×3矩阵,且允许透视转换,透视转换大家可以了解为投影,用矩阵的第三列进行控制。
QTransform的toAffine()方法可以将QTransform转换为QMatrix。这里推荐QTransform。
image
m11和m22xy代表缩放系数,m12和m21代表扭曲系数,m31和m32代表平移偏移量,m13和m23代表指定水平和垂直投影,m33被作为额外的投影因子。
关于绘图矩阵,你还可以使用它的方便方法如缩放scale() 旋转rotate() 平移translate() 扭曲shear()
5 使用变换矩阵编程
下面的代码是帮助文档中的一部分,是个很好的例子。
void TransformGraph::paintEvent(QPaintEvent *e){ //将角度转化为弧度,求出正余弦值 double a = qDegreesToRadians(45.0); double sina = sin(a); double cosa = cos(a); //平移 QTransform translationTransform(1, 0, 0, 1, 50.0, 50.0); //旋转 QTransform rotationTransform(cosa, sina, -sina, cosa, 0, 0); //缩放 QTransform scalingTransform(0.5, 0, 0, 1.0, 0, 0); //矩阵相乘,取得最终的变换矩阵。 //所有步骤也可以直接写成: //QTransform transform(0.5*cosa, 0.5*sina, -1*sina, 1*cosa, 50.0, 50.0); QTransform transform; transform = scalingTransform * rotationTransform * translationTransform; QPainter painter(this); painter.setPen(QPen(Qt::blue, 1, Qt::DashLine)); painter.drawRect(0, 0, 100, 100); painter.setTransform(transform); painter.setFont(QFont("Helvetica", 24)); painter.setPen(QPen(Qt::black, 1)); painter.drawText(20, 10, "QTransform");}欢迎关注微信公众号“小豆君Qt分享”,最新文章都会在公众号第一时间发布,或者者你有不懂的问题,关注公众号后,可加好友或者进Qt群取得答案。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 成为Qt绘图高手,你需要掌握这些