00001
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
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() {}
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
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
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
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
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 }
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