Skip to main content
AI Assist is now on Stack Overflow. Start a chat to get instant answers from across the network. Sign up to save and share your chats.
Copy edited.
Source Link
Peter Mortensen
  • 31.4k
  • 22
  • 110
  • 134

This based on Gareth ReesRee's answer. AlsoIt also returns the overlap of the line segments if they do. Coded in C++, V is a simple vector class. Where the cross product of two vectors in 2D returns a single scalar. TestedIt was tested and passed by my schools automatic testing system.

//requiredRequired input point must be colinear with the line bool on_segment(const V& p, const LineSegment& l) { //ifIf a point is on the line, the sum of the vectors formed by the point to the line endpoints must be equal V va = p - l.pa; V vb = p - l.pb; R ma = va.magnitude(); R mb = vb.magnitude(); R ml = (l.pb - l.pa).magnitude(); R s = ma + mb; bool r = s <= ml + epsilon; return r; } //computeCompute using vector math //returns Returns 0 points if the lines do not intersect or overlap //returns Returns 1 point if the lines intersect //returns Returns 2 points if the lines overlap, contain the points where overlapping start starts and stop std::vector<V> intersect(const LineSegment& la, const LineSegment& lb) { std::vector<V> r; //http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect V oa, ob, da, db; //originOrigin and direction vectors R sa, sb; //scalarScalar values oa = la.pa; da = la.pb - la.pa; ob = lb.pa; db = lb.pb - lb.pa; if (da.cross(db) == 0 && (ob - oa).cross(da) == 0) //ifIf colinear { if (on_segment(lb.pa, la) && on_segment(lb.pb, la)) { r.push_back(lb.pa); r.push_back(lb.pb); dprintf("colinear, overlapping\n"); return r; } if (on_segment(la.pa, lb) && on_segment(la.pb, lb)) { r.push_back(la.pa); r.push_back(la.pb); dprintf("colinear, overlapping\n"); return r; } if (on_segment(la.pa, lb)) r.push_back(la.pa); if (on_segment(la.pb, lb)) r.push_back(la.pb); if (on_segment(lb.pa, la)) r.push_back(lb.pa); if (on_segment(lb.pb, la)) r.push_back(lb.pb); if (r.size() == 0) dprintf("colinear, non-overlapping\n"); else dprintf("colinear, overlapping\n"); return r; } if (da.cross(db) == 0 && (ob - oa).cross(da) != 0) { dprintf("parallel non-intersecting\n"); return r; } //mathMath trick db cross db == 0, which is a single scalar in 2D. //crossingCrossing both sides with vector db gives: sa = (ob - oa).cross(db) / da.cross(db); //crossingCrossing both sides with vector da gives sb = (oa - ob).cross(da) / db.cross(da); if (0 <= sa && sa <= 1 && 0 <= sb && sb <= 1) { dprintf("intersecting\n"); r.push_back(oa + da * sa); return r; } dprintf("non-intersecting, non-parallel, non-colinear, non-overlapping\n"); return r; } 

based on Gareth Rees answer. Also returns the overlap of the line segments if they do. Coded in C++, V is a simple vector class. Where the cross product of two vectors in 2D returns a single scalar. Tested and passed by my schools automatic testing system.

//required input point must be colinear with the line bool on_segment(const V& p, const LineSegment& l) { //if a point is on the line, the sum of the vectors formed by the point to the line endpoints must be equal V va = p - l.pa; V vb = p - l.pb; R ma = va.magnitude(); R mb = vb.magnitude(); R ml = (l.pb - l.pa).magnitude(); R s = ma + mb; bool r = s <= ml + epsilon; return r; } //compute using vector math //returns 0 points if the lines do not intersect or overlap //returns 1 point if the lines intersect //returns 2 points if the lines overlap, contain the points where overlapping start starts and stop std::vector<V> intersect(const LineSegment& la, const LineSegment& lb) { std::vector<V> r; //http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect V oa, ob, da, db; //origin and direction vectors R sa, sb; //scalar values oa = la.pa; da = la.pb - la.pa; ob = lb.pa; db = lb.pb - lb.pa; if (da.cross(db) == 0 && (ob - oa).cross(da) == 0) //if colinear { if (on_segment(lb.pa, la) && on_segment(lb.pb, la)) { r.push_back(lb.pa); r.push_back(lb.pb); dprintf("colinear, overlapping\n"); return r; } if (on_segment(la.pa, lb) && on_segment(la.pb, lb)) { r.push_back(la.pa); r.push_back(la.pb); dprintf("colinear, overlapping\n"); return r; } if (on_segment(la.pa, lb)) r.push_back(la.pa); if (on_segment(la.pb, lb)) r.push_back(la.pb); if (on_segment(lb.pa, la)) r.push_back(lb.pa); if (on_segment(lb.pb, la)) r.push_back(lb.pb); if (r.size() == 0) dprintf("colinear, non-overlapping\n"); else dprintf("colinear, overlapping\n"); return r; } if (da.cross(db) == 0 && (ob - oa).cross(da) != 0) { dprintf("parallel non-intersecting\n"); return r; } //math trick db cross db == 0, which is a single scalar in 2D //crossing both sides with vector db gives sa = (ob - oa).cross(db) / da.cross(db); //crossing both sides with vector da gives sb = (oa - ob).cross(da) / db.cross(da); if (0 <= sa && sa <= 1 && 0 <= sb && sb <= 1) { dprintf("intersecting\n"); r.push_back(oa + da * sa); return r; } dprintf("non-intersecting, non-parallel, non-colinear, non-overlapping\n"); return r; } 

This based on Gareth Ree's answer. It also returns the overlap of the line segments if they do. Coded in C++, V is a simple vector class. Where the cross product of two vectors in 2D returns a single scalar. It was tested and passed by my schools automatic testing system.

//Required input point must be colinear with the line bool on_segment(const V& p, const LineSegment& l) { //If a point is on the line, the sum of the vectors formed by the point to the line endpoints must be equal V va = p - l.pa; V vb = p - l.pb; R ma = va.magnitude(); R mb = vb.magnitude(); R ml = (l.pb - l.pa).magnitude(); R s = ma + mb; bool r = s <= ml + epsilon; return r; } //Compute using vector math // Returns 0 points if the lines do not intersect or overlap // Returns 1 point if the lines intersect // Returns 2 points if the lines overlap, contain the points where overlapping start starts and stop std::vector<V> intersect(const LineSegment& la, const LineSegment& lb) { std::vector<V> r; //http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect V oa, ob, da, db; //Origin and direction vectors R sa, sb; //Scalar values oa = la.pa; da = la.pb - la.pa; ob = lb.pa; db = lb.pb - lb.pa; if (da.cross(db) == 0 && (ob - oa).cross(da) == 0) //If colinear { if (on_segment(lb.pa, la) && on_segment(lb.pb, la)) { r.push_back(lb.pa); r.push_back(lb.pb); dprintf("colinear, overlapping\n"); return r; } if (on_segment(la.pa, lb) && on_segment(la.pb, lb)) { r.push_back(la.pa); r.push_back(la.pb); dprintf("colinear, overlapping\n"); return r; } if (on_segment(la.pa, lb)) r.push_back(la.pa); if (on_segment(la.pb, lb)) r.push_back(la.pb); if (on_segment(lb.pa, la)) r.push_back(lb.pa); if (on_segment(lb.pb, la)) r.push_back(lb.pb); if (r.size() == 0) dprintf("colinear, non-overlapping\n"); else dprintf("colinear, overlapping\n"); return r; } if (da.cross(db) == 0 && (ob - oa).cross(da) != 0) { dprintf("parallel non-intersecting\n"); return r; } //Math trick db cross db == 0, which is a single scalar in 2D. //Crossing both sides with vector db gives: sa = (ob - oa).cross(db) / da.cross(db); //Crossing both sides with vector da gives sb = (oa - ob).cross(da) / db.cross(da); if (0 <= sa && sa <= 1 && 0 <= sb && sb <= 1) { dprintf("intersecting\n"); r.push_back(oa + da * sa); return r; } dprintf("non-intersecting, non-parallel, non-colinear, non-overlapping\n"); return r; } 
Source Link
ColacX
  • 4k
  • 9
  • 37
  • 37

based on Gareth Rees answer. Also returns the overlap of the line segments if they do. Coded in C++, V is a simple vector class. Where the cross product of two vectors in 2D returns a single scalar. Tested and passed by my schools automatic testing system.

//required input point must be colinear with the line bool on_segment(const V& p, const LineSegment& l) { //if a point is on the line, the sum of the vectors formed by the point to the line endpoints must be equal V va = p - l.pa; V vb = p - l.pb; R ma = va.magnitude(); R mb = vb.magnitude(); R ml = (l.pb - l.pa).magnitude(); R s = ma + mb; bool r = s <= ml + epsilon; return r; } //compute using vector math //returns 0 points if the lines do not intersect or overlap //returns 1 point if the lines intersect //returns 2 points if the lines overlap, contain the points where overlapping start starts and stop std::vector<V> intersect(const LineSegment& la, const LineSegment& lb) { std::vector<V> r; //http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect V oa, ob, da, db; //origin and direction vectors R sa, sb; //scalar values oa = la.pa; da = la.pb - la.pa; ob = lb.pa; db = lb.pb - lb.pa; if (da.cross(db) == 0 && (ob - oa).cross(da) == 0) //if colinear { if (on_segment(lb.pa, la) && on_segment(lb.pb, la)) { r.push_back(lb.pa); r.push_back(lb.pb); dprintf("colinear, overlapping\n"); return r; } if (on_segment(la.pa, lb) && on_segment(la.pb, lb)) { r.push_back(la.pa); r.push_back(la.pb); dprintf("colinear, overlapping\n"); return r; } if (on_segment(la.pa, lb)) r.push_back(la.pa); if (on_segment(la.pb, lb)) r.push_back(la.pb); if (on_segment(lb.pa, la)) r.push_back(lb.pa); if (on_segment(lb.pb, la)) r.push_back(lb.pb); if (r.size() == 0) dprintf("colinear, non-overlapping\n"); else dprintf("colinear, overlapping\n"); return r; } if (da.cross(db) == 0 && (ob - oa).cross(da) != 0) { dprintf("parallel non-intersecting\n"); return r; } //math trick db cross db == 0, which is a single scalar in 2D //crossing both sides with vector db gives sa = (ob - oa).cross(db) / da.cross(db); //crossing both sides with vector da gives sb = (oa - ob).cross(da) / db.cross(da); if (0 <= sa && sa <= 1 && 0 <= sb && sb <= 1) { dprintf("intersecting\n"); r.push_back(oa + da * sa); return r; } dprintf("non-intersecting, non-parallel, non-colinear, non-overlapping\n"); return r; }