summaryrefslogtreecommitdiff
path: root/src/base/GeomHelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/GeomHelper.cpp')
-rw-r--r--src/base/GeomHelper.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/base/GeomHelper.cpp b/src/base/GeomHelper.cpp
new file mode 100644
index 0000000..da167ad
--- /dev/null
+++ b/src/base/GeomHelper.cpp
@@ -0,0 +1,178 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GeomHelper.h"
+
+#include <math.h>
+#include <iostream>
+
+using namespace std;
+
+namespace avg {
+
+LineSegment::LineSegment(const glm::vec2& pt0, const glm::vec2& pt1)
+ : p0(pt0),
+ p1(pt1)
+{
+}
+
+bool LineSegment::isPointOver(const glm::vec2& pt)
+{
+ glm::vec2 c = pt - p0;
+ glm::vec2 v = (p1 - p0);
+ float d = glm::length(v);
+ v /= d;
+ float t = glm::dot(v, c);
+
+ return (t >= 0 && t <= d);
+}
+
+// Code adapted from Antonio, Franklin, "Faster Line Segment Intersection,"
+// Graphics Gems III (David Kirk, ed.), Academic Press, pp. 199-202, 1992.
+bool lineSegmentsIntersect(const LineSegment& l0, const LineSegment& l1)
+{
+ float xdiff0 = l0.p1.x-l0.p0.x;
+ float xdiff1 = l1.p0.x-l1.p1.x;
+
+ float x1lo, x1hi;
+
+ /* X bound box test*/
+ if (xdiff0 < 0) {
+ x1lo=l0.p1.x;
+ x1hi=l0.p0.x;
+ } else {
+ x1hi=l0.p1.x;
+ x1lo=l0.p0.x;
+ }
+ if (xdiff1 > 0) {
+ if (x1hi < l1.p1.x || l1.p0.x < x1lo) {
+ return false;
+ }
+ } else {
+ if (x1hi < l1.p0.x || l1.p1.x < x1lo) {
+ return false;
+ }
+ }
+
+ float ydiff0 = l0.p1.y-l0.p0.y;
+ float ydiff1 = l1.p0.y-l1.p1.y;
+
+ float y1lo, y1hi;
+
+ /* Y bound box test*/
+ if (ydiff0 < 0) {
+ y1lo=l0.p1.y;
+ y1hi=l0.p0.y;
+ } else {
+ y1hi=l0.p1.y;
+ y1lo=l0.p0.y;
+ }
+ if (ydiff1 > 0) {
+ if (y1hi < l1.p1.y || l1.p0.y < y1lo) {
+ return false;
+ }
+ } else {
+ if (y1hi < l1.p0.y || l1.p1.y < y1lo) {
+ return false;
+ }
+ }
+
+ float Cx = l0.p0.x-l1.p0.x;
+ float Cy = l0.p0.y-l1.p0.y;
+ float d = ydiff1*Cx - xdiff1*Cy; /* alpha numerator*/
+ float f = ydiff0*xdiff1 - xdiff0*ydiff1; /* both denominator*/
+ if (f > 0) { /* alpha tests*/
+ if (d < 0 || d > f) {
+ return false;
+ }
+ } else {
+ if (d > 0 || d < f) {
+ return false;
+ }
+ }
+
+ float e = xdiff0*Cy - ydiff0*Cx; /* beta numerator*/
+ if(f > 0) { /* beta tests*/
+ if (e < 0 || e > f) {
+ return false;
+ }
+ } else {
+ if (e > 0 || e < f) {
+ return false;
+ }
+ }
+
+ if (f == 0) {
+ // Theoretically, lines could still intersect in this case, but we don't care
+ // because given numerical inaccuracies, the result is random anyway :-).
+ return false;
+ }
+
+// /*compute intersection coordinates*/
+// float num = d*xdiff0; /* numerator */
+// offset = SAME_SIGNS(num,f) ? f/2 : -f/2; /* round direction*/
+// *x = x1 + (num+offset) / f; /* intersection x */
+//
+// num = d*ydiff0;
+// offset = SAME_SIGNS(num,f) ? f/2 : -f/2;
+// *y = y1 + (num+offset) / f; /* intersection y */
+
+ return true;
+}
+
+// Original code from:
+// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html.
+// Precomputing a bounding box for the polygon would speed this up a lot,
+// but the function hasn't shown up on any profiles so far.
+bool pointInPolygon(const glm::vec2& pt, const vector<glm::vec2>& poly)
+{
+ if (poly.size() < 3) {
+ return false;
+ }
+ bool bPtInPoly = false;
+ for (unsigned i = 0, j = poly.size()-1; i < poly.size(); j = i++) {
+ if (((poly[i].y > pt.y) != (poly[j].y > pt.y)) &&
+ (pt.x < (poly[j].x-poly[i].x)*(pt.y-poly[i].y) / (poly[j].y-poly[i].y)
+ +poly[i].x))
+ {
+ bPtInPoly = !bPtInPoly;
+ }
+ }
+ return bPtInPoly;
+}
+
+glm::vec2 getLineLineIntersection(const glm::vec2& p1, const glm::vec2& v1,
+ const glm::vec2& p2, const glm::vec2& v2)
+{
+ float denom = v2.y*v1.x-v2.x*v1.y;
+ if (fabs(denom) < 0.0000001) {
+ // If the lines are parallel or coincident, we just return p2!
+ return p2;
+ }
+ float numer = v2.x*(p1.y-p2.y) - v2.y*(p1.x-p2.x);
+ float ua = numer/denom;
+
+ return p1+ua*v1;
+
+}
+
+
+}