Search code examples
c#mathpoints

Convert 8 points to a rectangle


I draw 4 lines through 8 points on my picturebox which creates a rectangle.

            float xnum = 0.580481F;
            float ynum = 0.373782F;
            float znum = 0.419519F;
            float wnum = 0.219629F;

            PointF wnum1 = new PointF(1024, wnum * 1024);
            PointF wnum2 = new PointF(0, wnum * 1024);

            PointF xnum1 = new PointF(xnum * 1024, 1024);
            PointF xnum2 = new PointF(xnum * 1024, 0);

            PointF ynum1 = new PointF(1024, ynum * 1024);
            PointF ynum2 = new PointF(0, ynum * 1024);

            PointF znum1 = new PointF(znum * 1024, 1024);
            PointF znum2 = new PointF(znum * 1024, 0);

            e.Graphics.DrawLine(pen1, wnum1, wnum2);
            e.Graphics.DrawLine(pen1, znum1, znum2);
            e.Graphics.DrawLine(pen1, xnum1, xnum2);
            e.Graphics.DrawLine(pen1, ynum1, ynum2);

Is there a way to draw the rectangle directly out of my 8 points?


Solution

  • To draw a rectangle you need four points. What you're asking is to find the intersection of a set of lines described by eight different points, and draw the resulting polygon. When phrased like that, it becomes a matter of working through the math:

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        using (var pen1 = new Pen(Color.Black))
        {
            float xnum = 0.580481F;
            float ynum = 0.373782F;
            float znum = 0.419519F;
            float wnum = 0.219629F;
    
            PointF wnum1 = new PointF(1024, wnum * 1024);
            PointF wnum2 = new PointF(0, wnum * 1024);
    
            PointF xnum1 = new PointF(xnum * 1024, 1024);
            PointF xnum2 = new PointF(xnum * 1024, 0);
    
            PointF ynum1 = new PointF(1024, ynum * 1024);
            PointF ynum2 = new PointF(0, ynum * 1024);
    
            PointF znum1 = new PointF(znum * 1024, 1024);
            PointF znum2 = new PointF(znum * 1024, 0);
    
            // Given the four lines, find the intersection points that mark the corners of the polygon
            PointF[] points = new PointF[]
            {
                LineLineIntersection(wnum1, wnum2, xnum1, xnum2),
                LineLineIntersection(ynum1, ynum2, xnum1, xnum2),
                LineLineIntersection(ynum1, ynum2, znum1, znum2),
                LineLineIntersection(wnum1, wnum2, znum1, znum2),
            };
            e.Graphics.DrawPolygon(pen1, points);
        }
    }
    
    static PointF LineLineIntersection(PointF line1pt1, PointF line1pt2, PointF line2pt1, PointF line2pt2)
    {
        // Calculate the formula for the first line
        float a1 = line1pt2.Y - line1pt1.Y;
        float b1 = line1pt1.X - line1pt2.X;
        float c1 = a1 * (line1pt1.X) + b1 * (line1pt1.Y);
    
        // Calculate the formula for the second line
        float a2 = line2pt2.Y - line2pt1.Y;
        float b2 = line2pt1.X - line2pt2.X;
        float c2 = a2 * (line2pt1.X) + b2 * (line2pt1.Y);
    
        float determinant = a1 * b2 - a2 * b1;
    
        if (determinant == 0)
        {
            // The two lines are parallel, there is no intersection (or they're the same line)
            throw new Exception("Parallel lines");
        }
        else
        {
            // Calculate the point of intersection
            float x = (b2 * c1 - b1 * c2) / determinant;
            float y = (a1 * c2 - a2 * c1) / determinant;
            return new PointF(x, y);
        }
    }