It's an app that I made through an online course in which I learned the basics of the Qt framework and GUI building.
https://git.thepra.dev/thepra/QtCurvesCpp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
4.3 KiB
246 lines
4.3 KiB
#include "renderarea.h" |
|
#include <QPainter> |
|
|
|
QSize RenderArea::minimumSizeHint() const |
|
{ |
|
return QSize{491,481}; |
|
} |
|
|
|
QSize RenderArea::sizeHint() const |
|
{ |
|
return QSize{491,481}; |
|
} |
|
|
|
void RenderArea::paintEvent(QPaintEvent* event) |
|
{ |
|
Q_UNUSED(event); |
|
QPainter painter{this}; |
|
painter.setRenderHint(QPainter::Antialiasing,true); |
|
|
|
painter.setBrush(mBackgroundColour); |
|
painter.setPen(mPen); |
|
|
|
painter.drawRect(this->rect()); |
|
|
|
QPointF prevPoint{Compute(0)}; |
|
QPoint center{this->rect().center()},prevPixel; |
|
prevPixel.setX(prevPoint.x() * mScale + center.x()); |
|
prevPixel.setY(prevPoint.y() * mScale + center.y()); |
|
|
|
double step{ mIntervalLenght / mStepCount }; |
|
|
|
for(double t{0}; t < mIntervalLenght; t += step){ |
|
QPointF point = Compute(t); |
|
|
|
QPoint pixel{}; |
|
pixel.setX(point.x() * mScale + center.x()); |
|
pixel.setY(point.y() * mScale + center.y()); |
|
|
|
painter.drawLine(pixel, prevPixel); |
|
|
|
prevPixel=pixel; |
|
} |
|
QPointF point = Compute(mIntervalLenght); |
|
QPoint pixel{}; |
|
pixel.setX(point.x() * mScale + center.x()); |
|
pixel.setY(point.y() * mScale + center.y()); |
|
painter.drawLine(pixel, prevPixel); |
|
} |
|
|
|
RenderArea::RenderArea(QWidget *parent) : |
|
QWidget{parent}, |
|
mBackgroundColour{36,35,35}, |
|
mPen{QColor{251,250,250}}, |
|
mShape{Astroid} |
|
{ |
|
mPen.setWidth(2); |
|
OnShapeChanged(); |
|
} |
|
|
|
QPointF RenderArea::ComputeAstroid(double t){ |
|
return QPointF{ |
|
2*pow(cos(t),3), |
|
2*pow(sin(t),3) |
|
}; |
|
} |
|
|
|
QPointF RenderArea::ComputeCycloid(double t) |
|
{ |
|
return QPointF{ |
|
1.5 * (1 - cos(t)), |
|
1.5 * (t - sin(t)) |
|
}; |
|
} |
|
|
|
QPointF RenderArea::ComputeHuygens(double t) |
|
{ |
|
return QPointF{ |
|
4 * (3 * cos(t) - cos(3 * t)), |
|
4 * (3 * sin(t) - sin(3 * t)) |
|
}; |
|
} |
|
|
|
QPointF RenderArea::ComputeHypo(double t) |
|
{ |
|
return QPointF{ |
|
1.5 * (2 * cos(t) + cos(2 * t)), |
|
1.5 * (2 * sin(t) - sin(2 * t)) |
|
}; |
|
} |
|
|
|
QPointF RenderArea::ComputeLine(double t) |
|
{ |
|
return QPointF{1-t,1-t}; |
|
} |
|
|
|
QPointF RenderArea::ComputeCircle(double t) |
|
{ |
|
return QPointF{cos(t),sin(t)}; |
|
} |
|
|
|
QPointF RenderArea::ComputeEllipse(double t) |
|
{ |
|
double a{2},b{1.1}; |
|
return QPointF{a*cos(t),b*sin(t)}; |
|
} |
|
|
|
QPointF RenderArea::ComputeFancy(double t) |
|
{ |
|
return QPointF{ |
|
11*cos(t) - 6*cos((11.0/6)*t), |
|
11*sin(t) - 6*sin((11.0/6)*t) |
|
}; |
|
} |
|
|
|
QPointF RenderArea::ComputeStarfish(double t) |
|
{ |
|
double R{5},r{3},d{5}; |
|
return QPointF{ |
|
(R-r)*cos(t) + d*cos(t*((R-r)/r)), |
|
(R-r)*sin(t) - d*sin(t*((R-r)/r)) |
|
}; |
|
} |
|
|
|
QPointF RenderArea::ComputeCloud2(double t) |
|
{ |
|
return ComputeCloudWithSign(t,1.); |
|
} |
|
|
|
QPointF RenderArea::ComputeCloud1(double t) |
|
{ |
|
return ComputeCloudWithSign(t,-1.); |
|
} |
|
|
|
QPointF RenderArea::ComputeCloudWithSign(double t,double sign) |
|
{ |
|
double a{14},b{1}; |
|
return QPointF{ |
|
(a+b)*cos(t*(b/a)) + sign*b*cos(t*((a+b)/a)), |
|
(a+b)*sin(t*(b/a)) - b*sin(t*((a+b)/a)) |
|
}; |
|
} |
|
|
|
void RenderArea::OnShapeChanged() |
|
{ |
|
switch (mShape) { |
|
case Astroid: |
|
mScale=90; |
|
mIntervalLenght=2*M_PI; |
|
mStepCount=512; |
|
break; |
|
case Cycloid: |
|
mScale=10; |
|
mIntervalLenght=4*M_PI; |
|
mStepCount=128; |
|
break; |
|
case HuygensCycloid: |
|
mScale=10; |
|
mIntervalLenght=4*M_PI; |
|
mStepCount=512; |
|
break; |
|
case HypoCycloid: |
|
mScale=40; |
|
mIntervalLenght=2*M_PI; |
|
mStepCount=256; |
|
break; |
|
case Line: |
|
mScale=100; |
|
mIntervalLenght=2; |
|
mStepCount=128; |
|
break; |
|
case Circle: |
|
mScale=100; |
|
mIntervalLenght=2*M_PI; |
|
mStepCount=128; |
|
break; |
|
case Ellipse: |
|
mScale=75; |
|
mIntervalLenght=2*M_PI; |
|
mStepCount=256; |
|
break; |
|
case Fancy: |
|
mScale=10; |
|
mIntervalLenght=12*M_PI; |
|
mStepCount=512; |
|
break; |
|
case Starfish: |
|
mScale=25; |
|
mIntervalLenght=6*M_PI; |
|
mStepCount=256; |
|
break; |
|
case Cloud1: |
|
mScale=10; |
|
mIntervalLenght=28*M_PI; |
|
mStepCount=128; |
|
break; |
|
case Cloud2: |
|
mScale=10; |
|
mIntervalLenght=28*M_PI; |
|
mStepCount=128; |
|
break; |
|
default: |
|
break; |
|
} |
|
} |
|
|
|
QPointF RenderArea::Compute(double t) |
|
{ |
|
switch (mShape) { |
|
case Astroid: |
|
return ComputeAstroid(t); |
|
break; |
|
case Cycloid: |
|
return ComputeCycloid(t); |
|
break; |
|
case HuygensCycloid: |
|
return ComputeHuygens(t); |
|
break; |
|
case HypoCycloid: |
|
return ComputeHypo(t); |
|
break; |
|
case Line: |
|
return ComputeLine(t); |
|
break; |
|
case Circle: |
|
return ComputeCircle(t); |
|
break; |
|
case Ellipse: |
|
return ComputeEllipse(t); |
|
break; |
|
case Fancy: |
|
return ComputeFancy(t); |
|
break; |
|
case Starfish: |
|
return ComputeStarfish(t); |
|
break; |
|
case Cloud1: |
|
return ComputeCloud1(t); |
|
break; |
|
case Cloud2: |
|
return ComputeCloud2(t); |
|
break; |
|
default: |
|
break; |
|
} |
|
return QPointF{0,0}; |
|
}
|
|
|