Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members

line2d.h

Go to the documentation of this file.
00001 // Copyright (C) 2002-2008 Nikolaus Gebhardt
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
00004 
00005 #ifndef __IRR_LINE_2D_H_INCLUDED__
00006 #define __IRR_LINE_2D_H_INCLUDED__
00007 
00008 #include "irrTypes.h"
00009 #include "vector2d.h"
00010 
00011 namespace irr
00012 {
00013 namespace core
00014 {
00015 
00017 template <class T>
00018 class line2d
00019 {
00020         public:
00022                 line2d() : start(0,0), end(1,1) {}
00024                 line2d(T xa, T ya, T xb, T yb) : start(xa, ya), end(xb, yb) {}
00026                 line2d(const vector2d<T>& start, const vector2d<T>& end) : start(start), end(end) {}
00028                 line2d(const line2d<T>& other) : start(other.start), end(other.end) {}
00029 
00030                 // operators
00031 
00032                 line2d<T> operator+(const vector2d<T>& point) const { return line2d<T>(start + point, end + point); }
00033                 line2d<T>& operator+=(const vector2d<T>& point) { start += point; end += point; return *this; }
00034 
00035                 line2d<T> operator-(const vector2d<T>& point) const { return line2d<T>(start - point, end - point); }
00036                 line2d<T>& operator-=(const vector2d<T>& point) { start -= point; end -= point; return *this; }
00037 
00038                 bool operator==(const line2d<T>& other) const
00039                 { return (start==other.start && end==other.end) || (end==other.start && start==other.end);}
00040                 bool operator!=(const line2d<T>& other) const
00041                 { return !(start==other.start && end==other.end) || (end==other.start && start==other.end);}
00042 
00043                 // functions
00045                 void setLine(const T& xa, const T& ya, const T& xb, const T& yb){start.set(xa, ya); end.set(xb, yb);}
00047                 void setLine(const vector2d<T>& nstart, const vector2d<T>& nend){start.set(nstart); end.set(nend);}
00049                 void setLine(const line2d<T>& line){start.set(line.start); end.set(line.end);}
00050 
00052 
00053                 f64 getLength() const { return start.getDistanceFrom(end); }
00054 
00056 
00057                 T getLengthSQ() const { return start.getDistanceFromSQ(end); }
00058 
00060 
00061                 vector2d<T> getMiddle() const
00062                 {
00063                         return (start + end) * (T)0.5;
00064                 }
00065 
00067 
00068                 vector2d<T> getVector() const { return vector2d<T>(start.X - end.X, start.Y - end.Y); }
00069 
00071 
00075                 bool intersectWith(const line2d<T>& l, vector2d<T>& out) const
00076                 {
00077                         bool found=false;
00078 
00079                         f32 a1,a2,b1,b2;
00080 
00081                         // calculate slopes, deal with infinity
00082                         if (end.X-start.X == 0)
00083                                 b1 = (f32)1e+10;
00084                         else
00085                                 b1 = (end.Y-start.Y)/(end.X-start.X);
00086                         if (l.end.X-l.start.X == 0)
00087                                 b2 = (f32)1e+10;
00088                         else
00089                                 b2 = (l.end.Y-l.start.Y)/(l.end.X-l.start.X);
00090 
00091                         // calculate position
00092                         a1 = start.Y   - b1 * start.X;
00093                         a2 = l.start.Y - b2 * l.start.X;
00094                         out.X = - (a1-a2)/(b1-b2);
00095                         out.Y = a1 + b1*out.X;
00096 
00097                         // did the lines cross?
00098                         if ((start.X-out.X) *(out.X-end.X) >= -ROUNDING_ERROR_32 &&
00099                                 (l.start.X-out.X)*(out.X-l.end.X)>= -ROUNDING_ERROR_32 &&
00100                                 (start.Y-out.Y)  *(out.Y-end.Y)  >= -ROUNDING_ERROR_32 &&
00101                                 (l.start.Y-out.Y)*(out.Y-l.end.Y)>= -ROUNDING_ERROR_32 )
00102                         {
00103                                 found = true;
00104                         }
00105                         return found;
00106                 }
00107 
00109 
00110                 vector2d<T> getUnitVector() const
00111                 {
00112                         T len = (T)(1.0 / getLength());
00113                         return vector2d<T>((end.X - start.X) * len, (end.Y - start.Y) * len);
00114                 }
00115 
00117 
00119                 f64 getAngleWith(const line2d<T>& l) const
00120                 {
00121                         vector2d<T> vect = getVector();
00122                         vector2d<T> vect2 = l.getVector();
00123                         return vect.getAngleWith(vect2);
00124                 }
00125 
00127 
00129                 T getPointOrientation(const vector2d<T>& point) const
00130                 {
00131                         return ( (end.X - start.X) * (point.Y - start.Y) -
00132                                         (point.X - start.X) * (end.Y - start.Y) );
00133                 }
00134 
00136 
00137                 bool isPointOnLine(const vector2d<T>& point) const
00138                 {
00139                         T d = getPointOrientation(point);
00140                         return (d == 0 && point.isBetweenPoints(start, end));
00141                 }
00142 
00144 
00145                 bool isPointBetweenStartAndEnd(const vector2d<T>& point) const
00146                 {
00147                         return point.isBetweenPoints(start, end);
00148                 }
00149 
00151                 vector2d<T> getClosestPoint(const vector2d<T>& point) const
00152                 {
00153                         vector2d<T> c = point - start;
00154                         vector2d<T> v = end - start;
00155                         T d = (T)v.getLength();
00156                         v /= d;
00157                         T t = v.dotProduct(c);
00158 
00159                         if (t < (T)0.0) return start;
00160                         if (t > d) return end;
00161 
00162                         v *= t;
00163                         return start + v;
00164                 }
00165 
00167                 vector2d<T> start;
00169                 vector2d<T> end;
00170 };
00171 
00173         typedef line2d<f32> line2df;
00175         typedef line2d<s32> line2di;
00176 
00177 } // end namespace core
00178 } // end namespace irr
00179 
00180 #endif
00181 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2008 by Nikolaus Gebhardt. Generated on Sun Sep 21 08:57:43 2008 by Doxygen (1.4.2)