Skip to main content
标签ad报错:该广告ID(9)不存在。
  主页 > Qt入门

一个qt/c++ demo,用于显示 Sierpinski Tetrahedron(谢尔宾斯基四面体) 分形图

2023-04-24 浏览:
标签ad报错:该广告ID(7)不存在。

#include <QtGui>
#include <QApplication>
#include <vector>

class Point3D {
public:
    Point3D(float x, float y, float z)
        : x_(x), y_(y), z_(z) {}

    float x() const { return x_; }
    float y() const { return y_; }
    float z() const { return z_; }

private:
    float x_, y_, z_;
};

class SierpinskiTetrahedron : public QWidget {
public:
    SierpinskiTetrahedron(QWidget *parent = 0)
        : QWidget(parent), depth_(0), color_(Qt::white) {
        setWindowTitle("Sierpinski Tetrahedron");
        resize(800, 600);
        setAutoFillBackground(false);

        tetrahedron_.push_back(Point3D(-1.0f, 0.0f, 0.0f));
        tetrahedron_.push_back(Point3D(0.0f, -1.0f, 0.0f));
        tetrahedron_.push_back(Point3D(0.0f, 0.0f, -1.0f));
        tetrahedron_.push_back(Point3D(1.0f, 1.0f, 1.0f));
    }

protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);

        std::vector<Point3D> points;
        createSierpinskiTetrahedron(&points);

        QMatrix4x4 matrix;
        matrix.rotate(30.0f, QVector3D(1.0f, 1.0f, 1.0f));
        matrix.rotate(30.0f, QVector3D(0.0f, 0.0f, 1.0f));

        for (const Point3D &point : points) {
            QVector3D transformedPoint =
                matrix.map(QVector3D(point.x(), point.y(), point.z()));
            QPoint screenPoint(transformedPoint.x() * 200 + width() / 2,
                               transformedPoint.y() * 200 + height() / 2);
            painter.drawPoint(screenPoint);
        }
    }

private:
    void createSierpinskiTetrahedron(std::vector<Point3D> *points) {
        points->clear();
        points->reserve(4 * std::pow(3, depth_));

        std::vector<Point3D> tempTetrahedron = tetrahedron_;
        for (int i = 0; i < depth_; ++i) {
            std::vector<Point3D> newTempTetrahedron;
            newTempTetrahedron.reserve(4 * tempTetrahedron.size());

            for (const Point3D &p : tempTetrahedron) {
                newTempTetrahedron.push_back(p);
            }

            for (size_t j = 0; j < tempTetrahedron.size(); ++j) {
                Point3D a = tempTetrahedron[j];
                for (size_t k = j + 1; k < tempTetrahedron.size(); ++k) {
                    Point3D b = tempTetrahedron[k];
                    Point3D c((a.x() + b.x()) / 2,
                              (a.y() + b.y()) / 2,
                              (a.z() + b.z()) / 2);
                    newTempTetrahedron.push_back(c);
                }
            }

            tempTetrahedron = newTempTetrahedron;
        }

        for (const Point3D &p : tempTetrahedron) {
            points->push_back(p);
        }
    }

private:
    std::vector<Point3D> tetrahedron_;
    int depth_;
    QColor color_;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    SierpinskiTetrahedron fractal;
    fractal.show();

    return app.exec();
}