sid*_*guy 11 graphics qt qt4 coordinates qpainter
我正在使用Qt 4.7 QPainter将一些多边形等绘制到一个小部件中.我希望改变坐标系,使得(0,0)位于我的小部件的中心,并且x/y轴以标准的"笛卡尔"方式运行(即,y增加"向上"并且减少"下").换句话说,如果你知道我的意思,我希望坐标是"数学" - 而不是"计算机图形".:-)
我正在尝试使用setViewport()和setWindow()而不是自己做数学,因为能够直接用我的坐标调用draw方法会很好.
这是我到目前为止所得到的:
// Setup coordinates
double screenWidth = width();
double screenHeight = height();
double windowWidth = 100.0;
double windowHeight = (screenHeight / screenWidth) * windowWidth;
painter.setViewport(0, 0, screenWidth, screenHeight);
painter.setWindow(-(windowWidth / 2.0), -(windowHeight / 2.0), windowWidth, windowHeight);
// Draw stuff
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::blue);
painter.drawRect(-10, -10, 20, 20);
Run Code Online (Sandbox Code Playgroud)
现在这个工作得很好,因为它在屏幕中间绘制了一个漂亮的蓝色方块.问题是,我不得不说左上角是(-10,-10).我希望能够制作它(-10,10),因为它就像笛卡尔坐标一样.
我试着搞乱setWindow/setViewport以获得这个"y轴翻转",但无济于事.这似乎是一个非常容易/基本的事情,但在搜索Qt文档和网络后,我无法弄明白!
谢谢,
克里斯
Pie*_*esu 23
使用课程QMatrix.它指定了2D变换.QMatrix设置为QPainter.
但请记住,在您的情况下,如果您将小部件的坐标转换为笛卡尔坐标,则必须将第一个点放在(-10,-10) (不是在(-10,10),如您所提到的)绘制矩形,其具有在中心(0,0) ,因为Y轴现在生长向上和X轴现在生长右.
您所需要的只是通过这种方式转换您的坐标系:
将原点从(0,0)转换到小部件的中间:
缩放Y轴由-1因子:

这是代码,在paintEvent()小部件的功能中输入:
QPainter pn( this );
int w_2 = width() / 2;
int h_2 = height() / 2;
{ // X- and Y-Axis drawing
pn.setPen( Qt::blue );
pn.drawLine( 0, h_2, width(), h_2); // X-Axis
pn.drawLine( w_2, 0 , w_2, height() ); // Y-Axis
}
QMatrix m;
m.translate( w_2, h_2 );
m.scale( 1, -1 );
pn.setMatrix( m );
pn.setPen( Qt::NoPen );
pn.setBrush( QBrush( Qt::blue, Qt::Dense4Pattern ) );
pn.drawRect( -10, -10, 20, 20 );
Run Code Online (Sandbox Code Playgroud)
结果:

更新于2014年4月7日
很久以前就提出过这个问题,很多事情都发生了变化.对于那些今天(2014年初)问自己同样问题的人,我的个人答案是,从Qt 4.3开始,可以更轻松地解决文本翻转问题.
你是对的.文本也会被删除,因为它是使用相同的画家绘制的.如果可能的话,您可以在完成所有翻转的绘图时在最后绘制文本.由于文本位置的新计算,这种方法不方便.此外,您还需要删除画家的设置.现在我建议你使用QGraphicsView,因为2D绘画的巨大支持.此外,QGraphicsItem ItemIgnoresTransformations可以设置每个标志,这允许它忽略继承的变换(即,它的位置仍然锚定到其父级,但忽略父级或视图旋转,缩放或剪切变换).此标志对于使文本标签项保持水平和未缩放非常有用,因此如果转换图形视图,它们仍然可读
我需要翻转 y 轴,以便使用 Qt 从 Java 坐标中定义的点绘制线条和多边形。我想其他人在从 Java 坐标系统移植到 Qt 坐标系统时也需要这样做。上面的讨论很有帮助。我的解决方案是:
painter.translate(0,height());
painter.scale(1.0, -1.0);
Run Code Online (Sandbox Code Playgroud)
然后继续绘制直线和多边形。