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, 如有发现,请尽快与博主联系!
回到 主博客

  • 11
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流浪猪头拯救地球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值