From 9e618371d7ac1f3d6984b0b96102d3bfe56c68d5 Mon Sep 17 00:00:00 2001 From: falkTX Date: Wed, 14 May 2014 15:34:18 +0100 Subject: [PATCH] Add Circle class --- dgl/Geometry.hpp | 117 ++++++++++++++++++++++++++- dgl/src/Geometry.cpp | 187 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 301 insertions(+), 3 deletions(-) diff --git a/dgl/Geometry.hpp b/dgl/Geometry.hpp index 9ba38e58..1b0b22e1 100644 --- a/dgl/Geometry.hpp +++ b/dgl/Geometry.hpp @@ -25,6 +25,7 @@ START_NAMESPACE_DGL // Forward class names template class Line; +template class Circle; template class Triangle; template class Rectangle; @@ -99,6 +100,7 @@ public: private: T fX, fY; template friend class Line; + template friend class Circle; template friend class Triangle; template friend class Rectangle; }; @@ -186,7 +188,7 @@ class Line { public: /** - Constructor for null line ([0, 0] to [0, 0]). + Constructor for a null line ([0, 0] to [0, 0]). */ Line() noexcept; @@ -308,6 +310,115 @@ private: Point fPosStart, fPosEnd; }; +// ----------------------------------------------------------------------- +// Circle + +template +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& pos, float size, int numSegments = 300); + + /** + Constructor using another Circle class values. + */ + Circle(const Circle& cir) noexcept; + + /** + Get X value. + */ + const T& getX() const noexcept; + + /** + Get Y value. + */ + const T& getY() const noexcept; + + /** + Get position. + */ + const Point& 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& 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& operator=(const Circle& cir) noexcept; + bool operator==(const Circle& cir) const noexcept; + bool operator!=(const Circle& cir) const noexcept; + +private: + Point fPos; + float fSize; + int fNumSegments; + + // cached values + float fTheta, fCos, fSin; + + void _draw(const bool isOutline); +}; + // ----------------------------------------------------------------------- // Triangle @@ -316,7 +427,7 @@ class Triangle { public: /** - Constructor for null triangle. + Constructor for a null triangle. */ Triangle() noexcept; @@ -363,7 +474,7 @@ class Rectangle { public: /** - Constructor for null rectangle. + Constructor for a null rectangle. */ Rectangle() noexcept; diff --git a/dgl/src/Geometry.cpp b/dgl/src/Geometry.cpp index 69e16730..b87d2365 100644 --- a/dgl/src/Geometry.cpp +++ b/dgl/src/Geometry.cpp @@ -412,6 +412,188 @@ bool Line::operator!=(const Line& line) const noexcept return !operator==(line); } +// ----------------------------------------------------------------------- +// Circle + +template +Circle::Circle() noexcept + : fPos(0, 0), + fSize(0.0f), + fNumSegments(0), + fTheta(0.0f), + fCos(0.0f), + fSin(0.0f) +{ +} + +template +Circle::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 +Circle::Circle(const Point& 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 +Circle::Circle(const Circle& 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 +const T& Circle::getX() const noexcept +{ + return fPos.fX; +} + +template +const T& Circle::getY() const noexcept +{ + return fPos.fX; +} + +template +const Point& Circle::getPos() const noexcept +{ + return fPos; +} + +template +void Circle::setX(const T& x) noexcept +{ + fPos.fX = x; +} + +template +void Circle::setY(const T& y) noexcept +{ + fPos.fY = y; +} + +template +void Circle::setPos(const T& x, const T& y) noexcept +{ + fPos.fX = x; + fPos.fY = y; +} + +template +void Circle::setPos(const Point& pos) noexcept +{ + fPos = pos; +} + +template +float Circle::getSize() const noexcept +{ + return fSize; +} + +template +void Circle::setSize(float size) noexcept +{ + fSize = size; +} + +template +int Circle::getNumSegments() const noexcept +{ + return fNumSegments; +} + +template +void Circle::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 +void Circle::draw() +{ + _draw(false); +} + +template +void Circle::drawOutline() +{ + _draw(true); +} + +template +Circle& Circle::operator=(const Circle& cir) noexcept +{ + fPos = cir.fPos; + fSize = cir.fSize; + fTheta = cir.fTheta; + fCos = cir.fCos; + fSin = cir.fSin; + fNumSegments = cir.fNumSegments; + return *this; +} + +template +bool Circle::operator==(const Circle& cir) const noexcept +{ + return (fPos == cir.fPos && fSize == cir.fSize && fNumSegments == cir.fNumSegments); +} + +template +bool Circle::operator!=(const Circle& cir) const noexcept +{ + return !operator==(cir); +} + +template +void Circle::_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; template class Line; template class Line; +template class Circle; +template class Circle; +template class Circle; +template class Circle; + template class Triangle; template class Triangle; template class Triangle;