@@ -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>; | ||||