vec2.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00048 template<class V>
00049 class vec2
00050 {
00051 public:
00052 vec2() : xx(), yy() {}
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
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
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
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
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
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 }
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:
00246 #endif // !GROOVX_GEOM_VEC2_H_UTC20050626084023_DEFINED