@@ -25,6 +25,7 @@ START_NAMESPACE_DGL | |||
// Forward class names | |||
template<typename> class Line; | |||
template<typename> class Circle; | |||
template<typename> class Triangle; | |||
template<typename> class Rectangle; | |||
@@ -99,6 +100,7 @@ public: | |||
private: | |||
T fX, fY; | |||
template<typename> friend class Line; | |||
template<typename> friend class Circle; | |||
template<typename> friend class Triangle; | |||
template<typename> 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<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 | |||
@@ -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; | |||
@@ -412,6 +412,188 @@ bool Line<T>::operator!=(const Line<T>& line) const noexcept | |||
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 | |||
@@ -744,6 +926,11 @@ template class Line<float>; | |||
template class Line<int>; | |||
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<float>; | |||
template class Triangle<int>; | |||