Last active
June 30, 2023 06:57
-
-
Save Przemekkkth/80b4e7dbb25e0ab9c6432fab1b713337 to your computer and use it in GitHub Desktop.
A Qt/C++ application that draws a cardioid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <QApplication> | |
#include <QWidget> | |
#include <QTimer> | |
#include <QElapsedTimer> | |
#include <QPoint> | |
#include <QPainter> | |
#include <QObject> | |
#include <algorithm> | |
#include <cmath> | |
class Window : public QWidget | |
{ | |
Q_OBJECT | |
public: | |
Window() | |
: m_radius(400), m_num_lines(150), m_counter(0.0f), m_inc(0.01f) | |
{ | |
setWindowTitle("Cardioid Qt C++"); | |
resize(1000, 600); | |
m_translate = QPoint(size().width()/2, size().height()/2); | |
QObject::connect(&m_timer, &QTimer::timeout, this, &Window::animationLoop); | |
m_timer.start(1000.f/60.f); //60 times per second | |
m_elapsedTimer.start(); | |
} | |
virtual ~Window(){} | |
QColor getColor(){ | |
m_counter += m_inc; | |
if (!(0.009 < m_counter && m_counter < 1)) { | |
m_counter = std::max(std::min(m_counter, 1.0f), 0.0f); | |
m_inc = -m_inc; | |
} | |
//interpolate | |
QColor c1 = Qt::red; | |
QColor c2 = Qt::green; | |
int r = (c2.red()-c1.red())*m_counter + c1.red(); | |
int g = (c2.green()-c1.green())*m_counter + c1.green(); | |
int b = (c2.blue()-c1.blue())*m_counter + c1.blue(); | |
return QColor(r,g,b); | |
} | |
void drawCardioid(QPainter& painter){ | |
painter.save(); | |
painter.setRenderHint(QPainter::Antialiasing); | |
painter.setPen(QColor(getColor())); | |
painter.setBrush(Qt::NoBrush); | |
qint64 time = m_elapsedTimer.elapsed(); | |
m_radius = 250 + 50 * std::abs(std::sin(time * 0.004) - 0.5); | |
float factor = 1 + 0.0001 * time; | |
for(int i = 0; i < m_num_lines; ++i) | |
{ | |
float theta = ( (2 * M_PI) / m_num_lines) * i; | |
int x1 = m_radius * std::cos(theta) + m_translate.x(); | |
int y1 = m_radius * std::sin(theta) + m_translate.y(); | |
int x2 = m_radius * std::cos(factor*theta) + m_translate.x(); | |
int y2 = m_radius * std::sin(factor*theta) + m_translate.y(); | |
painter.drawLine(QPoint(x1, y1), QPoint(x2, y2)); | |
} | |
painter.restore(); | |
} | |
private: | |
QTimer m_timer; | |
QElapsedTimer m_elapsedTimer; | |
int m_radius; | |
int m_num_lines; | |
QPoint m_translate; | |
float m_counter; | |
float m_inc; | |
private slots: | |
void animationLoop() | |
{ | |
update(); | |
} | |
private: | |
void paintEvent(QPaintEvent *event) | |
{ | |
Q_UNUSED(event); | |
QPainter qp(this); | |
qp.setBrush(QBrush(Qt::black)); | |
qp.drawRect(0,0,size().width(), size().height()); | |
drawCardioid(qp); | |
} | |
}; | |
#include "main.moc" | |
int main(int argc, char** argv) | |
{ | |
QApplication a(argc, argv); | |
Window *w = new Window(); | |
w->show(); | |
a.exec(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment