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