#include <cmath>
#include <QWidget>
#include <QPainter>
class SierpinskiTriangle : public QWidget
{
public:
SierpinskiTriangle(QWidget *parent = nullptr) : QWidget(parent) {}
QSize minimumSizeHint() const override { return QSize(200, 200); }
QSize sizeHint() const override { return QSize(400, 400); }
protected:
void paintEvent(QPaintEvent *event) override
{
Q_UNUSED(event);
QPainter painter(this);
// 设置背景为白色
painter.fillRect(rect(), Qt::white);
// 定义三角形的三个顶点坐标
QPointF p1(width() / 2.0, 10.0);
QPointF p2(10.0, height() - 10.0);
QPointF p3(width() - 10.0, height() - 10.0);
// 递归绘制谢尔宾斯基三角形
drawSierpinskiTriangle(&painter, p1, p2, p3, 6);
}
private:
// 绘制谢尔宾斯基三角形
void drawSierpinskiTriangle(QPainter *painter, const QPointF &p1, const QPointF &p2, const QPointF &p3, int level)
{
if (level == 0) {
// 如果递归到最后一层,就绘制一个实心三角形
QPolygonF polygon;
polygon << p1 << p2 << p3;
painter->drawPolygon(polygon);
} else {
// 否则,将大三角形分成三个小三角形
QPointF p4 = midpoint(p1, p2);
QPointF p5 = midpoint(p2, p3);
QPointF p6 = midpoint(p1, p3);
// 递归绘制三个小三角形
drawSierpinskiTriangle(painter, p1, p4, p6, level - 1);
drawSierpinskiTriangle(painter, p4, p2, p5, level - 1);
drawSierpinskiTriangle(painter, p6, p5, p3, level - 1);
}
}
// 计算两点的中点
static QPointF midpoint(const QPointF &p1, const QPointF &p2)
{
return QPointF((p1.x() + p2.x()) / 2.0, (p1.y() + p2.y()) / 2.0);
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
SierpinskiTriangle triangle;
triangle.show();
return app.exec();
}
在这个示例中,我们使用了QPainter类来绘制谢尔宾斯基三角形。在界面绘制事件中,
我们首先将整个背景填充为白色,然后定义了三角形的三个顶点坐标。接着,我们递归地
调用drawSierpinskiTriangle方法来绘制谢尔宾斯基三角形。
在这个方法中,如果递归到最后一层,就绘制一个实心三角形;否则,我们将大三角形分成三个小三角形,
并递归绘制这三个小三角形。