如上图,以红线为中心轴画出黑色矩形。给定红线的起点坐标和终点坐标以及矩形的宽度,如何绘制矩形?
我正在写一个
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()
}
解决方案:
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());
}
这是一种替代方法,不需要您计算旋转矩形的实际坐标。
相反,我们平移和旋转整个图形表面并绘制一个正确大小的“正常”矩形:
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
!代码:
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);
}
}
输出: