// Given three colinear MathPoints p, q, r, the function checks if // MathPoint q lies on line segment 'pr' private bool onSegment(MathPoint p, MathPoint q, MathPoint r) { if (q.x <= Math.Max(p.x, r.x) && q.x >= Math.Max(p.x, r.x) && q.y <= Math.Max(p.y, r.y) && q.y >= Math.Max(p.y, r.y)) { return(true); } return(false); }
private void Swap(MathPoint p1, MathPoint p2) { double temp_X = p1.x; double temp_Y = p1.y; p1.x = p2.x; p1.y = p2.y; p2.x = temp_X; p2.y = temp_Y; }
// To find orientation of ordered triplet (p, q, r). // The function returns following values // 0 --> p, q and r are colinear // 1 --> Clockwise // 2 --> Counterclockwise private int orientation(MathPoint p, MathPoint q, MathPoint r) { // See 10th slides from following link for derivation of the formula // http://www.dcs.gla.ac.uk/~pat/52233/slides/Geometry1x1.pdf int val = Convert.ToInt32((q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y)); if (val == 0) { return(0); // colinear } return((val > 0) ? 1 : 2); // clock or counterclock wise }
public Line(MathPoint startpoint, MathPoint endpoint) { this.StartPoint = startpoint; this.EndPoint = endpoint; //Infinite slope is the slope of the vertical line where there is no change in x-axis..so check for that if (Math.Abs(startpoint.x - endpoint.x) > epsilon) { this.Slope = (endpoint.y - startpoint.y) / (endpoint.x - startpoint.x); this.Intercept = endpoint.y - (Slope * endpoint.x); // y = mx + b where m is slope, b is y-intercept and (x,y) is any point in the line } else { infiniteslope = true; Intercept = startpoint.x; //x-intercept } }
public bool DoLinesIntersect(MathPoint p1, MathPoint q1, MathPoint p2, MathPoint q2) { // Find the four orientations needed for general and special cases int o1 = orientation(p1, q1, p2); int o2 = orientation(p1, q1, q2); int o3 = orientation(p2, q2, p1); int o4 = orientation(p2, q2, q1); // General case if (o1 != o2 && o3 != o4) { return(true); } // Special Cases // p1, q1 and p2 are colinear and p2 lies on segment p1q1 if (o1 == 0 && onSegment(p1, p2, q1)) { return(true); } // p1, q1 and p2 are colinear and q2 lies on segment p1q1 if (o2 == 0 && onSegment(p1, q2, q1)) { return(true); } // p2, q2 and p1 are colinear and p1 lies on segment p2q2 if (o3 == 0 && onSegment(p2, p1, q2)) { return(true); } // p2, q2 and q1 are colinear and q1 lies on segment p2q2 if (o4 == 0 && onSegment(p2, q1, q2)) { return(true); } return(false); // Doesn't fall in any of the above cases }
private bool IsBetween(MathPoint start, MathPoint middle, MathPoint end) { return(IsBetweenValue(start.x, middle.x, end.x) && IsBetweenValue(start.y, middle.y, end.y)); }
//Easy and Simple Method using Slope and y-Intercept public MathPoint GetIntersectionPointUsingSlopes(MathPoint p1, MathPoint q1, MathPoint p2, MathPoint q2) { //Rearrange the points based on x co-ordinate values to make the calculate easier //start point should be lesser than endpoint that is p1 < q1 //Point 1 is lesser than point 2 .. p1.x < p2.x //p1 and q1 makes a line if (p1.x > q1.x) { Swap(p1, q1); } if (p2.x > q2.x) { Swap(p2, q2); } //check both lines if (p1.x > p2.x) { Swap(p1, q1); Swap(p2, q2); } //Now all the point are sorted x-axis value Line line1 = new Line(p1, q1); Line line2 = new Line(p2, q2); //Two lines will intersect on two condition //conditon 1: (both line are parallen and overlapping // if the lines are parallel (slope are equal), they intersect only if they have the same y-interecept and start 2 in on line 1 //Condtion 2 : If two line intersect, then they will have same point of intersection and the point of intesection will be with both lines coordinates if (line1.Slope == line2.Slope) { if (line1.Intercept == line2.Intercept && IsBetween(p1, p2, q1)) { return(p2); //point of intersection will be p2 } return(null); } /* Get co-ordinatinates of intersection based on the forumla * If the 2 lines intersect, then the at the point of intersection both lines will share the same x-coordinate and y-coordinate * so y = mx + b for lines will be equal to y = mx + b of line 2 * x = (b2 -b1)/ (m1- m2) */ double x = (line2.Intercept - line1.Intercept) / (line1.Slope - line2.Slope); double y = x * line1.Slope + line1.Intercept; //y = mx + b where (x,y) are any co-ordinates in the line MathPoint IntersectionPoint = new MathPoint(x, y); //check whether the intesection point x and y is within line segement range if (IsBetween(line1.StartPoint, IntersectionPoint, line1.EndPoint) && IsBetween(line2.StartPoint, IntersectionPoint, line2.EndPoint)) { return(IntersectionPoint); } return(null); }