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

一个qt/c++ demo,用于显示 Peano Curve(皮亚诺曲线) 分形图

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

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

class Point2D {
public:
    Point2D(float x, float y)
        : x_(x), y_(y) {}

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

private:
    float x_, y_;
};

class PeanoCurve : public QWidget {
public:
    PeanoCurve(QWidget *parent = nullptr)
        : QWidget(parent), depth_(0), color_(Qt::white) {
        setWindowTitle("Peano Curve");
        resize(800, 600);
        setAutoFillBackground(false);

        curve_.push_back(Point2D(0.0f, 0.0f));
        curve_.push_back(Point2D(1.0f, 0.0f));
        curve_.push_back(Point2D(2.0f, 0.0f));
        curve_.push_back(Point2D(2.0f, 1.0f));
        curve_.push_back(Point2D(1.0f, 1.0f));
        curve_.push_back(Point2D(1.0f, 2.0f));
        curve_.push_back(Point2D(2.0f, 2.0f));
        curve_.push_back(Point2D(2.0f, 3.0f));
        curve_.push_back(Point2D(1.0f, 3.0f));
        curve_.push_back(Point2D(0.0f, 3.0f));
        curve_.push_back(Point2D(0.0f, 2.0f));
        curve_.push_back(Point2D(1.0f, 2.0f));
        curve_.push_back(Point2D(1.0f, 1.0f));
        curve_.push_back(Point2D(0.0f, 1.0f));
    }

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

        std::vector<Point2D> points;
        createPeanoCurve(&points);

        float scaleX = width() / 3;
        float scaleY = height() / 3;

        painter.translate(width() / 2, height() / 2);
        painter.scale(scaleX, -scaleY);

        painter.setPen(QPen(color_, 0.005f));

        if (!points.empty()) {
            QPoint p1(points[0].x() * scaleX, points[0].y() * scaleY);
            for (size_t i = 1; i < points.size(); ++i) {
                QPoint p2(points[i].x() * scaleX, points[i].y() * scaleY);
                painter.drawLine(p1, p2);
                p1 = p2;
            }
        }
    }

private:
    void createPeanoCurve(std::vector<Point2D> *points) {
        points->clear();
        points->reserve(std::pow(3, depth_ + 1));

        if (depth_ >= 0) {
            std::vector<Point2D> tempCurve = curve_;
            for (int i = 0; i < depth_; ++i) {
                std::vector<Point2D> newTempCurve;
                newTempCurve.reserve(4 * tempCurve.size());

                for (const Point2D &p : tempCurve) {
                    newTempCurve.push_back(p);
                }

                for (size_t j = 0; j < tempCurve.size(); ++j) {
                    Point2D a = tempCurve[j];
                    for (size_t k = j + 1; k < tempCurve.size(); ++k) {
                        Point2D b = tempCurve[k];
                        Point2D c((a.x() + b.x()) / 2, (a.y() + b.y()) / 2);
                        newTempCurve.push_back(c);
                    }
                }

                tempCurve = newTempCurve;
            }

            for (const Point2D &p : tempCurve) {
                points->push_back(p);
            }
        }
    }

private:
    std::vector<Point2D> curve_;
    int depth_;
    QColor color_;
};

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

    PeanoCurve fractal;
    fractal.show();

    return app.exec();
}