Adaptagrams
linesegment.h
1 /*
2  * vim: ts=4 sw=4 et tw=0 wm=0
3  *
4  * libvpsc - A solver for the problem of Variable Placement with
5  * Separation Constraints.
6  *
7  * Copyright (C) 2005-2008 Monash University
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  * See the file LICENSE.LGPL distributed with the library.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18  *
19 */
20 
22 //
23 // 2D Line Segment Intersection example
24 // Implementation of the theory provided by Paul Bourke
25 //
26 // Written by Damian Coventry
27 // Tuesday, 9 January 2007
28 //
30 
31 #ifndef VPSC_LINESEGMENT_H
32 #define VPSC_LINESEGMENT_H
33 
34 namespace linesegment {
35 class Vector
36 {
37 public:
38  double x_, y_;
39 
40  Vector(double f = 0.0f)
41  : x_(f), y_(f) {}
42 
43  Vector(double x, double y)
44  : x_(x), y_(y) {}
45 };
46 
47 class LineSegment
48 {
49 public:
50  Vector begin_;
51  Vector end_;
52 
53  LineSegment(const Vector& begin, const Vector& end)
54  : begin_(begin), end_(end) {}
55 
56  enum IntersectResult { PARALLEL, COINCIDENT, NOT_INTERSECTING, INTERSECTING };
57 
58  IntersectResult Intersect(const LineSegment& other_line, Vector& intersection)
59  {
60  double dx1=end_.x_ - begin_.x_;
61  double dy1=end_.y_ - begin_.y_;
62  double dx2=other_line.end_.x_ - other_line.begin_.x_;
63  double dy2=other_line.end_.y_ - other_line.begin_.y_;
64 
65  double denom = dy2 * dx1 - dy1 * dx2;
66 
67  double nume_a = dx2 * (begin_.y_ - other_line.begin_.y_) -
68  dy2 * (begin_.x_ - other_line.begin_.x_);
69 
70  double nume_b = dx1 * (begin_.y_ - other_line.begin_.y_) -
71  dy1 * (begin_.x_ - other_line.begin_.x_);
72 
73  if(denom == 0.0f)
74  {
75  if(nume_a == 0.0f && nume_b == 0.0f)
76  {
77  return COINCIDENT;
78  }
79  return PARALLEL;
80  }
81 
82  double ua = nume_a / denom;
83  double ub = nume_b / denom;
84 
85  if(ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f)
86  {
87  // Get the intersection point.
88  intersection.x_ = begin_.x_ + ua*dx1;
89  intersection.y_ = begin_.y_ + ua*dy1;
90 
91  return INTERSECTING;
92  }
93 
94  return NOT_INTERSECTING;
95  }
96 };
97 
98 void DoLineSegmentIntersection(const Vector& p0, const Vector& p1, const Vector& p2, const Vector& p3)
99 {
100  LineSegment linesegment0(p0, p1);
101  LineSegment linesegment1(p2, p3);
102 
103  Vector intersection;
104 
105  std::cout << "Line Segment 0: (" << p0.x_ << ", " << p0.y_ << ") to (" << p1.x_ << ", " << p1.y_ << ")\n"
106  << "Line Segment 1: (" << p2.x_ << ", " << p2.y_ << ") to (" << p3.x_ << ", " << p3.y_ << ")\n";
107 
108  switch(linesegment0.Intersect(linesegment1, intersection))
109  {
110  case LineSegment::PARALLEL:
111  std::cout << "The lines are parallel\n\n";
112  break;
113  case LineSegment::COINCIDENT:
114  std::cout << "The lines are coincident\n\n";
115  break;
116  case LineSegment::NOT_INTERSECTING:
117  std::cout << "The lines do not intersect\n\n";
118  break;
119  case LineSegment::INTERSECTING:
120  std::cout << "The lines intersect at (" << intersection.x_ << ", " << intersection.y_ << ")\n\n";
121  break;
122  }
123 }
124 
125 int test()
126 {
127  DoLineSegmentIntersection(Vector(0.0f, 0.0f), Vector(5.0f, 5.0f), Vector(5.0f, 0.0f), Vector(0.0f, 5.0f));
128  DoLineSegmentIntersection(Vector(1.0f, 3.0f), Vector(9.0f, 3.0f), Vector(0.0f, 1.0f), Vector(2.0f, 1.0f));
129  DoLineSegmentIntersection(Vector(1.0f, 5.0f), Vector(6.0f, 8.0f), Vector(0.5f, 3.0f), Vector(6.0f, 4.0f));
130  DoLineSegmentIntersection(Vector(1.0f, 1.0f), Vector(3.0f, 8.0f), Vector(0.5f, 2.0f), Vector(4.0f, 7.0f));
131  DoLineSegmentIntersection(Vector(1.0f, 2.0f), Vector(3.0f, 6.0f), Vector(2.0f, 4.0f), Vector(4.0f, 8.0f));
132  DoLineSegmentIntersection(Vector(3.5f, 9.0f), Vector(3.5f, 0.5f), Vector(3.0f, 1.0f), Vector(9.0f, 1.0f));
133  DoLineSegmentIntersection(Vector(2.0f, 3.0f), Vector(7.0f, 9.0f), Vector(1.0f, 2.0f), Vector(5.0f, 7.0f));
134  return 0;
135 }
136 } // namespace linesegment
137 
138 #endif // VPSC_LINESEGMENT_H
Point Vector
A vector, represented by the Point class.
Definition: geomtypes.h:128
Definition: linesegment.h:34