// 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);
        }