JNR
laLine2.h
1 /*
2 
3 Jump'n'Run Engine
4 http://www.atanaslaskov.com/jnr/
5 
6 BSD LICENSE
7 Copyright (c) 2007-2013, Atanas Laskov
8 All rights reserved.
9 
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are met:
12 1. Redistributions of source code must retain the above copyright notice,
13 this list of conditions and the following disclaimer.
14 2. Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation
16 and/or other materials provided with the distribution.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL ATANAS LASKOV BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 */
29 
30 #ifndef M_LINE_H
31 #define M_LINE_H
32 
34 
35 
37 //
39 
40 class laLine2
41 {
42 public:
45 
47 
48  laLine2(void) {}
49  laLine2(const laPoint2 &a, const laPoint2 &b){ build(a,b); }
50 
52  inline void build(const laPoint2 &a, const laPoint2 &b) {
53  origin = a; vector = b - a;
54  }
55 
57  inline void build_v(const laPoint2 &a, const laPoint2 &v) {
58  origin = a; vector = v;
59  }
61 
63 
64  inline double lenght() const{
65  return vector.lenght();
66  }
67 
69  inline double lenght_sq() const{
70  return vector.lenght_sq();
71  }
73 
75 
76 
78  inline laPoint2 end() const { return origin + vector; };
79 
81  inline void at(double k, laPoint2 *ppt) const{
82  *ppt = origin + vector*k;
83  }
84 
86  inline const laPoint2 at(double k) const{
87  return origin + vector*k ;
88  };
89 
90  inline double getX(double k) const{ return k*vector.x() + origin.x(); }
91  inline double getY(double k) const{ return k*vector.y() + origin.y(); }
92 
93 
95 
96  inline double getK( const laPoint2 &pt ) const{
97  return ( M_ABS(vector.x())>M_ABS(vector.y()) ) ? getK_atX(pt.x()) : getK_atY(pt.y());
98  };
99 
100  inline double getK_atX(double x) const{
101  //ASSERT(M_ABS(vector.x())!=0, "x componet too small");
102  return (x - origin.x()) / vector.x();
103  };
104 
105  inline double getK_atY(double y) const{
106  //ASSERT(M_ABS(vector.y())!=0, "y componet too small");
107  return (y - origin.y() ) / vector.y();
108  };
110 
112  //
113  inline laPoint2 normal(int direction=1) const{
114  laPoint2 normal(-direction*vector.y(), +direction*vector.x());
115  normal.normalize();
116 
117  return normal;
118  }
119 
122  //
123  inline int direction(const laPoint2 &pt) const {
124  PROFILE_COL(laPoint2_direction);
125  double k;// = getK(pt.x());
126 
127  if( M_ABS( vector.x() )>M_ABS( vector.y() ) )
128  {
129  k = getK_atX( pt.x() );
130  return ( getY(k) > pt.y() ) ? +1 : -1;
131  }
132  else
133  {
134  k = getK_atY( pt.y() );
135  return ( getX(k) > pt.x() ) ? +1 : -1;
136  }
137  }
138 
140  //
141  inline M_BOOL onSameSide(const laPoint2 &a, const laPoint2 &b) const{
142  return ( direction(a) == direction(b) );
143  }
144 
148  //
149  inline M_BOOL intersection(const laLine2 &ln, double *k, double *k_ln) const {
150  //PROFILE_COL(laLine2_intersection);
151  //ASSERT(k && k_ln, "Nil k or k_ln recepient ptr");
152  double dCross1 = vector.cross( ln.vector );
153 
154  if( M_ABS(dCross1) < 0.00001) return M_FALSE; // parallel vectors?
155 
156  // ln.origin.cross( ln.vector ) - origin.cross( ln.vec )
157  *k = ( (ln.origin.x() - origin.x())*ln.vector.y() + (origin.y() - ln.origin.y())*ln.vector.x() ) / dCross1;
158  *k_ln = ln.getK( at(*k) );
159 
160  return M_TRUE;
161  }
162 
164  //
165  inline double distance( laPoint2 &pt ) const {
166  laLine2 ln(pt, pt + normal());
167  double k, k_ln;
168 
169  intersection(ln, &k, &k_ln);
170  //ASSERT(intersection(ln, &k, &k_ln), "Line and normal can't be parallel, something's wrong.");
171  laPoint2 v = at(k) - pt;
172 
173  return v.lenght();
174  }
175 
177  //
178  inline double distance_sq( laPoint2 &pt ) const {
179  laLine2 ln(pt, pt + normal());
180  double k, k_ln;
181 
182  intersection(ln, &k, &k_ln);
183  //ASSERT(intersection(ln, &k, &k_ln), "Line and normal can't be parallel, something's wrong.");
184  laPoint2 v = at(k) - pt;
185 
186  return v.lenght_sq();
187  }
188 
190  void draw(class laRenderer* r, laPoint2 &pos);
191 
193  static void drawLine2s(laLine2 *arLines, unsigned n, class laRenderer* r, laPoint2 &pos);
194 };
196 #endif //#ifndef M_LINE_H
void draw(class laRenderer *r, laPoint2 &pos)
Draw the line ( primarily for debug purposes )
Definition: laLine2.cpp:49
M_BOOL onSameSide(const laPoint2 &a, const laPoint2 &b) const
Check if two points are on the same side of the line.
Definition: laLine2.h:141
void build(const laPoint2 &a, const laPoint2 &b)
Build a line from two end-points.
Definition: laLine2.h:52
double lenght_sq() const
Squared root of segment lenght.
Definition: laLine2.h:69
int direction(const laPoint2 &pt) const
Definition: laLine2.h:123
void build_v(const laPoint2 &a, const laPoint2 &v)
Build a line from an end-point and a vector.
Definition: laLine2.h:57
2D Point
Definition: laPoint_novec.h:41
M_BOOL intersection(const laLine2 &ln, double *k, double *k_ln) const
Definition: laLine2.h:149
laPoint2 end() const
Get the end-point.
Definition: laLine2.h:78
void at(double k, laPoint2 *ppt) const
Get point at 1/k lenght (returns in user-specified pointer)
Definition: laLine2.h:81
laPoint2 vector
Vector ( not normalized, so k = [0;1] traces the whole line segment )
Definition: laLine2.h:44
double distance(laPoint2 &pt) const
Compute the distance between a point and the line.
Definition: laLine2.h:165
2D line segment
Definition: laLine2.h:40
laPoint2 normal(int direction=1) const
Get a perpendicular vector of lenght 1 (normal of the line segment)
Definition: laLine2.h:113
#define M_ABS(a)
Return abs(a)
double getX(double k) const
Get X at 1/k lenght.
Definition: laLine2.h:90
Virtual interface for the Engine graphics renderer.
Definition: laRenderer.h:98
laPoint2 origin
Point of origin.
Definition: laLine2.h:43
static void drawLine2s(laLine2 *arLines, unsigned n, class laRenderer *r, laPoint2 &pos)
Draw many lines ( primarily for debug purposes )
Definition: laLine2.cpp:55
double getY(double k) const
Get Y at 1/k lenght.
Definition: laLine2.h:91
double distance_sq(laPoint2 &pt) const
Compute the square of the distance between a point and the line.
Definition: laLine2.h:178