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

# line2d.h

Go to the documentation of this file.

    00001 // Copyright (C) 2002-2009 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>(end.X - start.X, end.Y - start.Y); }
    00069
    00071
    00075                 bool intersectWith(const line2d<T>& l, vector2d<T>& out) const
    00076                 {
    00077                         // Uses the method given at:
    00078                         // http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/
    00079                         const f32 commonDenominator = (l.end.Y - l.start.Y)*(end.X - start.X) -
    00080                                                                                         (l.end.X - l.start.X)*(end.Y - start.Y);
    00081
    00082                         const f32 numeratorA = (l.end.X - l.start.X)*(start.Y - l.start.Y) -
    00083                                                                                         (l.end.Y - l.start.Y)*(start.X -l.start.X);
    00084
    00085                         const f32 numeratorB = (end.X - start.X)*(start.Y - l.start.Y) -
    00086                                                                                         (end.Y - start.Y)*(start.X -l.start.X);
    00087
    00088                         if(equals(commonDenominator, 0.f))
    00089                         {
    00090                                 // The lines are either coincident or parallel
    00091                                 if(equals(numeratorA, 0.f) && equals(numeratorB, 0.f))
    00092                                 {
    00093                                         // Try and find a common endpoint
    00094                                         if(l.start == start || l.end == start)
    00095                                                 out = start;
    00096                                         else if(l.end == end || l.start == end)
    00097                                                 out = end;
    00098                                         else
    00099                                                 // one line is contained in the other, so for lack of a better
    00100                                                 // answer, pick the average of both lines
    00101                                                 out = ((start + end + l.start + l.end) * 0.25f);
    00102
    00103                                         return true; // coincident
    00104                                 }
    00105
    00106                                 return false; // parallel
    00107                         }
    00108
    00109                         // Get the point of intersection on this line, checking that
    00110                         // it is within the line segment.
    00111                         const f32 uA = numeratorA / commonDenominator;
    00112                         if(uA < 0.f || uA > 1.f)
    00113                                 return false; // Outside the line segment
    00114
    00115                         const f32 uB = numeratorB / commonDenominator;
    00116                         if(uB < 0.f || uB > 1.f)
    00117                                 return false; // Outside the line segment
    00118
    00119                         // Calculate the intersection point.
    00120                         out.X = start.X + uA * (end.X - start.X);
    00121                         out.Y = start.Y + uA * (end.Y - start.Y);
    00122                         return true;
    00123                 }
    00124
    00126
    00127                 vector2d<T> getUnitVector() const
    00128                 {
    00129                         T len = (T)(1.0 / getLength());
    00130                         return vector2d<T>((end.X - start.X) * len, (end.Y - start.Y) * len);
    00131                 }
    00132
    00134
    00136                 f64 getAngleWith(const line2d<T>& l) const
    00137                 {
    00138                         vector2d<T> vect = getVector();
    00139                         vector2d<T> vect2 = l.getVector();
    00140                         return vect.getAngleWith(vect2);
    00141                 }
    00142
    00144
    00146                 T getPointOrientation(const vector2d<T>& point) const
    00147                 {
    00148                         return ( (end.X - start.X) * (point.Y - start.Y) -
    00149                                         (point.X - start.X) * (end.Y - start.Y) );
    00150                 }
    00151
    00153
    00154                 bool isPointOnLine(const vector2d<T>& point) const
    00155                 {
    00156                         T d = getPointOrientation(point);
    00157                         return (d == 0 && point.isBetweenPoints(start, end));
    00158                 }
    00159
    00161
    00162                 bool isPointBetweenStartAndEnd(const vector2d<T>& point) const
    00163                 {
    00164                         return point.isBetweenPoints(start, end);
    00165                 }
    00166
    00168                 vector2d<T> getClosestPoint(const vector2d<T>& point) const
    00169                 {
    00170                         vector2d<T> c = point - start;
    00171                         vector2d<T> v = end - start;
    00172                         T d = (T)v.getLength();
    00173                         v /= d;
    00174                         T t = v.dotProduct(c);
    00175
    00176                         if (t < (T)0.0) return start;
    00177                         if (t > d) return end;
    00178
    00179                         v *= t;
    00180                         return start + v;
    00181                 }
    00182
    00184                 vector2d<T> start;
    00186                 vector2d<T> end;
    00187 };
    00188
    00190         typedef line2d<f32> line2df;
    00192         typedef line2d<s32> line2di;
    00193
    00194 } // end namespace core
    00195 } // end namespace irr
    00196
    00197 #endif
    00198

| The Irrlicht Engine Documentation © 2003-2009 by Nikolaus Gebhardt. Generated on Sun Jan 10 09:24:04 2010 by Doxygen (1.5.6)