绘制椭圆弧线

在GDI+中绘制椭圆弧线并不难,但是本人在做AutoCAD二次开发的过程中却找不到绘制椭圆弧的函数,所以自己仿照GDI+中绘制椭圆弧的函数自己写了一个绘制圆弧的函数,主要用于在CAD中绘制椭圆弧线。废话不多说,贴出最终结果和代码,供大家学习参考。

 /// <summary>
        /// 绘制椭圆圆弧(约定顺时针方向绘制,x轴向右水平方向为0度)
        /// </summary>
        /// <param name="XRight">矩形右下角坐标x</param>
        /// <param name="YRight">矩形右下角坐标y</param>
        /// <param name="recWidth">矩形宽</param>
        /// <param name="recHeight">矩形高</param>
        /// <param name="StartAngle">起始角度</param>
        /// <param name="SweepAngle">绘制(扫略角度)</param>
        private double[] DrawEllipse(double XRight, double YRight, double recWidth, double recHeight, double StartAngle,
            double SweepAngle)
        {
            double[] Points = new double[2*(int)SweepAngle];
            //约定宽为椭圆的长半轴,高为椭圆的短半轴
            double b = recHeight / 2;
            double a = recWidth / 2;
            double endAngle = StartAngle + SweepAngle;
            //计算椭圆圆心坐标
            double Ex = XRight + recWidth / 2;
            double Ey = YRight + recHeight / 2;
            //按旋转角度个数计算
            double DeltaAngle =  Math.PI / 180;
            double tempThelta, tempX=0, temp,tempY=0;
            for (int i = 0; i < SweepAngle; i++)
            {
                tempThelta = StartAngle * Math.PI / 180 + i * DeltaAngle;
                if (tempThelta >= 2*Math.PI)
                {
                    tempThelta = tempThelta * Math.PI / 180 - 360 * Math.PI / 180;
                }
                else if (tempThelta == Math.PI / 2)  
                {
                    tempX = 0;
                    tempY =  b;
                }
                else if (tempThelta == Math.PI)
                {
                    tempX = - a;
                    tempY = 0;
                }
                else  if (tempThelta == 1.5d*Math.PI)
                {
                    tempX = 0;
                    tempY = - b;
                }
                if (tempThelta >= 0 && tempThelta < Math.PI / 2)
                {
                    temp = 1 / (b * b + a * a * Math.Tan(tempThelta) * Math.Tan(tempThelta));
                    tempX = a * b * Math.Sqrt(temp);
                    tempY = tempX * Math.Tan(tempThelta);
                }
               else  if (tempThelta > Math.PI / 2 && tempThelta < 3*Math.PI / 2)
                {
                    tempThelta = tempThelta - Math.PI;
                    temp = 1 / (b * b + a * a * Math.Tan(tempThelta) * Math.Tan(tempThelta));
                    tempX = a * b * Math.Sqrt(temp);
                    tempY = tempX * Math.Tan(tempThelta);
                    tempX = -tempX;
                    tempY = -tempY;
                    
                } 
                else if (tempThelta > 270*Math.PI/180 && tempThelta < 2*Math.PI)
                {
                    tempThelta = tempThelta - Math.PI;
                    temp = 1 / (b * b + a * a * Math.Tan(tempThelta) * Math.Tan(tempThelta));
                    tempX = a * b * Math.Sqrt(temp);
                    tempY = tempX * Math.Tan(tempThelta);
                    //tempY = tempY;
                }

                tempX = tempX + Ex;
                tempY = tempY + Ey;

                Points[2 * i] = tempX;
                Points[2 * i + 1] = tempY;
            }
            return Points;
        }

说明一下,采用的计算原理:

计算原理很简单,根据起始角度可以计算出下一点xy坐标的关系即

x=tan(thelta)y

然后带入椭圆曲线求出y值就可以了,需要注意以下几点:

(1)因为正切在kPI/2上的值是无穷,因此需要在360°内要把90°、180°和270°赋予指定的值;

(2)坐标系的变化,我们平常使用的坐标系通常为笛卡尔坐标系,这里要注意y的正负问题;

(3)递增,最好要以度为单位,这样可以有效的节省程序的计算时间。

最后,您可能在程序中看到用多很多if语句,大家也可以采用swich语句,个人喜好而已。希望能对童鞋们有所帮助。

转载自:https://blog.csdn.net/xiaohou66/article/details/6752634

You may also like...