WINDEX
cxy.h
1 
2 #pragma once
3 #include <cfloat>
4 #include <cmath>
5 #include <vector>
6 #include <iostream>
7 
9 class cxy
10 {
11 
12 public:
13  double x;
14  double y;
15 
16  cxy()
17  : x(-DBL_MAX),
18  y(-DBL_MAX)
19  {
20  }
21  cxy(double X, double Y)
22  : x(X), y(Y)
23  {
24  }
25  cxy(const cxy &xy)
26  : x(xy.x), y(xy.y)
27  {
28  }
32  cxy vect(const cxy &other) const
33  {
34  cxy v;
35  v.x = other.x - x;
36  v.y = other.y - y;
37  return v;
38  }
39 
43  double dist2(const cxy &other) const
44  {
45  cxy v = vect(other);
46  return v.x * v.x + v.y * v.y;
47  }
48 
49  // closest point on line to this point, fraction ( point = end1 + t * (end2-end1) )
50  // return t
51  double tclosest(
52  const cxy &end1,
53  const cxy &end2) const
54  {
55  cxy AB = end1.vect(end2);
56  cxy AP = end1.vect(*this);
57  double lAB = AB.x * AB.x + AB.y * AB.y;
58  return (AB.x * AP.x + AB.y * AP.y) / lAB;
59  }
60 
61  // closest point on line segment to this point
62  cxy closest(
63  const cxy &end1,
64  const cxy &end2) const
65  {
66  double t = tclosest(
67  end1, end2);
68  if (t < 0)
69  t = 0;
70  if (t > 1)
71  t = 1;
72  cxy ret(end1.x + t * (end2.x - end1.x),
73  end1.y + t * (end2.y - end1.y));
74  return ret;
75  }
76 
81  double dis2toline(
82  const cxy &end1,
83  const cxy &end2) const
84  {
85  double t = tclosest(end1, end2);
86  if (t < 0)
87  t = 0;
88  if (t > 1)
89  t = 1;
90  cxy AB = end1.vect(end2);
91  cxy closest(
92  end1.x + t * AB.x,
93  end1.y + t * AB.y);
94  return dist2(closest);
95  }
96 
98  bool isInside(const std::vector<cxy> &polygon) const
99  {
100  int c = 0;
101  std::vector<cxy>::const_iterator j = polygon.end() - 1;
102  for (std::vector<cxy>::const_iterator i = polygon.begin();
103  i != polygon.end(); j = i++)
104  {
105  if (((i->y > y) != (j->y > y)) &&
106  (x < (j->x - i->x) * (y - i->y) / (j->y - i->y) + i->x))
107  c = !c;
108  }
109  return (c == 1);
110  }
111 
112  static cxy enclosingWidthHeight(const std::vector<cxy> &polygon)
113  {
114  cxy max, min;
115  for (const cxy &p : polygon)
116  {
117  if (p.x > max.x)
118  max.x = p.x;
119  if (p.y > max.y)
120  max.y = p.y;
121  if (p.x < min.x)
122  min.x = p.x;
123  if (p.y < min.y)
124  min.y = p.y;
125  }
126  static cxy ret;
127  ret.x = max.x - min.x;
128  ret.y = max.y - min.y;
129  return ret;
130  }
131 
138  static bool isIntersection(
139  cxy &p,
140  const cxy &a, const cxy &b,
141  const cxy &c, const cxy &d)
142  {
143 
144  /*
145  https://www.topcoder.com/thrive/articles/Geometry%20Concepts%20part%202:%20%20Line%20Intersection%20and%20its%20Applications
146 
147  Ax+By=C
148 
149  A = y2-y1
150  B = x1-x2
151  C = Ax1+By1
152 
153  */
154  double A1 = b.y - a.y;
155  double B1 = a.x - b.x;
156  double C1 = A1 * a.x + B1 * a.y;
157  double A2 = d.y - c.y;
158  double B2 = c.x - d.x;
159  double C2 = A2 * c.x + B2 * c.y;
160 
173  double det = A1 * B2 - A2 * B1;
174  if (fabs(det) < 0.0001)
175  return false;
176  else
177  {
178  // intersection point of infinite lines
179  p.x = (B2 * C1 - B1 * C2) / det;
180  p.y = (A1 * C2 - A2 * C1) / det;
181 
182  // check segments intersect
183  if (!(std::min(a.x, b.x) <= p.x && p.x <= std::max(a.x, b.x)))
184  return false;
185  if (!(std::min(a.y, b.y) <= p.y && p.y <= std::max(a.y, b.y)))
186  return false;
187  if (!(std::min(c.x, d.x) <= p.x && p.x <= std::max(c.x, d.x)))
188  return false;
189  if (!(std::min(c.y, d.y) <= p.y && p.y <= std::max(c.y, d.y)))
190  return false;
191 
192  return true;
193  }
194  }
195 
196  static bool isIntersect(cxy &p1, cxy &q1, cxy &p2, cxy &q2);
197 
202 
203  static double angle(
204  const cxy &a, const cxy &b,
205  const cxy &c, const cxy &d)
206  {
207  cxy v1 = a.vect(b);
208  cxy v2 = c.vect(d);
209  double dot = v1.x * v2.x + v1.y * v2.y;
210  double det = v1.x * v2.y - v1.y * v2.x;
211  return atan2(det, dot);
212  }
213 
219 
220  static double clockwise(
221  const cxy &a,
222  const cxy &b,
223  const cxy &c)
224  {
225  double ang = cxy::angle(
226  b, a,
227  b, c);
228  // go around the other way
229  if (ang < 0)
230  ang += 6.28;
231  return ang;
232  }
233 
234  bool isValid() const
235  {
236  return ((x > -DBL_MAX + 1) && (y > -DBL_MAX + 1));
237  }
238  void invalidate()
239  {
240  x = -DBL_MAX;
241  y = -DBL_MAX;
242  }
243  void zoom(float ratio)
244  {
245  x *= ratio;
246  y *= ratio;
247  }
248  bool operator==(const cxy &other) const
249  {
250  return x == other.x && y == other.y;
251  }
252  cxy operator+(const cxy &other) const
253  {
254  cxy ret(*this);
255  ret.x += other.x;
256  ret.y += other.y;
257  return ret;
258  }
259  cxy operator-(const cxy &other) const
260  {
261  cxy ret(*this);
262  ret.x -= other.x;
263  ret.y -= other.y;
264  return ret;
265  }
266  cxy &operator*=(float s)
267  {
268  x *= s;
269  y *= s;
270  return *this;
271  }
272  cxy &operator*=(const cxy &other)
273  {
274  x *= other.x;
275  y *= other.y;
276  return *this;
277  }
278  cxy &operator+=(const cxy &other)
279  {
280  x += other.x;
281  y += other.y;
282  return *this;
283  }
284  cxy &operator/=(float s)
285  {
286  x /= s;
287  y /= s;
288  return *this;
289  }
290  friend std::ostream &operator<<(std::ostream &os, cxy p)
291  {
292  os << "(" << p.x << "," << p.y << ")";
293  return os;
294  }
295 };
297 class cxyz
298 {
299 public:
300  double x, y, z;
301 
302  cxyz()
303  : x(-DBL_MAX),
304  y(-DBL_MAX),
305  z(-DBL_MAX)
306  {
307  }
308  cxyz(double X, double Y, double Z)
309  : x(X), y(Y), z(Z)
310  {
311  }
312 
316  cxyz vect(const cxyz &other) const
317  {
318  return cxyz(
319  other.x - x,
320  other.y - y,
321  other.z - z);
322  }
323 
324  static cxyz plane(
325  const cxyz &p0,
326  const cxyz &p1,
327  const cxyz &p2)
328  {
329  cxyz p01 = p0.vect(p1);
330  cxyz p02 = p0.vect(p2);
331  return cxyz(
332  p0.x + p01.x + p02.x,
333  p0.y + p01.y + p02.y,
334  p0.z + p01.z + p02.z);
335  }
336 
337  cxyz cross(const cxyz &other)
338  {
339  return cxyz(
340  y * other.z - z * other.y,
341  z * other.x - x * other.z,
342  x * other.y - y * other.z);
343  }
344 
345  double dot(const cxyz &other)
346  {
347  return x * other.x +
348  y * other.y +
349  z * other.z;
350  }
351 
358 
360  const cxyz &la, const cxyz &lb,
361  const cxyz &p0, const cxyz &p1, const cxyz &p2)
362  {
363  cxyz crossall = p0.vect(p1).cross(p0.vect(p2));
364  cxyz crossu = p0.vect(p2).cross(lb.vect(la));
365  cxyz crossv = lb.vect(la).cross(p0.vect(p2));
366  cxyz lap0(la.x - p0.x, la.y - p0.y, la.z - p0.x);
367  double divisor = lb.vect(la).dot(crossall);
368  double t = crossall.dot(lap0) / divisor;
369  double u = crossu.dot(lap0) / divisor;
370  double v = crossv.dot(lap0) / divisor;
371 
372  // check that line intersects triangle
373  if (t >= 0 && t <= 1)
374  if (u >= 0 && u <= 1)
375  if (v >= 0 && v <= 1)
376  if (u + v <= 1)
377 
378  return cxyz(
379  la.x + t * (lb.x - la.x),
380  la.y + t * (lb.y - la.y),
381  la.z + t * (lb.z - la.z));
382 
383  return cxyz();
384  }
385  bool operator==(const cxyz &other) const
386  {
387  return x == other.x && y == other.y && z == other.z;
388  }
389 };
2D point or vector
Definition: cxy.h:10
static double clockwise(const cxy &a, const cxy &b, const cxy &c)
clockwise turn going from a to b to c, radians
Definition: cxy.h:220
static bool isIntersection(cxy &p, const cxy &a, const cxy &b, const cxy &c, const cxy &d)
true if line segments intersect
Definition: cxy.h:138
static double angle(const cxy &a, const cxy &b, const cxy &c, const cxy &d)
angle between line segments, radians
Definition: cxy.h:203
double dist2(const cxy &other) const
distance squared from this point to other
Definition: cxy.h:43
cxy vect(const cxy &other) const
vector from this point to other
Definition: cxy.h:32
double dis2toline(const cxy &end1, const cxy &end2) const
distance squared from this point to nearest point on line segment
Definition: cxy.h:81
bool isInside(const std::vector< cxy > &polygon) const
true if point inside polygon
Definition: cxy.h:98
3D point or vector
Definition: cxy.h:298
cxyz vect(const cxyz &other) const
vector from this point to other
Definition: cxy.h:316
static cxyz intersectLineTriangle(const cxyz &la, const cxyz &lb, const cxyz &p0, const cxyz &p1, const cxyz &p2)
intersection point between line and triangle
Definition: cxy.h:359