vec2.h

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 1999-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Thu Jan 28 12:54:13 1999
00010 // commit: $Id: vec2.h 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/geom/vec2.h $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_GEOM_VEC2_H_UTC20050626084023_DEFINED
00035 #define GROOVX_GEOM_VEC2_H_UTC20050626084023_DEFINED
00036 
00037 #include "geom/geom.h"
00038 
00039 #include <cmath>
00040 
00041 #include "rutz/debug.h"
00042 GVX_DBG_REGISTER
00043 
00044 namespace geom
00045 {
00047   template<class V>
00048   class vec2
00049   {
00050   public:
00051     vec2()         : xx(),  yy()  {} // default is zero-init
00052 
00053     vec2(V x, V y) : xx(x), yy(y) {}
00054 
00055     template <class U>
00056     explicit vec2(const vec2<U>& other) : xx(V(other.x())), yy(V(other.y())) {}
00057 
00058     template <class U>
00059     vec2& operator=(const vec2<U>& other)
00060     { xx = other.x(); yy = other.y(); return *this; }
00061 
00062     static vec2 zeros() { return vec2(V(0), V(0)); }
00063     static vec2 ones()  { return vec2(V(1), V(1)); }
00064 
00065     V& x() { return xx; }
00066     V& y() { return yy; }
00067 
00068     const V& x() const { return xx; }
00069     const V& y() const { return yy; }
00070 
00071     vec2 abs() const
00072     { return vec2(xx > 0 ? xx : -xx, yy > 0 ? yy : -yy); }
00073 
00074     void set(V x, V y) { xx = x; yy = y; }
00075 
00076     bool operator==(const vec2<V>& b)
00077     { return x() == b.x() && y() == b.y(); }
00078 
00079     //
00080     // Polar coordinates
00081     //
00082 
00083     double length() const { return sqrt(xx*xx + yy*yy); }
00084 
00085     void set_length(double len)
00086     {
00087       const double r = length();
00088       if (r != 0.0)
00089         scale_by(len / r);
00090     }
00091 
00092     void set_polar_rad(double r, double theta)
00093     {
00094       xx = r * cos(theta);
00095       yy = r * sin(theta);
00096     }
00097 
00098     double theta_deg() const
00099     {
00100       return geom::rad2deg(atan2(yy, xx));
00101     }
00102 
00103     void set_theta_deg(double degrees)
00104     {
00105       set_polar_rad(length(), geom::deg2rad(degrees));
00106     }
00107 
00108     void rotate_deg(double degrees)
00109     {
00110       // FIXME should use a real sin(),cos() rotation matrix here?
00111       degrees = geom::deg_n180_180(degrees);
00112       if (degrees == 0.0)
00113         {
00114           return;
00115         }
00116       else if (degrees == 90.0)
00117         {
00118           double old_x = xx;
00119           xx = -yy;
00120           yy = old_x;
00121         }
00122       else if (degrees == 180.0)
00123         {
00124           xx = -xx;
00125           yy = -yy;
00126         }
00127       else if (degrees == -90.0)
00128         {
00129           double old_x = xx;
00130           xx = yy;
00131           yy = -old_x;
00132         }
00133       else
00134         {
00135           set_theta_deg(theta_deg() + degrees);
00136         }
00137     }
00138 
00140     double angle_to(const vec2<V>& b) const
00141     {
00142       return rad_0_2pi(atan2(b.y() - y(), b.x() - x()));
00143     }
00144 
00145     double distance_to(const vec2<V>& b) const
00146     {
00147       const double dx = x() - b.x();
00148       const double dy = y() - b.y();
00149       return sqrt(dx*dx + dy*dy);
00150     }
00151 
00152     //
00153     // vec2-scalar math
00154     //
00155 
00156     template <class U>
00157     void scale_by(const U& factor) { xx *= factor; yy *= factor; }
00158 
00159     vec2 operator*(const V& factor) const
00160     { return vec2<V>(xx * factor, yy * factor); }
00161 
00162     vec2 operator/(const V& factor) const
00163     { return vec2<V>(xx / factor, yy / factor); }
00164 
00165     template <class U>
00166     vec2& operator*=(const U& factor) { scale_by(factor); return *this; }
00167 
00168     template <class U>
00169     vec2& operator/=(const U& factor) { scale_by(V(1)/factor); return *this; }
00170 
00171 
00172     //
00173     // vec2-vec2 math
00174     //
00175 
00176     vec2 operator+(const vec2<V>& rhs) const
00177     { return vec2<V>(xx + rhs.x(), yy + rhs.y()); }
00178 
00179     vec2 operator-(const vec2<V>& rhs) const
00180     { return vec2<V>(xx - rhs.x(), yy - rhs.y()); }
00181 
00182 
00183     template <class U>
00184     vec2 operator*(const vec2<U>& rhs) const
00185     { return vec2(V(x() * rhs.x()), V(y() * rhs.y())); }
00186 
00187     template <class U>
00188     vec2 operator/(const vec2<U>& rhs) const
00189     { return vec2(V(x() / rhs.x()), V(y() / rhs.y())); }
00190 
00191 
00192     template <class U>
00193     vec2& operator+=(const vec2<U>& rhs)
00194     { xx += V(rhs.x()); yy += V(rhs.y()); return *this; }
00195 
00196     template <class U>
00197     vec2& operator-=(const vec2<U>& rhs)
00198     { xx -= V(rhs.x()); yy -= V(rhs.y()); return *this; }
00199 
00200 
00201     template <class U>
00202     vec2& operator*=(const vec2<U>& factor)
00203     { xx *= factor.x(); yy *= factor.y(); return *this; }
00204 
00205     template <class U>
00206     vec2& operator/=(const vec2<U>& factor)
00207     { xx /= factor.x(); yy /= factor.y(); return *this; }
00208 
00209     void debug_dump() const throw()
00210     {
00211       dbg_eval(0, xx);
00212       dbg_eval_nl(0, yy);
00213     }
00214 
00215   private:
00216     V xx;
00217     V yy;
00218   };
00219 
00220   template <class U>
00221   vec2<U> normal_to(const vec2<U>& a)
00222   { return vec2<U>(-a.y(), a.x()); }
00223 
00224   template <class U>
00225   vec2<U> make_unit_length(const vec2<U>& a)
00226   {
00227     const double r = a.length();
00228     if (r == 0.0) return a;
00229     return vec2<U>(a.x()/r, a.y()/r);
00230   }
00231 
00232   typedef vec2<int> vec2i;
00233   typedef vec2<float> vec2f;
00234   typedef vec2<double> vec2d;
00235 
00236 } // end namespace Gfx
00237 
00238 static const char __attribute__((used)) vcid_groovx_geom_vec2_h_utc20050626084023[] = "$Id: vec2.h 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00239 #endif // !GROOVX_GEOM_VEC2_H_UTC20050626084023_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:38 2008 by Doxygen version 1.5.5.