使用圆弧半径和旋转在两点之间创建圆弧 [英] Creating an Arc between Two Points with Arc Radius and Rotation
问题描述
当我的主窗体被绘制时,我有两个点我想与 C# 图形类中的一个弧连接.我还有弧应该具有的半径以及弧应该从起点转向下一个的方向.我不知道我应该如何使用提供的 drawArc 重载来做到这一点.任何人都可以帮助我使用一个函数,该函数需要一个起点、一个终点、一个圆弧半径和一个方向(顺时针或逆时针),然后绘制该圆弧?或者更确切地说,我试图从 .gcode 文件如何指定弧形运动以及如果半径为负数则为顺时针旋转,反之亦然.我期待一些输入
I have two Points I want to connect with an Arc in the C# Graphics Class when my main form is painted. I also have the radius that arc should have and the direction the arc should turn from starting point to the next. I dont see how I should do that with the drawArc overloads provided. Can anybody help me with maybe a function that takes a starting point, a end point, an arc radius and a direction (Clockwise or counter-Clockwise) and then draws that arc? Or Rather I am trying to parse this from how .gcode files specify arc movements and if the radius is negative its a clockwise roation and vice versa. Am looking forward to some input
推荐答案
我为你想到了.
这是示例代码.这里的关键是函数DrawArcBetweenTwoPoints()
.为了测试,它还绘制了中心点和两个辐条.您应该删除这些行并专注于 DrawArc()
部分.
Here is the sample code. The key here is the function DrawArcBetweenTwoPoints()
. For testing it also draws the center points and the two spokes. You should remove those lines and focus on the DrawArc()
part.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TranslateTransform(ClientSize.Width/2, ClientSize.Height/2);
PointF A = new PointF(0, -40);
PointF B = new PointF(100, 40);
e.Graphics.DrawLine(Pens.DarkBlue, A, B);
DrawPoint(e.Graphics, Brushes.Black, A);
DrawPoint(e.Graphics, Brushes.Black, B);
DrawArcBetweenTwoPoints(e.Graphics, Pens.Red, A, B, 100);
}
public void DrawPoint(Graphics g, Brush brush, PointF A, float size = 8f)
{
g.FillEllipse(brush, A.X-size/2, A.Y-size/2, size, size);
}
public void DrawArcBetweenTwoPoints(Graphics g, Pen pen, PointF a, PointF b, float radius, bool flip = false)
{
if (flip)
{
PointF temp = b;
b =a;
a = temp;
}
// get distance components
double x = b.X-a.X, y = b.Y-a.Y;
// get orientation angle
var θ = Math.Atan2(y, x);
// length between A and B
var l = Math.Sqrt(x*x+y*y);
if (2*radius>=l)
{
// find the sweep angle (actually half the sweep angle)
var φ = Math.Asin(l/(2*radius));
// triangle height from the chord to the center
var h = radius*Math.Cos(φ);
// get center point.
// Use sin(θ)=y/l and cos(θ)=x/l
PointF C = new PointF(
(float)(a.X + x/2 - h*(y/l)),
(float)(a.Y + y/2 + h*(x/l)));
g.DrawLine(Pens.DarkGray, C, a);
g.DrawLine(Pens.DarkGray, C, b);
DrawPoint(g, Brushes.Orange, C);
// Conversion factor between radians and degrees
const double to_deg = 180/Math.PI;
// Draw arc based on square around center and start/sweep angles
g.DrawArc(pen, C.X-radius, C.Y-radius, 2*radius, 2*radius,
(float)((θ-φ)*to_deg)-90, (float)(2*φ*to_deg));
}
}
private void Form1_Resize(object sender, EventArgs e)
{
this.Refresh();
}
}
我用下面的代码测试了翻转弧
I tested the flip arc with the following code
DrawArcBetweenTwoPoints(e.Graphics, Pens.Red, A, B, 100);
DrawArcBetweenTwoPoints(e.Graphics, Pens.Red, A, B, 100, true);
这篇关于使用圆弧半径和旋转在两点之间创建圆弧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!