/* * DISTRHO Plugin Framework (DPF) * Copyright (C) 2012-2016 Filipe Coelho * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this * permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "../Geometry.hpp" #include START_NAMESPACE_DGL static const float M_2PIf = 3.14159265358979323846f*2.0f; // ----------------------------------------------------------------------- // Point template Point::Point() noexcept : fX(0), fY(0) {} template Point::Point(const T& x, const T& y) noexcept : fX(x), fY(y) {} template Point::Point(const Point& pos) noexcept : fX(pos.fX), fY(pos.fY) {} template const T& Point::getX() const noexcept { return fX; } template const T& Point::getY() const noexcept { return fY; } template void Point::setX(const T& x) noexcept { fX = x; } template void Point::setY(const T& y) noexcept { fY = y; } template void Point::setPos(const T& x, const T& y) noexcept { fX = x; fY = y; } template void Point::setPos(const Point& pos) noexcept { fX = pos.fX; fY = pos.fY; } template void Point::moveBy(const T& x, const T& y) noexcept { fX = static_cast(fX+x); fY = static_cast(fY+y); } template void Point::moveBy(const Point& pos) noexcept { fX = static_cast(fX+pos.fX); fY = static_cast(fY+pos.fY); } template bool Point::isZero() const noexcept { return fX == 0 && fY == 0; } template bool Point::isNotZero() const noexcept { return fX != 0 || fY != 0; } template Point Point::operator+(const Point& pos) noexcept { return Point(fX+pos.fX, fY+pos.fY); } template Point Point::operator-(const Point& pos) noexcept { return Point(fX-pos.fX, fY-pos.fY); } template Point& Point::operator=(const Point& pos) noexcept { fX = pos.fX; fY = pos.fY; return *this; } template Point& Point::operator+=(const Point& pos) noexcept { fX = static_cast(fX+pos.fX); fY = static_cast(fY+pos.fY); return *this; } template Point& Point::operator-=(const Point& pos) noexcept { fX = static_cast(fX-pos.fX); fY = static_cast(fY-pos.fY); return *this; } template bool Point::operator==(const Point& pos) const noexcept { return (fX == pos.fX && fY == pos.fY); } template bool Point::operator!=(const Point& pos) const noexcept { return (fX != pos.fX || fY != pos.fY); } // ----------------------------------------------------------------------- // Size template Size::Size() noexcept : fWidth(0), fHeight(0) {} template Size::Size(const T& width, const T& height) noexcept : fWidth(width), fHeight(height) {} template Size::Size(const Size& size) noexcept : fWidth(size.fWidth), fHeight(size.fHeight) {} template const T& Size::getWidth() const noexcept { return fWidth; } template const T& Size::getHeight() const noexcept { return fHeight; } template void Size::setWidth(const T& width) noexcept { fWidth = width; } template void Size::setHeight(const T& height) noexcept { fHeight = height; } template void Size::setSize(const T& width, const T& height) noexcept { fWidth = width; fHeight = height; } template void Size::setSize(const Size& size) noexcept { fWidth = size.fWidth; fHeight = size.fHeight; } template void Size::growBy(double multiplier) noexcept { fWidth = static_cast(static_cast(fWidth)*multiplier); fHeight = static_cast(static_cast(fHeight)*multiplier); } template void Size::shrinkBy(double divider) noexcept { fWidth = static_cast(static_cast(fWidth)/divider); fHeight = static_cast(static_cast(fHeight)/divider); } template bool Size::isNull() const noexcept { return fWidth == 0 && fHeight == 0; } template bool Size::isNotNull() const noexcept { return fWidth != 0 || fHeight != 0; } template bool Size::isValid() const noexcept { return fWidth > 1 && fHeight > 1; } template bool Size::isInvalid() const noexcept { return fWidth <= 0 || fHeight <= 0; } template Size Size::operator+(const Size& size) noexcept { return Size(fWidth+size.fWidth, fHeight+size.fHeight); } template Size Size::operator-(const Size& size) noexcept { return Size(fWidth-size.fWidth, fHeight-size.fHeight); } template Size& Size::operator=(const Size& size) noexcept { fWidth = size.fWidth; fHeight = size.fHeight; return *this; } template Size& Size::operator+=(const Size& size) noexcept { fWidth = static_cast(fWidth+size.fWidth); fHeight = static_cast(fHeight+size.fHeight); return *this; } template Size& Size::operator-=(const Size& size) noexcept { fWidth = static_cast(fWidth-size.fWidth); fHeight = static_cast(fHeight-size.fHeight); return *this; } template Size& Size::operator*=(double m) noexcept { fWidth = static_cast(static_cast(fWidth)*m); fHeight = static_cast(static_cast(fHeight)*m); return *this; } template Size& Size::operator/=(double d) noexcept { fWidth = static_cast(static_cast(fWidth)/d); fHeight = static_cast(static_cast(fHeight)/d); return *this; } template bool Size::operator==(const Size& size) const noexcept { return (fWidth == size.fWidth && fHeight == size.fHeight); } template bool Size::operator!=(const Size& size) const noexcept { return (fWidth != size.fWidth || fHeight != size.fHeight); } // ----------------------------------------------------------------------- // Line template Line::Line() noexcept : fPosStart(0, 0), fPosEnd(0, 0) {} template Line::Line(const T& startX, const T& startY, const T& endX, const T& endY) noexcept : fPosStart(startX, startY), fPosEnd(endX, endY) {} template Line::Line(const T& startX, const T& startY, const Point& endPos) noexcept : fPosStart(startX, startY), fPosEnd(endPos) {} template Line::Line(const Point& startPos, const T& endX, const T& endY) noexcept : fPosStart(startPos), fPosEnd(endX, endY) {} template Line::Line(const Point& startPos, const Point& endPos) noexcept : fPosStart(startPos), fPosEnd(endPos) {} template Line::Line(const Line& line) noexcept : fPosStart(line.fPosStart), fPosEnd(line.fPosEnd) {} template const T& Line::getStartX() const noexcept { return fPosStart.fX; } template const T& Line::getStartY() const noexcept { return fPosStart.fY; } template const T& Line::getEndX() const noexcept { return fPosEnd.fX; } template const T& Line::getEndY() const noexcept { return fPosEnd.fY; } template const Point& Line::getStartPos() const noexcept { return fPosStart; } template const Point& Line::getEndPos() const noexcept { return fPosEnd; } template void Line::setStartX(const T& x) noexcept { fPosStart.fX = x; } template void Line::setStartY(const T& y) noexcept { fPosStart.fY = y; } template void Line::setStartPos(const T& x, const T& y) noexcept { fPosStart = Point(x, y); } template void Line::setStartPos(const Point& pos) noexcept { fPosStart = pos; } template void Line::setEndX(const T& x) noexcept { fPosEnd.fX = x; } template void Line::setEndY(const T& y) noexcept { fPosEnd.fY = y; } template void Line::setEndPos(const T& x, const T& y) noexcept { fPosEnd = Point(x, y); } template void Line::setEndPos(const Point& pos) noexcept { fPosEnd = pos; } template void Line::moveBy(const T& x, const T& y) noexcept { fPosStart.moveBy(x, y); fPosEnd.moveBy(x, y); } template void Line::moveBy(const Point& pos) noexcept { fPosStart.moveBy(pos); fPosEnd.moveBy(pos); } template void Line::draw() { DISTRHO_SAFE_ASSERT_RETURN(fPosStart != fPosEnd,); glBegin(GL_LINES); { glVertex2d(fPosStart.fX, fPosStart.fY); glVertex2d(fPosEnd.fX, fPosEnd.fY); } glEnd(); } template bool Line::isNull() const noexcept { return fPosStart == fPosEnd; } template bool Line::isNotNull() const noexcept { return fPosStart != fPosEnd; } template Line& Line::operator=(const Line& line) noexcept { fPosStart = line.fPosStart; fPosEnd = line.fPosEnd; return *this; } template bool Line::operator==(const Line& line) const noexcept { return (fPosStart == line.fPosStart && fPosEnd == line.fPosEnd); } template bool Line::operator!=(const Line& line) const noexcept { return (fPosStart != line.fPosStart || fPosEnd != line.fPosEnd); } // ----------------------------------------------------------------------- // 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, const float size, const uint numSegments) : fPos(x, y), fSize(size), fNumSegments(numSegments >= 3 ? numSegments : 3), fTheta(M_2PIf / static_cast(fNumSegments)), fCos(std::cos(fTheta)), fSin(std::sin(fTheta)) { DISTRHO_SAFE_ASSERT(fSize > 0.0f); } template Circle::Circle(const Point& pos, const float size, const uint numSegments) : fPos(pos), fSize(size), fNumSegments(numSegments >= 3 ? numSegments : 3), fTheta(M_2PIf / static_cast(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.fY; } 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(const float size) noexcept { DISTRHO_SAFE_ASSERT_RETURN(size > 0.0f,); fSize = size; } template uint Circle::getNumSegments() const noexcept { return fNumSegments; } template void Circle::setNumSegments(const uint num) { DISTRHO_SAFE_ASSERT_RETURN(num >= 3,); if (fNumSegments == num) return; fNumSegments = num; fTheta = M_2PIf / static_cast(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 && d_isEqual(fSize, cir.fSize) && fNumSegments == cir.fNumSegments); } template bool Circle::operator!=(const Circle& cir) const noexcept { return (fPos != cir.fPos || d_isNotEqual(fSize, cir.fSize) || fNumSegments != cir.fNumSegments); } template void Circle::_draw(const bool outline) { DISTRHO_SAFE_ASSERT_RETURN(fNumSegments >= 3 && fSize > 0.0f,); double t, x = fSize, y = 0.0; glBegin(outline ? GL_LINE_LOOP : GL_POLYGON); for (uint i=0; i Triangle::Triangle() noexcept : fPos1(0, 0), fPos2(0, 0), fPos3(0, 0) {} template Triangle::Triangle(const T& x1, const T& y1, const T& x2, const T& y2, const T& x3, const T& y3) noexcept : fPos1(x1, y1), fPos2(x2, y2), fPos3(x3, y3) {} template Triangle::Triangle(const Point& pos1, const Point& pos2, const Point& pos3) noexcept : fPos1(pos1), fPos2(pos2), fPos3(pos3) {} template Triangle::Triangle(const Triangle& tri) noexcept : fPos1(tri.fPos1), fPos2(tri.fPos2), fPos3(tri.fPos3) {} template void Triangle::draw() { _draw(false); } template void Triangle::drawOutline() { _draw(true); } template bool Triangle::isNull() const noexcept { return fPos1 == fPos2 && fPos1 == fPos3; } template bool Triangle::isNotNull() const noexcept { return fPos1 != fPos2 || fPos1 != fPos3; } template bool Triangle::isValid() const noexcept { return fPos1 != fPos2 && fPos1 != fPos3; } template bool Triangle::isInvalid() const noexcept { return fPos1 == fPos2 || fPos1 == fPos3; } template Triangle& Triangle::operator=(const Triangle& tri) noexcept { fPos1 = tri.fPos1; fPos2 = tri.fPos2; fPos3 = tri.fPos3; return *this; } template bool Triangle::operator==(const Triangle& tri) const noexcept { return (fPos1 == tri.fPos1 && fPos2 == tri.fPos2 && fPos3 == tri.fPos3); } template bool Triangle::operator!=(const Triangle& tri) const noexcept { return (fPos1 != tri.fPos1 || fPos2 != tri.fPos2 || fPos3 != tri.fPos3); } template void Triangle::_draw(const bool outline) { DISTRHO_SAFE_ASSERT_RETURN(fPos1 != fPos2 && fPos1 != fPos3,); glBegin(outline ? GL_LINE_LOOP : GL_TRIANGLES); { glVertex2d(fPos1.fX, fPos1.fY); glVertex2d(fPos2.fX, fPos2.fY); glVertex2d(fPos3.fX, fPos3.fY); } glEnd(); } // ----------------------------------------------------------------------- // Rectangle template Rectangle::Rectangle() noexcept : fPos(0, 0), fSize(0, 0) {} template Rectangle::Rectangle(const T& x, const T& y, const T& width, const T& height) noexcept : fPos(x, y), fSize(width, height) {} template Rectangle::Rectangle(const T& x, const T& y, const Size& size) noexcept : fPos(x, y), fSize(size) {} template Rectangle::Rectangle(const Point& pos, const T& width, const T& height) noexcept : fPos(pos), fSize(width, height) {} template Rectangle::Rectangle(const Point& pos, const Size& size) noexcept : fPos(pos), fSize(size) {} template Rectangle::Rectangle(const Rectangle& rect) noexcept : fPos(rect.fPos), fSize(rect.fSize) {} template const T& Rectangle::getX() const noexcept { return fPos.fX; } template const T& Rectangle::getY() const noexcept { return fPos.fY; } template const T& Rectangle::getWidth() const noexcept { return fSize.fWidth; } template const T& Rectangle::getHeight() const noexcept { return fSize.fHeight; } template const Point& Rectangle::getPos() const noexcept { return fPos; } template const Size& Rectangle::getSize() const noexcept { return fSize; } template void Rectangle::setX(const T& x) noexcept { fPos.fX = x; } template void Rectangle::setY(const T& y) noexcept { fPos.fY = y; } template void Rectangle::setPos(const T& x, const T& y) noexcept { fPos.fX = x; fPos.fY = y; } template void Rectangle::setPos(const Point& pos) noexcept { fPos = pos; } template void Rectangle::moveBy(const T& x, const T& y) noexcept { fPos.moveBy(x, y); } template void Rectangle::moveBy(const Point& pos) noexcept { fPos.moveBy(pos); } template void Rectangle::setWidth(const T& width) noexcept { fSize.fWidth = width; } template void Rectangle::setHeight(const T& height) noexcept { fSize.fHeight = height; } template void Rectangle::setSize(const T& width, const T& height) noexcept { fSize.fWidth = width; fSize.fHeight = height; } template void Rectangle::setSize(const Size& size) noexcept { fSize = size; } template void Rectangle::growBy(double multiplier) noexcept { fSize.growBy(multiplier); } template void Rectangle::shrinkBy(double divider) noexcept { fSize.shrinkBy(divider); } template void Rectangle::setRectangle(const Point& pos, const Size& size) noexcept { fPos = pos; fSize = size; } template void Rectangle::setRectangle(const Rectangle& rect) noexcept { fPos = rect.fPos; fSize = rect.fSize; } template bool Rectangle::contains(const T& x, const T& y) const noexcept { return (x >= fPos.fX && y >= fPos.fY && x <= fPos.fX+fSize.fWidth && y <= fPos.fY+fSize.fHeight); } template bool Rectangle::contains(const Point& pos) const noexcept { return contains(pos.fX, pos.fY); } template bool Rectangle::containsX(const T& x) const noexcept { return (x >= fPos.fX && x <= fPos.fX + fSize.fWidth); } template bool Rectangle::containsY(const T& y) const noexcept { return (y >= fPos.fY && y <= fPos.fY + fSize.fHeight); } template void Rectangle::draw() { _draw(false); } template void Rectangle::drawOutline() { _draw(true); } template Rectangle& Rectangle::operator=(const Rectangle& rect) noexcept { fPos = rect.fPos; fSize = rect.fSize; return *this; } template Rectangle& Rectangle::operator*=(double m) noexcept { fSize *= m; return *this; } template Rectangle& Rectangle::operator/=(double d) noexcept { fSize /= d; return *this; } template bool Rectangle::operator==(const Rectangle& rect) const noexcept { return (fPos == rect.fPos && fSize == rect.fSize); } template bool Rectangle::operator!=(const Rectangle& rect) const noexcept { return (fPos != rect.fPos || fSize != rect.fSize); } template void Rectangle::_draw(const bool outline) { DISTRHO_SAFE_ASSERT_RETURN(fSize.isValid(),); glBegin(outline ? GL_LINE_LOOP : GL_QUADS); { glTexCoord2f(0.0f, 0.0f); glVertex2d(fPos.fX, fPos.fY); glTexCoord2f(1.0f, 0.0f); glVertex2d(fPos.fX+fSize.fWidth, fPos.fY); glTexCoord2f(1.0f, 1.0f); glVertex2d(fPos.fX+fSize.fWidth, fPos.fY+fSize.fHeight); glTexCoord2f(0.0f, 1.0f); glVertex2d(fPos.fX, fPos.fY+fSize.fHeight); } glEnd(); } // ----------------------------------------------------------------------- // Possible template data types template class Point; template class Point; template class Point; template class Point; template class Point; template class Point; template class Size; template class Size; template class Size; template class Size; template class Size; template class Size; template class Line; template class Line; template class Line; template class Line; template class Line; template class Line; template class Circle; template class Circle; template class Circle; template class Circle; template class Circle; template class Circle; template class Triangle; template class Triangle; template class Triangle; template class Triangle; template class Triangle; template class Triangle; template class Rectangle; template class Rectangle; template class Rectangle; template class Rectangle; template class Rectangle; template class Rectangle; // ----------------------------------------------------------------------- END_NAMESPACE_DGL