point.h

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 #ifndef FIFE_VIDEO_POINT_H
00023 #define FIFE_VIDEO_POINT_H
00024 
00025 // Standard C++ library includes
00026 #include <iostream>
00027 #include <cassert>
00028 
00029 // Platform specific includes
00030 
00031 // 3rd party library includes
00032 
00033 // FIFE includes
00034 // These includes are split up in two parts, separated by one empty line
00035 // First block: files included from the FIFE root src directory
00036 // Second block: files included from the same folder
00037 #include "util/base/fife_stdint.h"
00038 #include "util/math/fife_math.h"
00039 
00040 namespace FIFE {
00041 
00047     template <typename T> class PointType2D {
00048     public:
00049         union {
00050             T val[2];
00051             struct {
00052                 T x,y;
00053             };
00054         };
00055 
00060         explicit PointType2D(T _x = 0, T _y = 0): x(_x), y(_y) {
00061         }
00062 
00065         PointType2D(const PointType2D<T>& rhs): x(rhs.x), y(rhs.y) {
00066         }
00067 
00070         PointType2D<T> operator+(const PointType2D<T>& p) const {
00071             return PointType2D<T>(x + p.x, y + p.y);
00072         }
00073 
00076         PointType2D<T> operator-(const PointType2D<T>& p) const {
00077             return PointType2D<T>(x - p.x, y - p.y);
00078         }
00079 
00082         PointType2D<T>& operator+=(const PointType2D<T>& p) {
00083             x += p.x;
00084             y += p.y;
00085             return *this;
00086         }
00087 
00090         PointType2D<T>& operator-=(const PointType2D<T>& p) {
00091             x -= p.x;
00092             y -= p.y;
00093             return *this;
00094         }
00095 
00098         PointType2D<T> operator*(const T& i) const {
00099             return PointType2D<T>(x * i, y * i);
00100         }
00101 
00104         PointType2D<T> operator/(const T& i) const {
00105             return PointType2D<T>(x / i, y / i);
00106         }
00107 
00110         bool operator==(const PointType2D<T>& p) const {
00111             return x == p.x && y == p.y;
00112         }
00113 
00116         bool operator!=(const PointType2D<T>& p) const {
00117             return !(x == p.x && y == p.y);
00118         }
00119 
00122         T length() const {
00123             double sq;
00124             sq = x*x + y*y;
00125             return static_cast<T>(Mathd::Sqrt(sq));
00126         }
00127 
00130         void normalize() {
00131             T invLength = static_cast<T>(1.0/length());
00132 
00133             //TODO: get rid of this static cast
00134             if (invLength > static_cast<T>(Mathd::zeroTolerance())) {
00135                 x = x * invLength;
00136                 y = y * invLength;
00137             }
00138             else {
00139                 x = 0;
00140                 y = 0;
00141             }
00142         }
00143 
00146         void rotate(T angle){
00147             //TODO: get rid of this static cast
00148             T theta = (angle * static_cast<T>(Mathd::pi()))/180;
00149             T costheta = static_cast<T>(Mathd::Cos(theta));
00150             T sintheta = static_cast<T>(Mathd::Sin(theta));
00151 
00152             T nx = x;
00153             T ny = y;
00154 
00155             x = costheta * nx - sintheta * ny;
00156             y = sintheta * nx + costheta * ny;
00157         }
00158 
00161         void rotate(const PointType2D<T>& origin, T angle){
00162             //TODO: get rid of this static cast
00163             T theta = (angle * static_cast<T>(Mathd::pi()))/180;
00164             T costheta = static_cast<T>(Mathd::Cos(theta));
00165             T sintheta = static_cast<T>(Mathd::Sin(theta));
00166 
00167             T nx = x - origin.x;
00168             T ny = y - origin.y;
00169 
00170             x = costheta * nx - sintheta * ny;
00171             y = sintheta * nx + costheta * ny;
00172         }
00173 
00176         void set(T _x, T _y) {
00177             x = _x;
00178             y = _y;
00179         }
00180 
00181         inline T& operator[] (int32_t ind) {
00182             assert(ind > -1 && ind < 2);
00183             return val[ind];
00184         }
00185     };
00186 
00189     template<typename T>
00190     std::ostream& operator<<(std::ostream& os, const PointType2D<T>& p) {
00191         return os << "(" << p.x << ":" << p.y << ")";
00192     }
00193 
00194     typedef PointType2D<int32_t> Point;
00195     typedef PointType2D<double> DoublePoint;
00196 
00202     template <typename T> class PointType3D {
00203     public:
00204         union {
00205             T val[3];
00206             struct {
00207                 T x,y,z;
00208             };
00209         };
00210 
00215         explicit PointType3D(T _x = 0, T _y = 0, T _z = 0): x(_x), y(_y), z(_z) {
00216         }
00217 
00220         PointType3D(const PointType3D<T>& rhs): x(rhs.x), y(rhs.y), z(rhs.z) {
00221         }
00222 
00225         PointType3D<T> operator+(const PointType3D<T>& p) const {
00226             return PointType3D<T>(x + p.x, y + p.y, z + p.z);
00227         }
00228 
00231         PointType3D<T> operator-(const PointType3D<T>& p) const {
00232             return PointType3D<T>(x - p.x, y - p.y, z - p.z);
00233         }
00234 
00237         PointType3D<T>& operator+=(const PointType3D<T>& p) {
00238             x += p.x;
00239             y += p.y;
00240             z += p.z;
00241             return *this;
00242         }
00243 
00246         PointType3D<T>& operator-=(const PointType3D<T>& p) {
00247             x -= p.x;
00248             y -= p.y;
00249             z -= p.z;
00250             return *this;
00251         }
00252 
00255         PointType3D<T> operator*(const T& i) const {
00256             return PointType3D<T>(x * i, y * i, z * i);
00257         }
00258 
00261         PointType3D<T> operator/(const T& i) const {
00262             return PointType3D<T>(x / i, y / i, z / i);
00263         }
00264 
00267         bool operator==(const PointType3D<T>& p) const {
00268             return x == p.x && y == p.y && z == p.z;
00269         }
00270 
00273         bool operator!=(const PointType3D<T>& p) const {
00274             return !(x == p.x && y == p.y && z == p.z);
00275         }
00276 
00279         T length() const {
00280             double sq;
00281             sq = x*x + y*y + z*z;
00282             return static_cast<T>(Mathd::Sqrt(sq));
00283         }
00284 
00287         void normalize() {
00288             T invLength = static_cast<T>(1.0/length());
00289 
00290             //TODO: get rid of this static cast
00291             if (invLength > static_cast<T>(Mathd::zeroTolerance())) {
00292                 x = x * invLength;
00293                 y = y * invLength;
00294                 z = z * invLength;
00295             }
00296             else {
00297                 x = 0;
00298                 y = 0;
00299                 z = 0;
00300             }
00301         }
00302 
00305         void set(T _x, T _y, T _z) {
00306             x = _x;
00307             y = _y;
00308             z = _z;
00309         }
00310 
00311         inline T& operator[] (int32_t ind) {
00312             assert(ind > -1 && ind < 3);
00313             return val[ind];
00314         }
00315     };
00316 
00319     template<typename T>
00320     std::ostream& operator<<(std::ostream& os, const PointType3D<T>& p) {
00321         return os << "(" << p.x << ":" << p.y << ":" << p.z << ")";
00322     }
00323 
00324     typedef PointType3D<int32_t> Point3D;
00325     typedef PointType3D<double> DoublePoint3D;
00326 
00329     inline Point doublePt2intPt(DoublePoint pt) {
00330         Point tmp(static_cast<int32_t>(round(pt.x)), static_cast<int32_t>(round(pt.y)));
00331         return tmp;
00332     }
00333 
00336     inline Point3D doublePt2intPt(DoublePoint3D pt) {
00337         Point3D tmp(static_cast<int32_t>(round(pt.x)), static_cast<int32_t>(round(pt.y)), static_cast<int32_t>(round(pt.z)));
00338         return tmp;
00339     }
00340 
00343     inline DoublePoint intPt2doublePt(Point pt) {
00344         DoublePoint tmp(static_cast<double>(pt.x), static_cast<double>(pt.y));
00345         return tmp;
00346     }
00347 
00350     inline DoublePoint3D intPt2doublePt(Point3D pt) {
00351         DoublePoint3D tmp(static_cast<double>(pt.x), static_cast<double>(pt.y), static_cast<double>(pt.z));
00352         return tmp;
00353     }
00354 
00355 }
00356 
00357 #endif