vec2.h

00001 /** @file geom/vec2.h 2-D geometric vector/point */
00002 
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 12962 2010-03-06 02:13:53Z irock $
00011 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/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 //
00032 ///////////////////////////////////////////////////////////////////////
00033 
00034 #ifndef GROOVX_GEOM_VEC2_H_UTC20050626084023_DEFINED
00035 #define GROOVX_GEOM_VEC2_H_UTC20050626084023_DEFINED
00036 
00037 #include "Util/FastMathFunctions.H"
00038 #include "Image/geom.h"
00039 
00040 #include <cmath>
00041 
00042 #include "rutz/debug.h"
00043 GVX_DBG_REGISTER
00044 
00045 namespace geom
00046 {
00047   /// Gfx::vec2 is a 2-D vector class for representing 2-D points or distances.
00048   template<class V>
00049   class vec2
00050   {
00051   public:
00052     vec2()         : xx(),  yy()  {} // default is zero-init
00053 
00054     vec2(V x, V y) : xx(x), yy(y) {}
00055 
00056     template <class U>
00057     explicit vec2(const vec2<U>& other) : xx(V(other.x())), yy(V(other.y())) {}
00058 
00059     template <class U>
00060     vec2& operator=(const vec2<U>& other)
00061     { xx = other.x(); yy = other.y(); return *this; }
00062 
00063     static vec2 zeros() { return vec2(V(0), V(0)); }
00064     static vec2 ones()  { return vec2(V(1), V(1)); }
00065 
00066     V& x() { return xx; }
00067     V& y() { return yy; }
00068 
00069     const V& x() const { return xx; }
00070     const V& y() const { return yy; }
00071 
00072     vec2 abs() const
00073     { return vec2(xx > 0 ? xx : -xx, yy > 0 ? yy : -yy); }
00074 
00075     void set(V x, V y) { xx = x; yy = y; }
00076 
00077     bool operator==(const vec2<V>& b)
00078     { return x() == b.x() && y() == b.y(); }
00079 
00080     //
00081     // Polar coordinates
00082     //
00083 
00084     double length() const { return fastSqrt(xx*xx + yy*yy); }
00085 
00086     void set_length(double len)
00087     {
00088       const double r = length();
00089       if (r != 0.0)
00090         scale_by(len / r);
00091     }
00092 
00093     void set_polar_rad(double r, double theta)
00094     {
00095       xx = r * cos(theta);
00096       yy = r * sin(theta);
00097     }
00098 
00099     double theta_deg() const
00100     {
00101       return geom::rad2deg(atan2(yy, xx));
00102     }
00103 
00104     double theta_rad() const
00105     {
00106       return atan2(yy, xx);
00107     }
00108 
00109 
00110     void set_theta_deg(double degrees)
00111     {
00112       set_polar_rad(length(), geom::deg2rad(degrees));
00113     }
00114 
00115     void rotate_deg(double degrees)
00116     {
00117       // FIXME should use a real sin(),cos() rotation matrix here?
00118       degrees = geom::deg_n180_180(degrees);
00119       if (degrees == 0.0)
00120         {
00121           return;
00122         }
00123       else if (degrees == 90.0)
00124         {
00125           double old_x = xx;
00126           xx = -yy;
00127           yy = old_x;
00128         }
00129       else if (degrees == 180.0)
00130         {
00131           xx = -xx;
00132           yy = -yy;
00133         }
00134       else if (degrees == -90.0)
00135         {
00136           double old_x = xx;
00137           xx = yy;
00138           yy = -old_x;
00139         }
00140       else
00141         {
00142           set_theta_deg(theta_deg() + degrees);
00143         }
00144     }
00145 
00146     /// Result in radians.
00147     double angle_to(const vec2<V>& b) const
00148     {
00149       return rad_0_2pi(atan2(b.y() - y(), b.x() - x()));
00150     }
00151 
00152     double distance_to(const vec2<V>& b) const
00153     {
00154       const double dx = x() - b.x();
00155       const double dy = y() - b.y();
00156       return fastSqrt(dx*dx + dy*dy);
00157     }
00158 
00159     //
00160     // vec2-scalar math
00161     //
00162 
00163     template <class U>
00164     void scale_by(const U& factor) { xx *= factor; yy *= factor; }
00165 
00166     vec2 operator*(const V& factor) const
00167     { return vec2<V>(xx * factor, yy * factor); }
00168 
00169     vec2 operator/(const V& factor) const
00170     { return vec2<V>(xx / factor, yy / factor); }
00171 
00172     template <class U>
00173     vec2& operator*=(const U& factor) { scale_by(factor); return *this; }
00174 
00175     template <class U>
00176     vec2& operator/=(const U& factor) { scale_by(V(1)/factor); return *this; }
00177 
00178 
00179     //
00180     // vec2-vec2 math
00181     //
00182 
00183     vec2 operator+(const vec2<V>& rhs) const
00184     { return vec2<V>(xx + rhs.x(), yy + rhs.y()); }
00185 
00186     vec2 operator-(const vec2<V>& rhs) const
00187     { return vec2<V>(xx - rhs.x(), yy - rhs.y()); }
00188 
00189 
00190     template <class U>
00191     vec2 operator*(const vec2<U>& rhs) const
00192     { return vec2(V(x() * rhs.x()), V(y() * rhs.y())); }
00193 
00194     template <class U>
00195     vec2 operator/(const vec2<U>& rhs) const
00196     { return vec2(V(x() / rhs.x()), V(y() / rhs.y())); }
00197 
00198 
00199     template <class U>
00200     vec2& operator+=(const vec2<U>& rhs)
00201     { xx += V(rhs.x()); yy += V(rhs.y()); return *this; }
00202 
00203     template <class U>
00204     vec2& operator-=(const vec2<U>& rhs)
00205     { xx -= V(rhs.x()); yy -= V(rhs.y()); return *this; }
00206 
00207 
00208     template <class U>
00209     vec2& operator*=(const vec2<U>& factor)
00210     { xx *= factor.x(); yy *= factor.y(); return *this; }
00211 
00212     template <class U>
00213     vec2& operator/=(const vec2<U>& factor)
00214     { xx /= factor.x(); yy /= factor.y(); return *this; }
00215 
00216     void debug_dump() const throw()
00217     {
00218       dbg_eval(0, xx);
00219       dbg_eval_nl(0, yy);
00220     }
00221 
00222   private:
00223     V xx;
00224     V yy;
00225   };
00226 
00227   template <class U>
00228   vec2<U> normal_to(const vec2<U>& a)
00229   { return vec2<U>(-a.y(), a.x()); }
00230 
00231   template <class U>
00232   vec2<U> make_unit_length(const vec2<U>& a)
00233   {
00234     const double r = a.length();
00235     if (r == 0.0) return a;
00236     return vec2<U>(a.x()/r, a.y()/r);
00237   }
00238 
00239   typedef vec2<int> vec2i;
00240   typedef vec2<float> vec2f;
00241   typedef vec2<double> vec2d;
00242 
00243 } // end namespace Gfx
00244 
00245 static const char __attribute__((used)) vcid_groovx_geom_vec2_h_utc20050626084023[] = "$Id: vec2.h 12962 2010-03-06 02:13:53Z irock $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/vec2.h $";
00246 #endif // !GROOVX_GEOM_VEC2_H_UTC20050626084023_DEFINED
Generated on Sun May 8 08:05:16 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3