使用curveTo绘制完美圆形的一部分

3

我需要使用graphics.curveTo绘制一个完美圆的一部分(我已经有要绘制的半径和角度),但我无法理解控制点x和y的确切公式,以使曲线完美。

我知道如何使用循环和许多lineTo来完成,但这对我的需求来说不够好...

提前感谢!

3个回答

7
我使用这个函数来绘制圆形段(我认为很久以前我从在线AS2示例中移植了它,该示例展示了如何绘制完整的圆):
    /**
     * Draw a segment of a circle
     * @param graphics      the graphics object to draw into
     * @param center        the center of the circle
     * @param start         start angle (radians)
     * @param end           end angle (radians)
     * @param r             radius of the circle
     * @param h_ratio       horizontal scaling factor
     * @param v_ratio       vertical scaling factor
     * @param new_drawing   if true, uses a moveTo call to start drawing at the start point of the circle; else continues drawing using only lineTo and curveTo
     * 
     */
    public static function drawCircleSegment(graphics:Graphics, center:Point, start:Number, end:Number, r:Number, h_ratio:Number=1, v_ratio:Number=1, new_drawing:Boolean=true):void
    {
        var x:Number = center.x;
        var y:Number = center.y;
        // first point of the circle segment
        if(new_drawing)
        {
            graphics.moveTo(x+Math.cos(start)*r*h_ratio, y+Math.sin(start)*r*v_ratio);
        }

        // draw the circle in segments
        var segments:uint = 8;

        var theta:Number = (end-start)/segments; 
        var angle:Number = start; // start drawing at angle ...

        var ctrlRadius:Number = r/Math.cos(theta/2); // this gets the radius of the control point
        for (var i:int = 0; i<segments; i++) {
             // increment the angle
             angle += theta;
             var angleMid:Number = angle-(theta/2);
             // calculate our control point
             var cx:Number = x+Math.cos(angleMid)*(ctrlRadius*h_ratio);
             var cy:Number = y+Math.sin(angleMid)*(ctrlRadius*v_ratio);
             // calculate our end point
             var px:Number = x+Math.cos(angle)*r*h_ratio;
             var py:Number = y+Math.sin(angle)*r*v_ratio;
             // draw the circle segment
             graphics.curveTo(cx, cy, px, py);
        }

    }

我认为这已经非常接近完美的圆了。虽然我不太理解其中的数学原理,但我希望参数足够清晰易懂。


1
我在上述函数中唯一添加的东西是根据弧长计算分段数量:var segments = Math.ceil(Math.abs(end-start)/(Math.PI/4)); - fserb

3

使用二次贝塞尔曲线创建完美的圆形(甚至部分圆形)将会非常困难,所以不用感到难过。

Flash Player 11 / AIR 3中引入了一个期待已久的图形API增强功能,即cubicCurveTo()函数,它可以绘制立方贝塞尔曲线,这使得绘制半圆等形状变得非常简单。


1

使用贝塞尔曲线无法画出完美的圆形,只能近似。请参见http://cgafaq.info/wiki/Bézier_circle_approximation。


我并不是指用一条贝塞尔曲线画一个完美的圆。使用多条曲线来画圆也是可以的。无论如何,谢谢你的回答 :) - Yaron U.
1
@YaronUliel,即使使用多个曲线也是不可能的。 - lhf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接