Qt 坐标系 转换矩阵

坐标系

先看官方解释的图
在这里插入图片描述

在Qt中,对于绘图而言,有三个坐标系

  • 世界坐标系(World Coordinates)
  • 窗口坐标系(“Window” Coordinates)
  • 设备坐标系(Device Coordinates)

世界坐标系:即逻辑坐标系,也就是笛卡尔坐标系。左下角为原点。此为Qt绘图的坐标系,左上角为原点。
窗口坐标系:这个坐标系是QPainter设置setWindow以后的一个坐标系。(注意,这个“窗口”不是平常的程序/控件窗口概念)
设备坐标系:即绘图设备的物理坐标系,默认的原点为应用程序的左上角。QPainter相关的draw函数是物理坐标系下的点。
这三个坐标系的映射(投射)关系,如下图所示。
在这里插入图片描述

平时我们的三个坐标系都是相同的,都是水平方向是X轴,垂直方向是Y轴,坐标原点是左上角(0, 0)。X轴从左到右增加,Y轴从上到下增加。

在这里插入图片描述

转换矩阵

2D绘图中,窗口坐标系和设备坐标系是一致的,仅通过对逻辑坐标系变换就可实现的平移、缩放、旋转效果。
在最开始那张图中,从世界坐标系变换到窗口坐标系,写着transformation matrix
没错,通过转换矩阵实现一系列变换!
该篇文章Direct2D教程VI——转换(Transform)详细讲解了转换的公式。可结合视频无所不能的矩阵 - 三维图形变换帮助理解。(注:需要懂矩阵相关知识)

代码实现
.h文件实现代码

#ifndef MATRIX_H
#define MATRIX_H

struct Point {
    double x;
    double y;
};

class Matrix {
public:
    Matrix();
    Matrix(double m11, double m12, double m13, double m21, double m22, double m23, double m31, double m32, double m33);
    ~Matrix();

    //水平平移dx个单位,垂直平移dy个单位
    void translate(double dx, double dy);
    //横向缩放sx比例,纵向缩放sy比例。大于1是放大,小于1是缩小。1,-1值可以改变坐标轴正方向。
    void scale(double sx, double sy);
    //顺时针旋转,单位度
    void rotate(double angle);
    //坐标变换
    Point map(Point before) const;

private:
    double m_11;
    double m_12;
    double m_13;

    double m_21;
    double m_22;
    double m_23;

    double m_31;
    double m_32;
    double m_33;
};
#endif // MATRIX_H

cpp文件实现代码

#include "matrix.h"
#include <QtMath>
Matrix::Matrix()
{
}

Matrix::Matrix(double m11, double m12, double m13, double m21, double m22, double m23, double m31, double m32, double m33)
    : m_11(m11)
    , m_12(m12)
    , m_13(m13)
    , m_21(m21)
    , m_22(m22)
    , m_23(m23)
    , m_31(m31)
    , m_32(m32)
    , m_33(m33)
{
}

Matrix::~Matrix()
{
}
//设置平移矩阵
void Matrix::translate(double dx, double dy)
{
    m_11 = 1;
    m_12 = 0;
    m_13 = 0;
    m_21 = 0;
    m_22 = 1;
    m_23 = 0;
    m_31 = dx;
    m_32 = dy;
    m_33 = 1;
}

//设置缩放矩阵
void Matrix::scale(double sx, double sy)
{
    m_11 = sx;
    m_12 = 0;
    m_13 = 0;
    m_21 = 0;
    m_22 = sy;
    m_23 = 0;
    m_31 = 0;
    m_32 = 0;
    m_33 = 1;
}

//设置旋转矩阵
void Matrix::rotate(double angle)
{
    m_11 = cos(angle);
    m_12 = sin(angle);
    m_13 = 0;
    m_21 = -sin(angle);
    m_22 = cos(angle);
    m_23 = 0;
    m_31 = 0;
    m_32 = 0;
    m_33 = 1;
}

//坐标变换
Point Matrix::map(Point before) const
{
    Point after;
    after.x = before.x * m_11 + before.y * m_21 + m_31;
    after.y = before.x * m_12 + before.y * m_22 + m_32;
    return after;
}

Qt中的实现函数
QPainter绘图之坐标转换函数

函数原型作用
void translate(qreal dx,qreal dy)平移
void rotate(qreal angle)旋转
void scale(qreal sx,qreal sy)缩放
void shear(qreal sh,qreal sv)扭转

坐标系统的2D变换由QTransform类实现,QPainter也可以实现,而QTransform可以存储多个变换操作,对数据量大且复合变换有优势。

窗口—视口转换

视口一般设定与屏幕的DPI一致,通常不用变

更多的坐标系概念
窗口,视口,场景坐标系,对象坐标系,世界坐标系,逻辑坐标,物理坐标。
Graphics View Framework图形视图框架,相关的概念。

绘制坐标系

可平移缩放刻度自适应的坐标系
(放图)

我学习过程的疑惑

1.为什么有这么多不同的坐标系
三维降二维,世界不同,视角不同。
2.我以为逻辑坐标转成物理坐标,只是一个公式变换
原一开始,我以为,设定原点,对直接输入的逻辑坐标,经过公式转换,转成物理坐标,然后画在设备窗口上就行。没想到,大有学问啊。
3.如何画上去
变换坐标系,通过translate偏移,scale翻转轴方向。然后draw(x1,y1,x2,y2)
变点,通过公式或通过矩阵变换,计算逻辑坐标点落在物理坐标的点。然后draw(map(x1,y1),map(x2,y2))

参考

  1. 小谈Qt的坐标系系统 - 3个坐标系,2个变换
  2. Direct2D教程VI——转换(Transform)
  3. 无所不能的矩阵 - 三维图形变换
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值