OpenFPGA/libs/EXTERNAL/libezgl/include/ezgl/rectangle.hpp

252 lines
4.7 KiB
C++

/*
* Copyright 2019 University of Toronto
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Authors: Mario Badr, Sameh Attia and Tanner Young-Schultz
*/
#ifndef EZGL_RECTANGLE_HPP
#define EZGL_RECTANGLE_HPP
#include "ezgl/point.hpp"
#include <algorithm>
namespace ezgl {
/**
* Represents a rectangle as two diagonally opposite points.
*/
class rectangle {
public:
/**
* Default constructor: Create a zero-sized rectangle at {0,0}.
*/
rectangle() : m_first({0, 0}), m_second({0, 0})
{
}
/**
* Create a rectangle from two diagonally opposite points.
*/
rectangle(point2d origin_pt, point2d top_right_pt) : m_first(origin_pt), m_second(top_right_pt)
{
}
/**
* Create a rectangle with a given width and height.
*/
rectangle(point2d origin_pt, double rec_width, double rec_height) : m_first(origin_pt), m_second(origin_pt)
{
m_second.x += rec_width;
m_second.y += rec_height;
}
/**
* The minimum x-coordinate.
*/
double left() const
{
return std::min(m_first.x, m_second.x);
}
/**
* The maximum x-coordinate.
*/
double right() const
{
return std::max(m_first.x, m_second.x);
}
/**
* The minimum y-coordinate.
*/
double bottom() const
{
return std::min(m_first.y, m_second.y);
}
/**
* The maximum y-coordinate.
*/
double top() const
{
return std::max(m_first.y, m_second.y);
}
/**
* The minimum x-coordinate and the minimum y-coordinate.
*/
point2d bottom_left() const
{
return {left(), bottom()};
}
/**
* The minimum x-coordinate and the maximum y-coordinate.
*/
point2d top_left() const
{
return {left(), top()};
}
/**
* The maximum x-coordinate and the minimum y-coordinate.
*/
point2d bottom_right() const
{
return {right(), bottom()};
}
/**
* The maximum x-coordinate and the maximum y-coordinate.
*/
point2d top_right() const
{
return {right(), top()};
}
/**
* Test if the x and y values are within the rectangle.
*/
bool contains(double x, double y) const
{
if(x < left() || right() < x || y < bottom() || top() < y) {
return false;
}
return true;
}
/**
* Test if the x and y values are within the rectangle.
*/
bool contains(point2d point) const
{
return contains(point.x, point.y);
}
/**
* The width of the rectangle.
*/
double width() const
{
return right() - left();
}
/**
* The height of the rectangle.
*/
double height() const
{
return top() - bottom();
}
/**
*
* The area of the rectangle.
*/
double area() const
{
return width() * height();
}
/**
* The center of the rectangle in the x plane.
*/
double center_x() const
{
return (right() + left()) * 0.5;
}
/**
* The center of the rectangle in the y plane.
*/
double center_y() const
{
return (top() + bottom()) * 0.5;
}
/**
* The center of the recangle.
*/
point2d center() const
{
return {center_x(), center_y()};
}
/**
* Test for equality.
*/
bool operator==(const rectangle &rhs) const
{
return m_first == rhs.m_first && m_second == rhs.m_second;
}
/**
* Test for inequality.
*/
bool operator!=(const rectangle &rhs) const
{
return !(rhs == *this);
}
/**
* translate the rectangle by positive offsets.
*/
friend rectangle &operator+=(rectangle &lhs, point2d const &rhs)
{
lhs.m_first += rhs;
lhs.m_second += rhs;
return lhs;
}
/**
* translate the rectangle by negative offsets.
*/
friend rectangle &operator-=(rectangle &lhs, point2d const &rhs)
{
lhs.m_first -= rhs;
lhs.m_second -= rhs;
return lhs;
}
/**
* Create a new rectangle that is translated (negative offsets).
*/
friend rectangle operator-(rectangle &lhs, point2d const &rhs)
{
return rectangle(lhs.m_first - rhs, lhs.m_second - rhs);
}
/**
* Create a new rectangle that is translated (positive offsets).
*/
friend rectangle operator+(rectangle &lhs, point2d const &rhs)
{
return rectangle(lhs.m_first + rhs, lhs.m_second + rhs);
}
/** The first point of the rectangle */
point2d m_first;
/** The second point of the rectangle */
point2d m_second;
};
}
#endif //EZGL_RECTANGLE_HPP