Qt 坐标系统与坐标变换
坐标变换函数
QPainter坐标变换相关函数
分组 | 函数原型 | 功能 |
---|---|---|
坐标变换 | void translate(qreal dx,qreal dy) | 坐标系统一定的偏移量,坐标原点平移到新的点 |
void rotate(qreal angle) | 坐标系统顺时针旋转-一个角度 | |
void scale(qreal sx,qreal sy) | 坐标系统缩放 | |
void shear(qrael sh,qreal sy) | 坐标系统做扭转变换 | |
状态保存与恢复 | void save() | 保存painter当前的状态,就是将当前状态压入栈 |
void restore() | 恢复上一次状态,就是从堆栈中弹出上次的状态 | |
void resetTransform() | 复位所有的坐标变换 |
1、坐标平移
坐标平移函数是translate(),其中一种参数形式的函数原型是:
void translate(qreal dx,qreal dy);
表示将坐标系统水平方向平移个单位,垂直方向平移个单位,在缺省的坐标系统中,单位就是像素。如果是从原始状态平移(dx,dy),那么平移后的坐标原点就移到了(dx,dy)。
假设一个绘图窗口宽度为300像素,高度为200像素,则其原始坐标系统如图8-10左所示; 若执行平移函数 translate(150,100),则坐标系统水平向右平移150像素,向下平移100像素,平 移后的坐标系统如图8-10右所示,坐标原点在窗口的中心,而左上角的坐标变为(-150,-100), 右下角的坐标变为(150,100)。如此将坐标原点变换到窗口中心在绘制某些图形时是非常方便的。
2、坐标旋转
坐标旋转的函数是rotate(),其函数原型为:
void rotate(qreal angle);
它是将坐标系统绕坐标原点顺时针旋转angle角度,单位是度。当angle为正数时是顺时针旋 转,为负数时是逆时针旋转。在图8-10右的基础上,若执行rotate(90),则得到图8-11所示的坐标系统。
注意:旋转之后并不改变窗口矩形的实际大小,只是改变了坐标轴的方向。
在图8-11的新坐标系下,窗口左上角的坐标变成了(-100,150),而右下角的坐标变成了(100,-150)。
3、缩放
缩放函数是scale(),其函数原型为:
void scale(qreal sx,qreal sy);
其中,sx,sy分别为横向和纵向缩放比例,比例大于1是放大,小于1是缩小。
4、状态保存与恢复
进行坐标变换时,QPainter内部实际上有一个坐标变换矩阵,用save()保存当前坐标状态,用 restore()恢复上次保存的坐标状态,这两个函数 必须配对使用 , 操作的是一个堆栈对象 。
resetTransform()函数则是复位所有坐标变换操作,恢复原始的坐标系统。
坐标变换绘图实例
(1)绘制3个五角星的程序
创建一个基于QWidget的窗口的应用程序samp8_123,窗体上不放置任何组件。在Widget类的 构造函数和paintEvent()事件中调用MyPaintFiveStar()函数,MyPaintFiveStar()的代码内容如下:
//画五角星
void sample8_123QPainter::MyPaintFiveStar()
{
QPainter painter(this);//创建QPainter对象
painter.setRenderHint(QPainter::Antialiasing);//
painter.setRenderHint(QPainter::TextAntialiasing);//
//生成五角星的5个顶点的,假设原点在五角星中心
qreal R = 100;//半径
const qreal Pi = 3.14159;
qreal deg = Pi * 72 / 180;//
//QPoint points[5] = {//针对Qt 5.12.1 编译错误修改,使用<Qtmath>中的函数 qSin(), qCos()
// QPoint(R, 0),
// QPoint(R*qCos(deg), -R*qSin(deg)),
// QPoint(R*qCos(2 * deg), -R*qSin(2 * deg)),
// QPoint(R*qCos(3 * deg), -R*qSin(3 * deg)),
// QPoint(R*qCos(4 * deg), -R*qSin(4 * deg))
//};
QPoint points[5]={ //这些代码在Qt 5.12.1中编译有问题,没有函数std::cos(),std::sin()
QPoint(R,0),
QPoint(R*std::cos(deg),-R*std::sin(deg)),
QPoint(R*std::cos(2*deg),-R*std::sin(2*deg)),
QPoint(R*std::cos(3*deg),-R*std::sin(3*deg)),
QPoint(R*std::cos(4*deg),-R*std::sin(4*deg))
};
//设置字体
QFont font;
font.setPointSize(12);
font.setBold(true);
painter.setFont(font);
//设置画笔
QPen penLine;
penLine.setWidth(2);//线宽
penLine.setColor(Qt::blue);//划线颜色
//Qt::NoPen,Qt::SolidLine, Qt::DashLine, Qt::DotLine,Qt::DashDotLine,Qt::DashDotDotLine,Qt::CustomDashLine
penLine.setStyle(Qt::SolidLine);//线的类型,实线、虚线等
//Qt::FlatCap, Qt::SquareCap,Qt::RoundCap
penLine.setCapStyle(Qt::FlatCap);//线端点样式
//Qt::MiterJoin,Qt::BevelJoin,Qt::RoundJoin,Qt::SvgMiterJoin
penLine.setJoinStyle(Qt::BevelJoin);//线的连接点样式
painter.setPen(penLine);
//设置画刷
QBrush brush;
brush.setColor(Qt::yellow);//画刷颜色
brush.setStyle(Qt::SolidPattern);//画刷填充样式
painter.setBrush(brush);
// QPen penText;
// penText.setWidth(2); //线宽
// penText.setColor(Qt::blue); //划线颜色
//设计绘制五角星的PainterPath,以便重复使用
QPainterPath starPath;
starPath.moveTo(points[0]);
starPath.lineTo(points[2]);
starPath.lineTo(points[4]);
starPath.lineTo(points[1]);
starPath.lineTo(points[3]);
starPath.closeSubpath();//闭合路径,最后一个点与第一个点相连
starPath.addText(points[0], font, "0"); //显示端点编号
starPath.addText(points[1], font, "1");
starPath.addText(points[2], font, "2");
starPath.addText(points[3], font, "3");
starPath.addText(points[4], font, "4");
//绘图
painter.save(); //保存坐标状态
painter.translate(100, 120);
painter.drawPath(starPath); //画星星
painter.drawText(0, 0, "S1");
painter.restore(); //恢复坐标状态
painter.translate(300, 120); //平移
painter.scale(0.8, 0.8); //缩放
painter.rotate(90); //顺时针旋转
painter.drawPath(starPath);//画星星
painter.drawText(0, 0, "S2");
painter.resetTransform(); //复位所有坐标变换
painter.translate(500, 120); //平移
painter.rotate(-145); //逆时针旋转
painter.drawPath(starPath);//画星星
painter.drawText(0, 0, "S3");
}