geometry_2d.h

Go to the documentation of this file.
00001 /*
00002  * geometry_2d.h
00003  *
00004  * Copyright (C) 2003,2008 Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * Basic 2D geometry.
00032  */
00033 
00034 #ifndef WAVEPACKET_GEOMETRY_2D_H__
00035 #define WAVEPACKET_GEOMETRY_2D_H__
00036 
00037 
00038 // includes --------------------------------------------------------------------
00039 #include "common/common.h"
00040 
00041 #include <iostream>
00042 
00043 #include <math.h>
00044 
00045 /// \ingroup geometric
00046 /*@{*/
00047 
00048 
00049 ////////////////////////////////////////////////////////////////////////////////
00050 ///
00051 /// \defgroup geometry Core Geometry Objects
00052 ///
00053 /// This module contains general geometry primitives for use in 2D or 3D
00054 /// spaces.
00055 ///
00056 ////////////////////////////////////////////////////////////////////////////////
00057 /*@{*/
00058 
00059 
00060 
00061 ////////////////////////////////////////////////////////////////////////////////
00062 //
00063 //      Basic types
00064 //
00065 ////////////////////////////////////////////////////////////////////////////////
00066 
00067 /**
00068  * Template for two-dimensional point.
00069  */
00070 template <class T>
00071 struct point2d_t {
00072         // constructors, manipulators
00073         point2d_t(IN T in_x = 0, IN T in_y = 0) throw() :
00074             x(in_x),
00075             y(in_y)
00076                 { }
00077         point2d_t(IN const point2d_t& pt) throw() :
00078             x(pt.x),
00079             y(pt.y)
00080                 { }
00081 
00082         void set(IN T in_x, IN T in_y) throw() {
00083                         x = in_x;
00084                         y = in_y;
00085                 }
00086 
00087         void clear(void) throw() {
00088                 x = y = 0;
00089                 }
00090 
00091         /**
00092          * dumps contents to stderr
00093          */
00094         void dump(const char * title) const throw() {
00095                         DPRINTF("  %s: (%5.2f, %5.2f)", title, x, y);
00096                 }
00097 
00098         /**
00099          * vector subtraction
00100          */
00101         point2d_t operator - (IN const point2d_t& rhs) const throw() {
00102                         return point2d_t(x - rhs.x, y - rhs.y);
00103                 }
00104 
00105         /**
00106          * vector addition
00107          */
00108         point2d_t operator + (IN const point2d_t& rhs) const throw() {
00109                         return point2d_t(x + rhs.x, y + rhs.y);
00110                 }
00111 
00112         void normalize(void) throw() {
00113                         float mag = sqrt((x * x) + (y * y));
00114                         if (mag) {
00115                                 x = (T) (x / mag);
00116                                 y = (T) (y / mag);
00117                         }
00118                 }
00119 
00120         // static operators
00121         static T dotProduct(IN const point2d_t& u,
00122                                 IN const point2d_t& v) throw() {
00123                         return (u.x * v.x) + (u.y * v.y);
00124                 }
00125 
00126         // data fields
00127         T       x;
00128         T       y;
00129 };
00130 
00131 
00132 
00133 /// templated 2D rectangle
00134 template <class T>
00135 struct rect2d_t {
00136         typedef point2d_t<T> point_t;
00137 
00138         // constructors
00139         rect2d_t(void) throw() { }
00140         rect2d_t(IN T iLeft, IN T iTop, IN T iRight, IN T iBottom) throw() {
00141                         left = iLeft;
00142                         top = iTop;
00143                         right = iRight;
00144                         bottom = iBottom;
00145                 }
00146 
00147         /// expand rect to fully contain input rect
00148         void inflate(IN const rect2d_t& r) throw() {
00149                         if (left > r.left)
00150                                 left = r.left;
00151                         if (right < r.right)
00152                                 right = r.right;
00153                         if (top > r.top)
00154                                 top = r.top;
00155                         if (bottom < r.bottom)
00156                                 bottom = r.bottom;
00157                 }
00158 
00159         /// valid?
00160         bool isValid(void) const throw() {
00161                         return ((right >= left) && (bottom >= top));
00162                 }
00163 
00164         /// expand rect in all dimensions by provided amount
00165         void expand(IN T s) throw() {
00166                         left -= s;
00167                         right += s;
00168                         top -= s;
00169                         bottom += s;
00170                 }
00171 
00172         /// null size?
00173         bool isEmpty(void) const throw() {
00174                         if (left == right ||
00175                             top == bottom)
00176                                 return true;
00177                         return false;
00178                 }
00179 
00180         /// move rect by specified dx,dy amount
00181         void shift(IN T dx, IN T dy) throw() {
00182                         left += dx;
00183                         top += dy;
00184                         right += dx;
00185                         bottom += dy;
00186                 }
00187 
00188         /// does this rect contain the specified point?
00189         bool contains(IN const point_t& pt) const throw() {
00190                         if (pt.x >= left && pt.x <= right &&
00191                             pt.y >= top && pt.y <= bottom)
00192                                 return true;
00193                         return false;
00194                 }
00195 
00196         /// does this rect contain the specified point?
00197         bool contains(IN float x, IN float y) const throw() {
00198                         return this->contains(point_t(x, y));
00199                 }
00200 
00201         /// does this rect fully contain the specified rect?
00202         bool contains(IN const rect2d_t& r) const throw() {
00203                         return (left <= r.left &&
00204                                 right >= r.right &&
00205                                 top <= r.top &&
00206                                 bottom >= r.bottom);
00207                 }
00208 
00209         /// does this rect intersect the specified rect?
00210         bool intersects(IN const rect2d_t& r) const throw() {
00211                         if (left < r.right &&
00212                             right > r.left &&
00213                             top < r.bottom &&
00214                             bottom > r.top)
00215                                 return true;
00216                         return false;
00217                 }
00218 
00219         /// expand to include the given point
00220         void expandToInclude(IN const point_t& p) throw() {
00221                         this->expandToInclude(p.x, p.y);
00222                 }
00223 
00224         /// expand to include the given point
00225         void expandToInclude(IN T x, IN T y) throw() {
00226                         left =(x < left) ? x : left;
00227                         top = (y < top) ? y : top;
00228                         right = (x > right) ? x : right;
00229                         bottom = (y > bottom) ? y : bottom;
00230                 }
00231 
00232         /// explicitly set the rect coordinates
00233         void set(IN T in_left, IN T in_top,
00234                         IN T in_right, IN T in_bottom) throw() {
00235                         left = in_left;
00236                         top = in_top;
00237                         right = in_right;
00238                         bottom = in_bottom;
00239                 }
00240 
00241         /// minimum bounding rect containing the two points
00242         void fromPoints(IN const point_t& p0, IN const point_t& p1) throw() {
00243                         left = (p0.x < p1.x) ? p0.x : p1.x;
00244                         top = (p0.y < p1.y) ? p0.y : p1.y;
00245                         right = (p0.x > p1.x) ? p0.x : p1.x;
00246                         bottom = (p0.y > p1.y) ? p0.y : p1.y;
00247                 }
00248 
00249         /// scale out in X and Y directions
00250         void scale(IN float rX, IN float rY) throw() {
00251                         left *= rX;
00252                         top *= rY;
00253                         right *= rX;
00254                         bottom *= rY;
00255                 }
00256 
00257         /// reset rect to be null rectangle at (0,0)
00258         void clear(void) throw() { this->set(0, 0, 0, 0); }
00259 
00260         /// debug helper to dump rectangle to std err
00261         void dump(IN const char * title) const throw() {
00262                         std::cerr << title << ": (" << left << ", " << top;
00263                         std::cerr << ") - (" << right << ", " << bottom;
00264                         std::cerr << ")\n";
00265                 }
00266 
00267         /// return top left coordinate
00268         point_t getTopLeft(void) const throw() {
00269                         return point_t(left, top);
00270                 }
00271 
00272         /// return top right coordinate
00273         point_t getBottomRight(void) const throw() {
00274                         return point_t(right, bottom);
00275                 }
00276 
00277         // data fields
00278         T       left;
00279         T       top;
00280         T       right;
00281         T       bottom;
00282 };
00283 
00284 
00285 
00286 #endif  // WAVEPACKET_GEOMETRY_2D_H__
00287