/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: Patrick Boenzli : Vector2D::scale() Vector2D::abs() Benjamin Grauer: port to Vector2D */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH #include "rect2D.h" #ifdef DEBUG #include "debug.h" #else #include #define PRINT(x) printf #endif /** * @brief creates a new Rectangle with * @param x the left border * @param y the top border * @param width: the width * @param height the height */ Rect2D::Rect2D(float x, float y, float width, float height) { this->setLeft(x), this->setTop(y); this->setSize(width, height); } /** * @brief creates a new Rectangle with * @param topLeft the top-left corner * @param bottomRight the lower-right corner */ Rect2D::Rect2D(const Vector2D& topLeft, const Vector2D& bottomRight ) { this->setTopLeft(topLeft); this->setBottomRight(bottomRight); } /** * @brief creates a new Rectangle with * @param rect the rectangle to copy. */ Rect2D::Rect2D(const Rect2D& rect) { *this = rect; } /** * @brief copies the Values of rect to this rect * @param rect copy the values from. * @returns this reference. */ Rect2D& Rect2D::operator=(const Rect2D& rect) { this->_topLeft = rect._topLeft; this->_bottomRight = rect._bottomRight; return *this; } /** * @brief compares two rectanles. * @param rect the rectangle to compare * @returns true if the two rectangles are the same */ bool Rect2D::operator==(const Rect2D& rect) const { return (this->_topLeft == rect._topLeft && this->_bottomRight == rect._bottomRight); } /** * @brief negative compares two rectanles. * @param rect the rectangle to compare * @returns true if the two rectangles are different */ bool Rect2D::operator!=(const Rect2D& rect) const { return (this->_topLeft != rect._topLeft || this->_bottomRight != rect._bottomRight); } /** * @brief adds two rectangles together * @param rect the rectagle to be added * @returns a Rectangle, where both are added together. * * @note since adding rectangles does not make sense generally, here a description: * adds toplefts and botomrights */ Rect2D Rect2D::operator+(const Rect2D& rect) const { return Rect2D(this->_topLeft + rect._topLeft, this->_bottomRight + rect._bottomRight); } /** * @brief adds two rectangles together * @param rect the rectagle to be added to this one * @returns a Rectangle, where both are added together. */ Rect2D& Rect2D::operator+=(const Rect2D& rect) { this->_topLeft += rect._topLeft; this->_bottomRight += rect._bottomRight; return *this; } /** * @brief subracts two rectangles from each other * @param rect the rectagle to be substracted from this one * @returns a Rectangle, where both are substracted from one another. */ Rect2D Rect2D::operator-(const Rect2D& rect) const { return Rect2D(this->_topLeft - rect._topLeft, this->_bottomRight - rect._bottomRight); } /** * @brief subracts two rectangles from each other * @param rect the rectagle to be substracted from this one * @returns a Rectangle, where both are substracted from one another. */ Rect2D& Rect2D::operator-=(const Rect2D& rect) { this->_topLeft -= rect._topLeft; this->_bottomRight -= rect._bottomRight; return *this; } /** * @brief intersects two Rectangles. * @see intersection . * @param rect the Rectangle to intersect with this one. * @returns the intersection Region. */ Rect2D Rect2D::operator&(const Rect2D& rect) const { return this->intersection(rect); } /** * @brief intersects two Rectangles and assigns result to this one. * @param rect the Rectangle to intersect with this one. * @returns the intersection Region. */ Rect2D& Rect2D::operator&=(const Rect2D& rect) { *this = this->intersection(rect); } /** * TODO coment/implement */ Rect2D Rect2D::operator*(const Vector2D& scaling) const { #warning implements this... //this->scale(scaling); } /** * @brief sets the width of the Rectangle * @param width the new width of the Rectangle * * the rectangle will be resized from the top left corner out. */ void Rect2D::setWidth(float width) { this->_bottomRight.x = this->_topLeft.x + width; } /** * @brief sets the height of the Rectangle * @param height the new height of the Rectangle * * the rectangle will be resized from the top left corner out. */ void Rect2D::setHeight(float height) { this->_bottomRight.y = this->_topLeft.y + height; } /** * @brief sets the size of the Rectangle * @param width the new width of the Rectangle. * @param height the new height of the Rectangle. * the rectangle will be resized from the top left corner out. */ void Rect2D::setSize(float width, float height) { this->_bottomRight = this->_topLeft + Vector2D(width, height); } /** * @brief sets the size of the Rectangle * @param size the new size of the Rectangle. * the rectangle will be resized from the top left corner out. */ void Rect2D::setSize(const Vector2D& size) { this->_bottomRight = this->_topLeft + size; } /** * @brief sets the new Center * @param center the center to move the Rectangle to. * moves the Rectangle from its current center to the new Center */ void Rect2D::setCenter(const Vector2D& center) { this->move(center - this->center()); } /** * @brief sets the new Center * @param x the center's X to move the Rectangle to. * @param y the center's Y to move the Rectangle to. * moves the Rectangle from its current center to the new Center */ void Rect2D::setCenter(float x, float y) { this->setCenter(Vector2D(x, y)); } /** * @brief sets the new Center * @param center the center to move the Rectangle to. * moves the Rectangle from its current center to the new Center */ void Rect2D::setCenterX(float x) { #warning implement this } /** * @brief sets the new Center * @param center the center to move the Rectangle to. * moves the Rectangle from its current center to the new Center */ void Rect2D::setCenterY(float y) { #warning implement this } /** * @brief scales the Rectangle from topLeft out. * @param x: the scale factor in x direction */ void Rect2D::scaleX(float x) { this->_bottomRight.x = this->_topLeft.x + this->width() * x; } /** * @brief scales the Rectangle from topLeft out. * @param y: the scale factor in y direction */ void Rect2D::scaleY(float y) { this->_bottomRight.y = this->_topLeft.y + this->height() * y; } /** * @brief scales the Rectangle from topLeft out. * @param x: the scale factor in x direction * @param y: the scale factor in y direction */ void Rect2D::scale(float x, float y) { this->scale(Vector2D(x,y)); } /** * @brief scales the Rectangle from topLeft out. * @param v: the scale factors. */ void Rect2D::scale(const Vector2D& v) { this->_bottomRight = this->_topLeft + this->size().internalMultipy(v); } /** * @brief scales the Rectangle from the Center out. * @param x: the scale factor in x-direction. * @param y: the scale factor in y-direction. */ void Rect2D::scaleCentered(float x, float y) { this->scaleCentered(Vector2D(x, y)); } /** * @brief scales the Rectangle from the Center out. * @param v: the scale factors. */ void Rect2D::scaleCentered(const Vector2D& v) { #warning implement this } /** * @brief moves the Rectangle * @param x the amount to move in x. */ void Rect2D::moveX(float x) { this->_topLeft.x += x; this->_bottomRight.x += x; } /** * @brief moves the Rectangle * @param y the amount to move in y. */ void Rect2D::moveY(float y) { this->_topLeft.y += y; this->_bottomRight.y += y; } /** * @brief moves the Rectangle * @param x the amount to move in x. * @param y the amount to move in y. */ void Rect2D::move(float x, float y) { this->move(Vector2D(x, y)); } /** * @brief moves the Rectangle * @param v the amount to move. */ void Rect2D::move(const Vector2D& v) { this->_topLeft += v; this->_bottomRight += v; } /** * @brief swaps top and bottom. */ void Rect2D::swapTopBottom() { float tmp = this->top(); this->setTop(this->bottom()); this->setBottom(tmp); } /** * @brief swaps left and right. */ void Rect2D::swapLeftRight() { float tmp = this->left(); this->setLeft(this->right()); this->setRight(tmp); } /** * @brief normalizes the Rectangle. * * Normalizing a Rectangle means, that the top is above bottom, and left is left of right afterwards :) */ void Rect2D::normalize() { if (this->top() > this->bottom()) this->swapTopBottom(); if (this->left() > this->right()) this->swapLeftRight(); } /** * @brief normalizes the Rectangle. * @returns the normalized version of this rectangle. * * Normalizing a Rectangle means, that the top is above bottom, and left is left of right afterwards :) */ Rect2D Rect2D::normalized() const { Rect2D norm(*this); norm.normalize(); return norm; } /** * @brief The intersection of two Rectangles is calculated and returned. * @param intersector the Rectangle to intersect with this one. * @return the intersection region. */ Rect2D Rect2D::intersection(const Rect2D& intersector) const { #warning implement } /** * @brief checks if the intersection of two Rectangles is not empty. */ bool Rect2D::intersects(const Rect2D& intersector) const { #warning implement } /** * @brief make an Extensive join of two rectangles. * @param rect the rectangle to unite with this one. * @returns the united rectangle */ Rect2D Rect2D::unite(const Rect2D& rect) { #warning implement } /** * @brief checks if rect is inside of this Rectangle. * @param rect The Rectangle that should be inside of this one. * @returns tru if it is. */ bool Rect2D::contains(const Rect2D& rect) const { return (this->top() <= rect.top() && this->bottom() >= rect.bottom() && this->left() <= rect.left() && this->right() >= rect.right()); } /** * @param point the point to check if it is inside. * @returns true if the point is inside of this Rectangle. */ bool Rect2D::contains(const Vector2D& point) const { return (this->top() <= point.y && this->bottom() >= point.y && this->left() <= point.x && this->right() >= point.x); } /** * @brief slerps this Rectangle to rect. * @param rect the rectangle to slerp to. * @param value how much to slerp to [0:stay, 1:go there] * @returns reference to this. */ const Rect2D& Rect2D::slerp(const Rect2D& rect, float value) { this->_topLeft.slerp(rect._topLeft, value); this->_bottomRight.slerp(rect._bottomRight, value); return *this; } /** * @brief print debug output for the Rect */ void Rect2D::debug() const { PRINT(0)("Top: %0.2f Left: %0.2f; Bottom %0.2f Right:%0.2f; Size: %0.2fx%0.2f\n", top(), left(), bottom(), right(), size().x, size().y); }