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

问题描述 投票:0回答:2

如上图,以红线为中心轴画出黑色矩形。给定红线的起点坐标和终点坐标以及矩形的宽度,如何绘制矩形?

我正在写一个

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()
}
c# winforms graphics drawing
2个回答
0
投票

解决方案:

  1. 从起点位置和终点位置计算矩形的长度。
  2. 计算直线从起点位置到终点位置的斜率
  3. 从斜率计算角度。
  4. 计算矩形的四个顶点位置。
  5. 用直线连接矩形的四个顶点。
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());
}

0
投票

这是一种替代方法,不需要您计算旋转矩形的实际坐标。

相反,我们平移和旋转整个图形表面并绘制一个正确大小的“正常”矩形:

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

}

输出:

© www.soinside.com 2019 - 2024. All rights reserved.