Sirikata
|
00001 /* Sirikata Utilities -- Math Library 00002 * Vector2.hpp 00003 * 00004 * Copyright (c) 2009, Daniel Reiter Horn 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 #ifndef _SIRIKATA_VECTOR2_HPP_ 00033 #define _SIRIKATA_VECTOR2_HPP_ 00034 00035 #include <string> 00036 #include <cassert> 00037 #include <sstream> 00038 00039 namespace Sirikata { 00040 template <typename scalar> class Vector2 { 00041 public: 00042 static const unsigned char size = 2; 00043 typedef scalar real; 00044 union { 00045 struct { 00046 scalar x; 00047 scalar y; 00048 }; 00049 scalar v[2]; 00050 }; 00051 Vector2(scalar x, scalar y) { 00052 this->x=x; 00053 this->y=y; 00054 } 00055 template <class V> explicit Vector2(const V&other) { 00056 x=other[0]; 00057 y=other[1]; 00058 } 00059 Vector2(){} 00060 template <class V> static Vector2 fromSSE(const V&other){ 00061 return Vector2(other.x(),other.y()); 00062 } 00063 scalar&operator[](const unsigned int i) { 00064 assert(i<2); 00065 return v[i]; 00066 } 00067 #if 0 00068 template<class T> operator T() const{ 00069 return T(x,y); 00070 } 00071 #else 00072 template<class T> T convert() const{ 00073 return T(x,y); 00074 } 00075 #endif 00076 scalar operator[](const unsigned int i) const{ 00077 assert(i<2); 00078 return v[i]; 00079 } 00080 Vector2&operator=(scalar other) { 00081 x=other; 00082 y=other; 00083 return *this; 00084 } 00085 static Vector2 zero() { 00086 return Vector2(0,0); 00087 } 00088 static Vector2 unitX() { 00089 return Vector2(1,0); 00090 } 00091 static Vector2 unitY() { 00092 return Vector2(0,1); 00093 } 00094 static Vector2 unitNegX() { 00095 return Vector2(-1,0); 00096 } 00097 static Vector2 unitNegY() { 00098 return Vector2(0,-1); 00099 } 00100 Vector2 operator*(scalar scale) const { 00101 return Vector2(x*scale,y*scale); 00102 } 00103 Vector2 operator/(scalar scale) const { 00104 return Vector2(x/scale,y/scale); 00105 } 00106 Vector2 operator+(const Vector2&other) const { 00107 return Vector2(x+other.x,y+other.y); 00108 } 00109 Vector2 componentMultiply(const Vector2&other) const { 00110 return Vector2(x*other.x,y*other.y); 00111 } 00112 Vector2 operator-(const Vector2&other) const { 00113 return Vector2(x-other.x,y-other.y); 00114 } 00115 Vector2 operator-() const { 00116 return Vector2(-x,-y); 00117 } 00118 Vector2& operator*=(scalar scale) { 00119 x*=scale; 00120 y*=scale; 00121 return *this; 00122 } 00123 Vector2& operator/=(scalar scale) { 00124 x/=scale; 00125 y/=scale; 00126 return *this; 00127 } 00128 Vector2& operator+=(const Vector2& other) { 00129 x+=other.x; 00130 y+=other.y; 00131 return *this; 00132 } 00133 Vector2& operator-=(const Vector2& other) { 00134 x-=other.x; 00135 y-=other.y; 00136 return *this; 00137 } 00138 scalar dot(const Vector2 &other) const{ 00139 return x*other.x+y*other.y; 00140 } 00141 Vector2 min(const Vector2&other)const { 00142 return Vector2(other.x<x?other.x:x, 00143 other.y<y?other.y:y); 00144 } 00145 Vector2 max(const Vector2&other)const { 00146 return Vector2(other.x>x?other.x:x, 00147 other.y>y?other.y:y); 00148 } 00149 scalar lengthSquared()const { 00150 return dot(*this); 00151 } 00152 scalar length()const { 00153 return (scalar)sqrt(dot(*this)); 00154 } 00155 bool operator==(const Vector2&other)const { 00156 return x==other.x&&y==other.y; 00157 } 00158 bool operator!=(const Vector2&other)const { 00159 return x!=other.x||y!=other.y; 00160 } 00161 Vector2 normal()const { 00162 scalar len=length(); 00163 if (len>1e-08) 00164 return *this/len; 00165 return *this; 00166 } 00167 scalar normalizeThis() { 00168 scalar len=length(); 00169 if (len>1e-08) 00170 *this/=len; 00171 return len; 00172 } 00173 std::string toString()const { 00174 std::ostringstream os; 00175 os<<'<'<<x<<","<<y<<'>'; 00176 return os.str(); 00177 } 00178 Vector2 reflect(const Vector2& normal)const { 00179 return Vector2(*this-normal*((scalar)2.0*this->dot(normal))); 00180 } 00181 }; 00182 00183 template<typename scalar> inline Vector2<scalar> operator *(scalar lhs, const Vector2<scalar> &rhs) { 00184 return Vector2<scalar>(lhs*rhs.x,lhs*rhs.y,lhs*rhs.z); 00185 } 00186 template<typename scalar> inline Vector2<scalar> operator /(scalar lhs, const Vector2<scalar> &rhs) { 00187 return Vector2<scalar>(lhs/rhs.x,lhs/rhs.y); 00188 } 00189 template<typename scalar> inline std::ostream& operator <<(std::ostream& os, const Vector2<scalar> &rhs) { 00190 os<<'<'<<rhs.x<<","<<rhs.y<<","<<'>'; 00191 return os; 00192 } 00193 template<typename scalar> inline std::istream& operator >>(std::istream& is, Vector2<scalar> &rhs) { 00194 // FIXME this should be more robust. It currently relies on the exact format provided by operator << 00195 char dummy; 00196 is >> dummy >> rhs.x >> dummy >> rhs.y >> dummy; 00197 return is; 00198 } 00199 00200 } 00201 #endif