winforms 如何画一个以直线为中心轴的矩形?

dy1byipe  于 2023-02-24  发布在  其他
关注(0)|答案(2)|浏览(146)

如上图所示,以红线为中心轴画黑色矩形,已知红线的起点坐标、终点坐标和矩形的宽度,如何画矩形?
我在写System.Drawing.Graphics的扩展方法来实现,直线的起点位置、终点位置、矩形的宽度作为参数传递给方法,但是接下来怎么写画矩形逻辑呢?

public static void DrawRectangleWithLine(this Graphics g, Pen pen, Vector3 startPointPosition, Vector3 endPointPosition, int width)
{
    double length = Math.Pow(Math.Pow(startPointPosition.X - endPointPosition.X, 2) + Math.Pow(startPointPosition.Y - endPointPosition.Y, 2), 0.5);
    double slope = (startPointPosition.Y - endPointPosition.Y) / (startPointPosition.X - endPointPosition.X);
    double angle = Math.Atan(slope);
    // draw the four sides of the rectangle
    g.DrawLine()
    g.DrawLine()
    g.DrawLine()
    g.DrawLine()
}
uxh89sit

uxh89sit1#

    • 解决方案:**

1.从起点位置和终点位置计算矩形的长度。
1.从起点位置和终点位置计算直线的斜率。
1.从斜率计算Angular 。
1.计算矩形的四个顶点的位置。
1.用直线连接矩形的四个顶点。

public static void DrawRectangleWithLine(this Graphics g, Pen pen, Vector3 startPointPosition, Vector3 endPointPosition, int width)
{
    double length = Math.Pow(Math.Pow(startPointPosition.X - endPointPosition.X, 2) + Math.Pow(startPointPosition.Y - endPointPosition.Y, 2), 0.5);
    double slope = (startPointPosition.Y - endPointPosition.Y) / (startPointPosition.X - endPointPosition.X);
    double angle = Math.Atan(slope);
    Vector3 p1 = new Vector3(startPointPosition.X - width / 2 * Math.Sin(angle), startPointPosition.Y + width / 2 * Math.Cos(angle));
    Vector3 p2 = new Vector3(startPointPosition.X + width / 2 * Math.Sin(angle), startPointPosition.Y - width / 2 * Math.Cos(angle));
    Vector3 p3 = new Vector3(p1.X + length * Math.Cos(angle), p1.Y + length * Math.Sin(angle));
    Vector4 p4 = new Vector3(p2.X + length * Math.Cos(angle), p2.Y + length * Math.Sin(angle));
    g.DrawLine(pen, p1.ToPointF(), p2.ToPointF());
    g.DrawLine(pen, p2.ToPointF(), p4.ToPointF());
    g.DrawLine(pen, p4.ToPointF(), p3.ToPointF());
    g.DrawLine(pen, p3.ToPointF(), p1.ToPointF());
}
iyzzxitl

iyzzxitl2#

这里有一个替代方法,不需要计算旋转矩形的实际坐标。
相反,我们平移和旋转整个图形表面,并绘制一个大小正确的“正常”矩形:

public static void DrawRectangleWithLine(this Graphics g, Pen pen, Vector3 startPointPosition, Vector3 endPointPosition, int width)
{            
    // Draw the Red Line with the Original Coordinates
    g.ResetTransform();
    g.DrawLine(Pens.Red, startPointPosition, endPointPosition);

    // Draw the Rectangle around the Red Line
    // by moving the origin and rotating the surface
    double length = Math.Pow(Math.Pow(startPointPosition.X - endPointPosition.X, 2) + Math.Pow(startPointPosition.Y - endPointPosition.Y, 2), 0.5);
    Point midPoint = new Point(
        (startPointPosition.X + endPointPosition.X) / 2,
        (startPointPosition.Y + endPointPosition.Y)/2);
    float deltaX = endPointPosition.X - startPointPosition.X;
    float deltaY = endPointPosition.Y - startPointPosition.Y;
    float angle = (float)(Math.Atan2(deltaY, deltaX) * 180.0 / Math.PI);
    g.TranslateTransform(midPoint.X, midPoint.Y);
    g.RotateTransform((float)angle);

    // Method 1 of making the Rectangle:
    Rectangle rc = new Rectangle(new Point(0, 0), new Size(0, 0));
    rc.Inflate((int)(length / 2), width / 2);            
    g.DrawRectangle(pen, rc);

    // Method 2 of making the Rectangle:
    Rectangle rc2 = new Rectangle(new Point(-(int)(length / 2), -width / 2), new Size((int)length, width));
    g.DrawRectangle(pen, rc2);
}

在WinForms中使用它的示例:

  • 我使用了Point,而不是下面的Vector3
  • 所示矩形通过方法1

代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private Point startPoint = new Point(150, 500);
    private Point endPoint = new Point(650, 200);

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawRectangleWithLine(Pens.Black, startPoint, endPoint, 50);
    }

}

输出:

相关问题