- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的示例中,我按以下方式转换了 qt painter 的坐标系:
QTransform xform;
xform.rotate(90);
xform.scale(1, 1000000000000000);
xform.translate(0, -std::abs(max));
if (limit != 0)
xform.scale(1, std::abs(max)/std::abs(limit));
painter->setTransform(xform)
之所以有这么大的规模,是因为我的例子中的数据非常少。然后我为我的数据画图 - 它的值大约是 1e-14 并且一切都正确绘制。然后,除了由两点指定的图之外,我还想画几条线。
我应用 drawPolyLine 函数:
QPointF* line = new QPointF[2];
line[0].setX(0);
line[0].setY(0);
line[1].setX(0);
line[1].setY(std::abs(seismMax));
painter.drawPolyline(line, 2);
其中 seismMax 的数量级为 1e-14(作为我在图中的所有点)。然后画线。然后我应用 drawLine(因为我只有两点):
painter.drawLine(QPointF(0, 0), QPointF(0, std::abs(seismMax)));
并且在这种情况下没有画线。我怀疑这两个函数处理坐标的方式可能不同。当我用 drawLine 以原始比例绘制线时(例如像这样):
painter.drawLine(QPointF(0, 0), QPointF(0, 1000));
线条绘制正确。
最佳答案
我做了一个 MCVE接触问题。
因此,我使用了更小的缩放比例,无法重现该问题。然后,我使用了 OP 所述的缩放比例 1.0E14。突然,线条画消失了。降低缩放比例,我弄清楚了(在我的例子中)直到 1E12
它工作得很好但是随着更高的缩放比例线开始消失。在玩弄这个时,一位同事离开并暗示这可能只是 float 问题。我们很快讨论了这个并得出结论:
因此,后者可能会发生,将非 0 值删除为 0。
1014 是二进制的 47 位数字。这接近具有 53 位尾数的 double
的精度。 但是:QPainter
使用的渲染引擎可能是基于 OpenGL 的,其中 float
是很多东西的默认值。 float
只提供 23 位的尾数!
因此,在稍微考虑一下之后,我找到了不使用 1014 比例因子绘画的充分理由。
为了演示这一点,我制作了一个小示例 testQPainterDrawLine.cc
:
#include <QtWidgets>
class Widget: public QWidget {
public:
const double scale;
public:
Widget(double scale, QWidget *pQParent = nullptr):
QWidget(pQParent),
scale(scale)
{ }
virtual ~Widget() = default;
Widget(const Widget&) = delete;
Widget& operator=(const Widget&) = delete;
protected:
virtual void paintEvent(QPaintEvent *pQEvent) override;
};
void Widget::paintEvent(QPaintEvent*)
{
const double value = height() / scale;
QPainter qPainter(this);
qPainter.fillRect(0, 0, width(), height(), QColor(Qt::white));
qPainter.drawRect(0, 0, width() - 1, height() - 1);
QTransform xform;
xform.scale(1, scale);
qPainter.setTransform(xform);
qPainter.setPen(QPen(QColor(Qt::red), 3.0));
const double xL = 0.333 * width();
qPainter.drawLine(QPointF(xL, 0.0), QPointF(xL, value));
qPainter.setPen(QPen(QColor(Qt::blue), 3.0));
const double xPL = 0.667 * width();
QPointF qPts[] = { QPointF(xPL, 0.0), QPointF(xPL, value) };
const int nPts = sizeof qPts / sizeof *qPts;
qPainter.drawPolyline(qPts, nPts);
}
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
QWidget qWin;
QGridLayout qGrid;
qGrid.setRowStretch(0, 0); qGrid.setRowStretch(1, 1);
double scale = 1.0E11;
for (int i = 0; i < 4; ++i, scale *= 10.0) {
qGrid.addWidget(
new QLabel(QString("Scale: %1").arg(scale)),
0, i);
qGrid.addWidget(new Widget(scale), 1, i);
}
qWin.setLayout(&qGrid);
qWin.resize(1024, 256);
qWin.show();
return app.exec();
}
testQPainterDrawLine.pro
:
SOURCES = testQPainterDrawLine.cc
QT = widgets
在 cygwin64 中编译和测试:
$ qmake-qt5 testQPainterDrawLine.pro
$ make
$ ./testQPainterDrawLine
Qt Version: 5.9.4
所以,最后,我相信,它与 QPainter::drawLine()
和 QPainter::drawPolyline()
没有任何关系。这只是缩放太高并导致浮点问题。这就是线条可能会意外(消失)的原因。
解决方案很简单:在使用 QPainter
绘制值之前必须对其进行缩放,以便 QPainter
中的内部转换发生在更接近 0 和 1 的幅度上。
关于c++ - Qt - drawPolyline 和 drawLine 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52512387/
我实现了一个使用鼠标单击动态创建折线的程序。每次鼠标单击都会在 ArrayList 中添加新的 Point 并将其全部绘制出来。如果我单击相同的点,它会返回相同的值并将其添加到列表中,但它会绘制新线到
在我的示例中,我按以下方式转换了 qt painter 的坐标系: QTransform xform; xform.rotate(90); xform.scale(1, 100000000000
调用 drawPolyline() 与遍历每一行并在 Graphics2D 类中调用 drawLine() 有什么好处吗? 例如: graphics2d.drawPolyline(xPoints, y
我正在尝试为多段线设置动画(它必须表现得像波浪)。我试过这种方式: from PySide.QtCore import * from PySide.QtGui import * import sys,
我是一名优秀的程序员,十分优秀!