使用窗口/视口翻转QPainter y轴

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可以设置每个标志,这允许它忽略继承的变换(即,它的位置仍然锚定到其父级,但忽略父级或视图旋转,缩放或剪切变换).此标志对于使文本标签项保持水平和未缩放非常有用,因此如果转换图形视图,它们仍然可读

  • 正确,但需要提及的是,文本也会被翻转。这大多是不希望的! (2认同)

Dav*_*per 5

我需要翻转 y 轴,以便使用 Qt 从 Java 坐标中定义的点绘制线条和多边形。我想其他人在从 Java 坐标系统移植到 Qt 坐标系统时也需要这样做。上面的讨论很有帮助。我的解决方案是:

painter.translate(0,height());
painter.scale(1.0, -1.0);
Run Code Online (Sandbox Code Playgroud)

然后继续绘制直线和多边形。