1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
// helper functions
template <typename T> min(T a, T b) { return a < b ? a : b; }
template <typename T> max(T a, T b) { return a < b ? b : a; }
// Classes
struct Point
{
// Members
double x;
double y;
// Constructor
Point (double _x, double _y) : x(_x), y(_y) {}
};
class LineSegment
{
private:
// Members
double m; // y = m * x + b
double b;
Point p1; // Bounds of the line segment
Point p2; // Bounds of the line segment
// Helpers
double UpperBound() { return p1.x > p2.x ? p1.x : p2.x; }
double LowerBound() { return p1.x > p2.x ? p2.x : p1.x; }
public:
// Constructor
LineSegment (Point &_p1, Point &_p2) // Create a line from 2 points;
: p1(_p1), p2(_p2)
{
m = (_p1.y - _p2.y) / (_p1.x - _p2.x);
b = _p1.y - m * _p1.x;
}
// Methods
bool intersects(LineSegment &comp) // Checks if two lines intersect within the bounds
{
if (this->UpperBound() < comp.LowerBound()) return false; // 'this' helps clarify who the method belongs to.
if (this->LowerBound() > comp.UpperBound()) return false;
double lowerXbound = max(this->LowerBound(), comp.LowerBound());
double upperXbound = min(this->UpperBound(), comp.UpperBound());
double lowerYdiff = (this->m - comp.m) * lowerXbound + (this->b - comp.b); // Finds the difference in Y at the lower bound
double upperYdiff = (this->m - comp.m) * upperXbound + (this->b - comp.b); // Finds the difference in Y at the upper bound
return (lowerYdiff * upperYdiff) < 0; // Checks if the signs are opposite (ie they have crossed)
}
};
class Triangle
{
// Members
LineSegment l1;
LineSegment l2;
LineSegment l3;
public:
// Constructor
Triangle (Point &_p1, Point &_p2, Point &_p3)
: l1(_p1,_p2), l2(_p2,_p3), l3(_p3,_p1)
{ }
// Methods
bool intersects(Triangle &comp) // Checks if two triangles have any intersecting edges
{
if ( l1.intersects(comp.l1) ) return true; // Check all of the line segments
if ( l1.intersects(comp.l2) ) return true;
// if ( l1.intersects(comp.l3) ) return true; // After some checking, I don't actually need to test this line!
if ( l2.intersects(comp.l1) ) return true;
if ( l2.intersects(comp.l2) ) return true;
// if ( l2.intersects(comp.l3) ) return true; // or this one
if ( l3.intersects(comp.l1) ) return true;
if ( l3.intersects(comp.l2) ) return true;
// if ( l3.intersects(comp.l3) ) return true; // or this one :)
return false;
}
};
// Implementation
int main()
{
Point A(1 ,4), B(2,3), C(3.5, 6);
Point D(-3,5), E(5,3), F(4.2,-6);
Triangle t1(A,B,C);
Triangle t2(D,E,F);
if (t1.intersects(t2))
cout << "These intersect";
else
cout << "These do not intersect";
return 0;
}
|