C# DrawArc(画弧)
2020/6/12
最近用到C# 的 pictureBox 画圆弧,设计者的脑回路和我们平常的脑回路有点不太一样,所以刚上来就给整懵逼了,这篇博客就简单介绍一下如何调用这个 DrawArc
2020/6/13
其实昨天并没有达到想要的效果,画出来的弧为啥都是优弧呢?经过一些思考,我想我找到了原因,下面更正一下
1.理解设计者的脑回路
1.首先新建个窗体:
名字啥的随便区,但是要拉的大一点(不然一会画不下)
2.添加 Paint 响应事件:
3.找到
private void Draft_Paint(object sender, PaintEventArgs e)
{
}
在里面添加:
private void Draft_Paint(object sender, PaintEventArgs e)
{
// Create pen.
Pen blackPen = new Pen(Color.Black, 3);
// Create coordinates of rectangle to bound ellipse.
int x = 30;//包裹圆弧矩形的左上角x,y 坐标
int y = 30;
int width = 200;//包裹矩形的大小
int height = 200;
// Create start and sweep angles on ellipse.
int startAngle = 45;//起始角
int sweepAngle = 270;//逆时针转过这么多
// Draw arc to screen.
e.Graphics.DrawArc(blackPen, x, y, width, height, startAngle, sweepAngle);
}
4.点击调式运行:
注:只有黑色的是程序运行出的结果。
这个DrawArc 和pictureBox 的DrawArc 调用方法是一样的
2.将我们的脑回路转化成设计者的脑回路
我们画圆弧的时候(不知道各位读者是不是,反正我是,嘿嘿),通常是已知起始点、终止点、半径,来画的,如何将这些信息转化成上面的那些信息呢?
1.根据起止点和终止点求出圆心坐标:
我们都知道,两点确定不出来唯一一个圆,但是加上起止点到终止点是逆时针方向这个约束条件就可以唯一确定一个圆了,(扯,还得 在加上一个是优弧还是劣弧的条件)怎么做到的呢?
首先由两个点搞出来第三个点:
之后三个点就确定出来圆心坐标了。
2.得到圆心坐标,有半径,包裹矩形大小以及包裹矩形左上角坐标即可知
3.有圆心坐标,有起终点坐标,起始方位角,弧角即可知
综上,关键就是求出圆心坐标。
3.C# 代码实现
/*此函数用来在画布上画圆弧1
* 输入:p 笔, g 画布, R 半径, p1 起点, p2 终点, k 优1劣2 顺时针画的
* 注意,这里的p1 p2 是在画布坐标系下的坐标
*/
public static void DrawArc(Pen p,Graphics g,double R,Point p1,Point p2,int k=1)
{
Point cen = GetCenter.Ycenter(R, p1, p2,k);
// Create coordinates of rectangle to bound ellipse.
float x = (float)(cen.x-R),//包裹圆弧矩形的左上角x,y 坐标
y = (float)(cen.y-R), //由于系统的 DrawArc 不支持double 故强制类型转化一下
width=(float)(2*R),
height=(float)(2*R);
Angle
PI=new Angle(Math.PI/2),
AstartAngle = cen.getAn(p1),//起始角,以度为单位
a = cen.getAn(p2),
AsweepAngle = a - AstartAngle;//逆时针转过这么多
float startAngle = AstartAngle.d+180,
sweepAngle = AsweepAngle.d;
// Draw arc to screen.
g.DrawArc(p, x, y, width, height, startAngle, sweepAngle);
}
其所依附的类:
https://blog.csdn.net/Gou_Hailong/article/details/106686355
https://blog.csdn.net/Gou_Hailong/article/details/88989274
https://blog.csdn.net/Gou_Hailong/article/details/95803595
4.使用示例
在刚才的paint 中加入代码,点击运行
private void Draft_Paint(object sender, PaintEventArgs e)
{
// create pen.
Pen p = new Pen(Color.Black, 2);
PointF p1 = new PointF(120, 140),
p2 = new PointF(200, 110);
double r = 50;
Graphics g = e.Graphics;
Draw.DrawArc(p, g, r, p1, p2);//优1劣2,直观顺
p.Color = Color.Red;
Draw.DrawArc(p, g, r, p2, p1,2);
PointF p3 = new PointF(),
p4 = new PointF();
p3.X = p1.X + 200; p4.X = p2.X + 200;
p3.Y = p1.Y; p4.Y = p2.Y;
p.Color = Color.Blue;
Draw.DrawArc(p, g, r, p4, p3);//优1劣2
p.Color = Color.Yellow;
Draw.DrawArc(p, g, r, p3, p4, 2);
g.DrawLine(p, p1,p3);
g.DrawLine(p, p2, p4);
Point[] pt = new Point[4];
pt[0] = new Point(p1); pt[0].name = "p1";
pt[1] = new Point(p2); pt[1].name = "p2";
pt[2] = new Point(p3); pt[2].name = "p3";
pt[3] = new Point(p4); pt[3].name = "p4";
Font f = new Font("宋体", 10);
for(int i=0;i<4;i++)
{
g.FillEllipse(Brushes.Black, (float)(pt[i].X - 5), (float)(pt[i].Y) - 5, 10, 10);
g.DrawString(pt[i].name, f, Brushes.Black, (float)(pt[i].X - 5), (float)(pt[i].Y + 5));
}
}
结果:
欧了!
【注1】其中的代码也许并不完整,您可以作为伪码参看,或者您可以去我主博客逛逛,也许有意外之喜!
【注2】此篇博客是 C# 编程笔记 的子博客。
【注3】由于博主水平有限,程序可能存在漏洞或bug, 如有发现,请尽快与博主联系!
回到 主博客