/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** * Qwt Widget Library * Copyright (C) 1997 Josef Wilgen * Copyright (C) 2002 Uwe Rathmann * * This library is free software; you can redistribute it and/or * modify it under the terms of the Qwt License, Version 1.0 *****************************************************************************/ #include #if QT_VERSION < 0x040000 #include "qwt_math.h" #include "qwt_double_rect.h" /*! Constructs a null point. \sa QwtDoublePoint::isNull */ QwtDoublePoint::QwtDoublePoint(): d_x(0.0), d_y(0.0) { } //! Constructs a point with coordinates specified by x and y. QwtDoublePoint::QwtDoublePoint(double x, double y ): d_x(x), d_y(y) { } /*! Copy constructor. Constructs a point using the values of the point specified. */ QwtDoublePoint::QwtDoublePoint(const QPoint &p): d_x(double(p.x())), d_y(double(p.y())) { } /*! Returns true if point1 is equal to point2; otherwise returns false. Two points are equal to each other if both x-coordinates and both y-coordinates are the same. */ bool QwtDoublePoint::operator==(const QwtDoublePoint &other) const { return (d_x == other.d_x) && (d_y == other.d_y); } //! Returns true if point1 is not equal to point2; otherwise returns false. bool QwtDoublePoint::operator!=(const QwtDoublePoint &other) const { return !operator==(other); } /*! Negates the coordinates of the point, and returns a point with the new coordinates. (Inversion). */ const QwtDoublePoint QwtDoublePoint::operator-() const { return QwtDoublePoint(-d_x, -d_y); } /*! Adds the coordinates of the point to the corresponding coordinates of the other point, and returns a point with the new coordinates. (Vector addition.) */ const QwtDoublePoint QwtDoublePoint::operator+( const QwtDoublePoint &other) const { return QwtDoublePoint(d_x + other.d_x, d_y + other.d_y); } /*! Subtracts the coordinates of the other point from the corresponding coordinates of the given point, and returns a point with the new coordinates. (Vector subtraction.) */ const QwtDoublePoint QwtDoublePoint::operator-( const QwtDoublePoint &other) const { return QwtDoublePoint(d_x - other.d_x, d_y - other.d_y); } /*! Multiplies the coordinates of the point by the given scale factor, and returns a point with the new coordinates. (Scalar multiplication of a vector.) */ const QwtDoublePoint QwtDoublePoint::operator*(double factor) const { return QwtDoublePoint(d_x * factor, d_y * factor); } /*! Divides the coordinates of the point by the given scale factor, and returns a point with the new coordinates. (Scalar division of a vector.) */ const QwtDoublePoint QwtDoublePoint::operator/(double factor) const { return QwtDoublePoint(d_x / factor, d_y / factor); } /*! Adds the coordinates of this point to the corresponding coordinates of the other point, and returns a reference to this point with the new coordinates. This is equivalent to vector addition. */ QwtDoublePoint &QwtDoublePoint::operator+=(const QwtDoublePoint &other) { d_x += other.d_x; d_y += other.d_y; return *this; } /*! Subtracts the coordinates of the other point from the corresponding coordinates of this point, and returns a reference to this point with the new coordinates. This is equivalent to vector subtraction. */ QwtDoublePoint &QwtDoublePoint::operator-=(const QwtDoublePoint &other) { d_x -= other.d_x; d_y -= other.d_y; return *this; } /*! Multiplies the coordinates of this point by the given scale factor, and returns a reference to this point with the new coordinates. This is equivalent to scalar multiplication of a vector. */ QwtDoublePoint &QwtDoublePoint::operator*=(double factor) { d_x *= factor; d_y *= factor; return *this; } /*! Divides the coordinates of this point by the given scale factor, and returns a references to this point with the new coordinates. This is equivalent to scalar division of a vector. */ QwtDoublePoint &QwtDoublePoint::operator/=(double factor) { d_x /= factor; d_y /= factor; return *this; } //! Constructs an invalid size. QwtDoubleSize::QwtDoubleSize(): d_width(-1.0), d_height(-1.0) { } //! Constructs a size with width width and height height. QwtDoubleSize::QwtDoubleSize( double width, double height ): d_width(width), d_height(height) { } //! Constructs a size with floating point accuracy from the given size. QwtDoubleSize::QwtDoubleSize(const QSize &sz): d_width(double(sz.width())), d_height(double(sz.height())) { } //! Swaps the width and height values. void QwtDoubleSize::transpose() { double tmp = d_width; d_width = d_height; d_height = tmp; } /*! Returns a size with the maximum width and height of this size and other. */ QwtDoubleSize QwtDoubleSize::expandedTo( const QwtDoubleSize &other) const { return QwtDoubleSize( qwtMax(d_width, other.d_width), qwtMax(d_height, other.d_height) ); } /*! Returns a size with the minimum width and height of this size and other. */ QwtDoubleSize QwtDoubleSize::boundedTo( const QwtDoubleSize &other) const { return QwtDoubleSize( qwtMin(d_width, other.d_width), qwtMin(d_height, other.d_height) ); } //! Returns true if s1 and s2 are equal; otherwise returns false. bool QwtDoubleSize::operator==(const QwtDoubleSize &other) const { return d_width == other.d_width && d_height == other.d_height; } //! Returns true if s1 and s2 are different; otherwise returns false. bool QwtDoubleSize::operator!=(const QwtDoubleSize &other) const { return !operator==(other); } /*! Returns the size formed by adding both components by the components of other. Each component is added separately. */ const QwtDoubleSize QwtDoubleSize::operator+( const QwtDoubleSize &other) const { return QwtDoubleSize(d_width + other.d_width, d_height + other.d_height); } /*! Returns the size formed by subtracting both components by the components of other. Each component is subtracted separately. */ const QwtDoubleSize QwtDoubleSize::operator-( const QwtDoubleSize &other) const { return QwtDoubleSize(d_width - other.d_width, d_height - other.d_height); } //! Returns the size formed by multiplying both components by c. const QwtDoubleSize QwtDoubleSize::operator*(double c) const { return QwtDoubleSize(d_width * c, d_height * c); } //! Returns the size formed by dividing both components by c. const QwtDoubleSize QwtDoubleSize::operator/(double c) const { return QwtDoubleSize(d_width / c, d_height / c); } //! Adds size other to this size and returns a reference to this size. QwtDoubleSize &QwtDoubleSize::operator+=(const QwtDoubleSize &other) { d_width += other.d_width; d_height += other.d_height; return *this; } //! Subtracts size other from this size and returns a reference to this size. QwtDoubleSize &QwtDoubleSize::operator-=(const QwtDoubleSize &other) { d_width -= other.d_width; d_height -= other.d_height; return *this; } /* Multiplies this size's width and height by c, and returns a reference to this size. */ QwtDoubleSize &QwtDoubleSize::operator*=(double c) { d_width *= c; d_height *= c; return *this; } /* Devides this size's width and height by c, and returns a reference to this size. */ QwtDoubleSize &QwtDoubleSize::operator/=(double c) { d_width /= c; d_height /= c; return *this; } //! Constructs an rectangle with all components set to 0.0 QwtDoubleRect::QwtDoubleRect(): d_left(0.0), d_right(0.0), d_top(0.0), d_bottom(0.0) { } /*! Constructs an rectangle with x1 to x2 as x-range and, y1 to y2 as y-range. */ QwtDoubleRect::QwtDoubleRect(double left, double top, double width, double height): d_left(left), d_right(left + width), d_top(top), d_bottom(top + height) { } /*! Constructs a rectangle with topLeft as the top-left corner and size as the rectangle size. */ QwtDoubleRect::QwtDoubleRect( const QwtDoublePoint &p, const QwtDoubleSize &size): d_left(p.x()), d_right(p.x() + size.width()), d_top(p.y()), d_bottom(p.y() + size.height()) { } QwtDoubleRect::QwtDoubleRect(const QRect &rect): d_left(rect.left()), d_right(rect.right()), d_top(rect.top()), d_bottom(rect.bottom()) { } QRect QwtDoubleRect::toRect() const { return QRect(qRound(x()), qRound(y()), qRound(width()), qRound(height())); } /*! Set the x-range from x1 to x2 and the y-range from y1 to y2. */ void QwtDoubleRect::setRect(double left, double top, double width, double height) { d_left = left; d_right = left + width; d_top = top; d_bottom = top + height; } /*! Sets the size of the rectangle to size. Changes x2 and y2 only. */ void QwtDoubleRect::setSize(const QwtDoubleSize &size) { setWidth(size.width()); setHeight(size.height()); } /*! Returns a normalized rectangle, i.e. a rectangle that has a non-negative width and height. It swaps x1 and x2 if x1() > x2(), and swaps y1 and y2 if y1() > y2(). */ QwtDoubleRect QwtDoubleRect::normalized() const { QwtDoubleRect r; if ( d_right < d_left ) { r.d_left = d_right; r.d_right = d_left; } else { r.d_left = d_left; r.d_right = d_right; } if ( d_bottom < d_top ) { r.d_top = d_bottom; r.d_bottom = d_top; } else { r.d_top = d_top; r.d_bottom = d_bottom; } return r; } /*! Returns the bounding rectangle of this rectangle and rectangle other. r.unite(s) is equivalent to r|s. */ QwtDoubleRect QwtDoubleRect::unite(const QwtDoubleRect &other) const { return *this | other; } /*! Returns the intersection of this rectangle and rectangle other. r.intersect(s) is equivalent to r&s. */ QwtDoubleRect QwtDoubleRect::intersect(const QwtDoubleRect &other) const { return *this & other; } /*! Returns true if this rectangle intersects with rectangle other; otherwise returns false. */ bool QwtDoubleRect::intersects(const QwtDoubleRect &other) const { return ( qwtMax(d_left, other.d_left) <= qwtMin(d_right, other.d_right) ) && ( qwtMax(d_top, other.d_top ) <= qwtMin(d_bottom, other.d_bottom) ); } //! Returns true if this rect and other are equal; otherwise returns false. bool QwtDoubleRect::operator==(const QwtDoubleRect &other) const { return d_left == other.d_left && d_right == other.d_right && d_top == other.d_top && d_bottom == other.d_bottom; } //! Returns true if this rect and other are different; otherwise returns false. bool QwtDoubleRect::operator!=(const QwtDoubleRect &other) const { return !operator==(other); } /*! Returns the bounding rectangle of this rectangle and rectangle other. The bounding rectangle of a nonempty rectangle and an empty or invalid rectangle is defined to be the nonempty rectangle. */ QwtDoubleRect QwtDoubleRect::operator|(const QwtDoubleRect &other) const { if ( isEmpty() ) return other; if ( other.isEmpty() ) return *this; const double minX = qwtMin(d_left, other.d_left); const double maxX = qwtMax(d_right, other.d_right); const double minY = qwtMin(d_top, other.d_top); const double maxY = qwtMax(d_bottom, other.d_bottom); return QwtDoubleRect(minX, minY, maxX - minX, maxY - minY); } /*! Returns the intersection of this rectangle and rectangle other. Returns an empty rectangle if there is no intersection. */ QwtDoubleRect QwtDoubleRect::operator&(const QwtDoubleRect &other) const { if (isNull() || other.isNull()) return QwtDoubleRect(); const QwtDoubleRect r1 = normalized(); const QwtDoubleRect r2 = other.normalized(); const double minX = qwtMax(r1.left(), r2.left()); const double maxX = qwtMin(r1.right(), r2.right()); const double minY = qwtMax(r1.top(), r2.top()); const double maxY = qwtMin(r1.bottom(), r2.bottom()); return QwtDoubleRect(minX, minY, maxX - minX, maxY - minY); } //! Unites this rectangle with rectangle other. QwtDoubleRect &QwtDoubleRect::operator|=(const QwtDoubleRect &other) { *this = *this | other; return *this; } //! Intersects this rectangle with rectangle other. QwtDoubleRect &QwtDoubleRect::operator&=(const QwtDoubleRect &other) { *this = *this & other; return *this; } //! Returns the center point of the rectangle. QwtDoublePoint QwtDoubleRect::center() const { return QwtDoublePoint(d_left + (d_right - d_left) / 2.0, d_top + (d_bottom - d_top) / 2.0); } /*! Returns true if the point (x, y) is inside or on the edge of the rectangle; otherwise returns false. If proper is true, this function returns true only if p is inside (not on the edge). */ bool QwtDoubleRect::contains(double x, double y, bool proper) const { if ( proper ) return x > d_left && x < d_right && y > d_top && y < d_bottom; else return x >= d_left && x <= d_right && y >= d_top && y <= d_bottom; } /*! Returns true if the point p is inside or on the edge of the rectangle; otherwise returns false. If proper is true, this function returns true only if p is inside (not on the edge). */ bool QwtDoubleRect::contains(const QwtDoublePoint &p, bool proper) const { return contains(p.x(), p.y(), proper); } /*! Returns true if the rectangle other is inside this rectangle; otherwise returns false. If proper is true, this function returns true only if other is entirely inside (not on the edge). */ bool QwtDoubleRect::contains(const QwtDoubleRect &other, bool proper) const { return contains(other.d_left, other.d_top, proper) && contains(other.d_right, other.d_bottom, proper); } //! moves x1() to x, leaving the size unchanged void QwtDoubleRect::moveLeft(double x) { const double w = width(); d_left = x; d_right = d_left + w; } //! moves x1() to x, leaving the size unchanged void QwtDoubleRect::moveRight(double x) { const double w = width(); d_right = x; d_left = d_right - w; } //! moves y1() to y, leaving the size unchanged void QwtDoubleRect::moveTop(double y) { const double h = height(); d_top = y; d_bottom = d_top + h; } //! moves y1() to y, leaving the size unchanged void QwtDoubleRect::moveBottom(double y) { const double h = height(); d_bottom = y; d_top = d_bottom - h; } //! moves left() to x and top() to y, leaving the size unchanged void QwtDoubleRect::moveTo(double x, double y) { moveLeft(x); moveTop(y); } //! moves x1() by dx and y1() by dy. leaving the size unchanged void QwtDoubleRect::moveBy(double dx, double dy) { d_left += dx; d_right += dx; d_top += dy; d_bottom += dy; } //! moves the center to pos, leaving the size unchanged void QwtDoubleRect::moveCenter(const QwtDoublePoint &pos) { moveCenter(pos.x(), pos.y()); } //! moves the center to (x, y), leaving the size unchanged void QwtDoubleRect::moveCenter(double x, double y) { moveTo(x - width() / 2.0, y - height() / 2.0); } #endif // QT_VERSION < 0x040000