| @@ -25,6 +25,7 @@ START_NAMESPACE_DGL | |||||
| // Forward class names | // Forward class names | ||||
| template<typename> class Line; | template<typename> class Line; | ||||
| template<typename> class Circle; | |||||
| template<typename> class Triangle; | template<typename> class Triangle; | ||||
| template<typename> class Rectangle; | template<typename> class Rectangle; | ||||
| @@ -99,6 +100,7 @@ public: | |||||
| private: | private: | ||||
| T fX, fY; | T fX, fY; | ||||
| template<typename> friend class Line; | template<typename> friend class Line; | ||||
| template<typename> friend class Circle; | |||||
| template<typename> friend class Triangle; | template<typename> friend class Triangle; | ||||
| template<typename> friend class Rectangle; | template<typename> friend class Rectangle; | ||||
| }; | }; | ||||
| @@ -186,7 +188,7 @@ class Line | |||||
| { | { | ||||
| public: | public: | ||||
| /** | /** | ||||
| Constructor for null line ([0, 0] to [0, 0]). | |||||
| Constructor for a null line ([0, 0] to [0, 0]). | |||||
| */ | */ | ||||
| Line() noexcept; | Line() noexcept; | ||||
| @@ -308,6 +310,115 @@ private: | |||||
| Point<T> fPosStart, fPosEnd; | Point<T> fPosStart, fPosEnd; | ||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | |||||
| // Circle | |||||
| template<typename T> | |||||
| class Circle | |||||
| { | |||||
| public: | |||||
| /** | |||||
| Constructor for a null circle. | |||||
| */ | |||||
| Circle() noexcept; | |||||
| /** | |||||
| Constructor using custom X, Y and size values. | |||||
| */ | |||||
| Circle(const T& x, const T& y, float size, int numSegments = 300); | |||||
| /** | |||||
| Constructor using custom position and size values. | |||||
| */ | |||||
| Circle(const Point<T>& pos, float size, int numSegments = 300); | |||||
| /** | |||||
| Constructor using another Circle class values. | |||||
| */ | |||||
| Circle(const Circle<T>& cir) noexcept; | |||||
| /** | |||||
| Get X value. | |||||
| */ | |||||
| const T& getX() const noexcept; | |||||
| /** | |||||
| Get Y value. | |||||
| */ | |||||
| const T& getY() const noexcept; | |||||
| /** | |||||
| Get position. | |||||
| */ | |||||
| const Point<T>& getPos() const noexcept; | |||||
| /** | |||||
| Set X value as @a x. | |||||
| */ | |||||
| void setX(const T& x) noexcept; | |||||
| /** | |||||
| Set Y value as @a y. | |||||
| */ | |||||
| void setY(const T& y) noexcept; | |||||
| /** | |||||
| Set X and Y values as @a x and @a y respectively. | |||||
| */ | |||||
| void setPos(const T& x, const T& y) noexcept; | |||||
| /** | |||||
| Set X and Y values according to @a pos. | |||||
| */ | |||||
| void setPos(const Point<T>& pos) noexcept; | |||||
| /** | |||||
| Get size. | |||||
| */ | |||||
| float getSize() const noexcept; | |||||
| /** | |||||
| Set size. | |||||
| @note Must always be > 0.0f | |||||
| */ | |||||
| void setSize(float size) noexcept; | |||||
| /** | |||||
| Get the current number of line segments that make this circle. | |||||
| */ | |||||
| int getNumSegments() const noexcept; | |||||
| /** | |||||
| Set the number of line segments that will make this circle. | |||||
| @note Must always be >= 3 | |||||
| */ | |||||
| void setNumSegments(int num); | |||||
| /** | |||||
| Draw this circle using the current OpenGL state. | |||||
| */ | |||||
| void draw(); | |||||
| /** | |||||
| Draw lines (outline of this circle) using the current OpenGL state. | |||||
| */ | |||||
| void drawOutline(); | |||||
| Circle<T>& operator=(const Circle<T>& cir) noexcept; | |||||
| bool operator==(const Circle<T>& cir) const noexcept; | |||||
| bool operator!=(const Circle<T>& cir) const noexcept; | |||||
| private: | |||||
| Point<T> fPos; | |||||
| float fSize; | |||||
| int fNumSegments; | |||||
| // cached values | |||||
| float fTheta, fCos, fSin; | |||||
| void _draw(const bool isOutline); | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Triangle | // Triangle | ||||
| @@ -316,7 +427,7 @@ class Triangle | |||||
| { | { | ||||
| public: | public: | ||||
| /** | /** | ||||
| Constructor for null triangle. | |||||
| Constructor for a null triangle. | |||||
| */ | */ | ||||
| Triangle() noexcept; | Triangle() noexcept; | ||||
| @@ -363,7 +474,7 @@ class Rectangle | |||||
| { | { | ||||
| public: | public: | ||||
| /** | /** | ||||
| Constructor for null rectangle. | |||||
| Constructor for a null rectangle. | |||||
| */ | */ | ||||
| Rectangle() noexcept; | Rectangle() noexcept; | ||||
| @@ -412,6 +412,188 @@ bool Line<T>::operator!=(const Line<T>& line) const noexcept | |||||
| return !operator==(line); | return !operator==(line); | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| // Circle | |||||
| template<typename T> | |||||
| Circle<T>::Circle() noexcept | |||||
| : fPos(0, 0), | |||||
| fSize(0.0f), | |||||
| fNumSegments(0), | |||||
| fTheta(0.0f), | |||||
| fCos(0.0f), | |||||
| fSin(0.0f) | |||||
| { | |||||
| } | |||||
| template<typename T> | |||||
| Circle<T>::Circle(const T& x, const T& y, float size, int numSegments) | |||||
| : fPos(x, y), | |||||
| fSize(size), | |||||
| fNumSegments(numSegments >= 3 ? numSegments : 3), | |||||
| fTheta(2.0f * M_PI / float(fNumSegments)), | |||||
| fCos(std::cos(fTheta)), | |||||
| fSin(std::sin(fTheta)) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT(fSize > 0.0f); | |||||
| } | |||||
| template<typename T> | |||||
| Circle<T>::Circle(const Point<T>& pos, float size, int numSegments) | |||||
| : fPos(pos), | |||||
| fSize(size), | |||||
| fNumSegments(numSegments >= 3 ? numSegments : 3), | |||||
| fTheta(2.0f * M_PI / float(fNumSegments)), | |||||
| fCos(std::cos(fTheta)), | |||||
| fSin(std::sin(fTheta)) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT(fSize > 0.0f); | |||||
| } | |||||
| template<typename T> | |||||
| Circle<T>::Circle(const Circle<T>& cir) noexcept | |||||
| : fPos(cir.fPos), | |||||
| fSize(cir.fSize), | |||||
| fNumSegments(cir.fNumSegments), | |||||
| fTheta(cir.fTheta), | |||||
| fCos(cir.fCos), | |||||
| fSin(cir.fSin) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT(fSize > 0.0f); | |||||
| } | |||||
| template<typename T> | |||||
| const T& Circle<T>::getX() const noexcept | |||||
| { | |||||
| return fPos.fX; | |||||
| } | |||||
| template<typename T> | |||||
| const T& Circle<T>::getY() const noexcept | |||||
| { | |||||
| return fPos.fX; | |||||
| } | |||||
| template<typename T> | |||||
| const Point<T>& Circle<T>::getPos() const noexcept | |||||
| { | |||||
| return fPos; | |||||
| } | |||||
| template<typename T> | |||||
| void Circle<T>::setX(const T& x) noexcept | |||||
| { | |||||
| fPos.fX = x; | |||||
| } | |||||
| template<typename T> | |||||
| void Circle<T>::setY(const T& y) noexcept | |||||
| { | |||||
| fPos.fY = y; | |||||
| } | |||||
| template<typename T> | |||||
| void Circle<T>::setPos(const T& x, const T& y) noexcept | |||||
| { | |||||
| fPos.fX = x; | |||||
| fPos.fY = y; | |||||
| } | |||||
| template<typename T> | |||||
| void Circle<T>::setPos(const Point<T>& pos) noexcept | |||||
| { | |||||
| fPos = pos; | |||||
| } | |||||
| template<typename T> | |||||
| float Circle<T>::getSize() const noexcept | |||||
| { | |||||
| return fSize; | |||||
| } | |||||
| template<typename T> | |||||
| void Circle<T>::setSize(float size) noexcept | |||||
| { | |||||
| fSize = size; | |||||
| } | |||||
| template<typename T> | |||||
| int Circle<T>::getNumSegments() const noexcept | |||||
| { | |||||
| return fNumSegments; | |||||
| } | |||||
| template<typename T> | |||||
| void Circle<T>::setNumSegments(int num) | |||||
| { | |||||
| if (fNumSegments == num) | |||||
| return; | |||||
| fNumSegments = num; | |||||
| fTheta = 2.0f * M_PI / float(fNumSegments); | |||||
| fCos = std::cos(fTheta); | |||||
| fSin = std::sin(fTheta); | |||||
| } | |||||
| template<typename T> | |||||
| void Circle<T>::draw() | |||||
| { | |||||
| _draw(false); | |||||
| } | |||||
| template<typename T> | |||||
| void Circle<T>::drawOutline() | |||||
| { | |||||
| _draw(true); | |||||
| } | |||||
| template<typename T> | |||||
| Circle<T>& Circle<T>::operator=(const Circle<T>& cir) noexcept | |||||
| { | |||||
| fPos = cir.fPos; | |||||
| fSize = cir.fSize; | |||||
| fTheta = cir.fTheta; | |||||
| fCos = cir.fCos; | |||||
| fSin = cir.fSin; | |||||
| fNumSegments = cir.fNumSegments; | |||||
| return *this; | |||||
| } | |||||
| template<typename T> | |||||
| bool Circle<T>::operator==(const Circle<T>& cir) const noexcept | |||||
| { | |||||
| return (fPos == cir.fPos && fSize == cir.fSize && fNumSegments == cir.fNumSegments); | |||||
| } | |||||
| template<typename T> | |||||
| bool Circle<T>::operator!=(const Circle<T>& cir) const noexcept | |||||
| { | |||||
| return !operator==(cir); | |||||
| } | |||||
| template<typename T> | |||||
| void Circle<T>::_draw(const bool isOutline) | |||||
| { | |||||
| if (fNumSegments == 0 && fSize > 0.0f) | |||||
| return; | |||||
| float t, x = fSize, y = 0; | |||||
| glBegin(isOutline ? GL_LINE_LOOP : GL_POLYGON); | |||||
| for (int i=0; i<fNumSegments; ++i) | |||||
| { | |||||
| glVertex2f(x + fPos.fX, y + fPos.fY); | |||||
| t = x; | |||||
| x = fCos * x - fSin * y; | |||||
| y = fSin * t + fCos * y; | |||||
| } | |||||
| glEnd(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Triangle | // Triangle | ||||
| @@ -744,6 +926,11 @@ template class Line<float>; | |||||
| template class Line<int>; | template class Line<int>; | ||||
| template class Line<short>; | template class Line<short>; | ||||
| template class Circle<double>; | |||||
| template class Circle<float>; | |||||
| template class Circle<int>; | |||||
| template class Circle<short>; | |||||
| template class Triangle<double>; | template class Triangle<double>; | ||||
| template class Triangle<float>; | template class Triangle<float>; | ||||
| template class Triangle<int>; | template class Triangle<int>; | ||||