【问题标题】:flash as3 draw a donut wedge (arc with inner and outer radius) using curveToflash as3 使用curveTo绘制一个甜甜圈楔(具有内半径和外半径的圆弧)
【发布时间】:2011-11-28 15:09:59
【问题描述】:

我正在尝试使用最少的代码/迭代在 Flash 中绘制弧线。我在下面从一个旧的 AS2 示例中移植了此方法,但它需要循环执行多个步骤才能使其看起来流畅,我宁愿避免这种情况。我看到 AS3 有一个“curveTo”命令,但它并没有真正绘制圆弧,而是绘制贝塞尔曲线。 flash中是否有arc命令?还是一种画圆的方法?

这是我的旧代码:

function drawSolidArc (drawObj:Object, centerX:Number,centerY:Number,innerRadius:Number,outerRadius:Number,startAngle:Number,arcAngle:Number,steps:int=20):void {
    if (Math.abs(startAngle)>360)startAngle%=360
    if (Math.abs(arcAngle)>360)arcAngle%=360
    startAngle/=360,arcAngle/=360
    var twoPI:Number = 2 * Math.PI;
    var angleStep:Number = arcAngle/steps;
    var angle:Number, i:int, endAngle:Number;
    var xx:Number = centerX + Math.cos(startAngle * twoPI) * innerRadius;
    var yy:Number = centerY + Math.sin(startAngle * twoPI) * innerRadius;
    var xxInit:Number=xx;
    var yyInit:Number=yy;
    drawObj.graphics.moveTo(xx,yy);
    for(i=1; i<=steps; i++) {
        angle = (startAngle + i * angleStep) * twoPI;
        xx = centerX + Math.cos(angle) * innerRadius;
        yy = centerY + Math.sin(angle) * innerRadius;
        drawObj.graphics.lineTo(xx,yy);
    }
    endAngle = startAngle + arcAngle;
    for(i=0;i<=steps;i++) {
        angle = (endAngle - i * angleStep) * twoPI;
        xx = centerX + Math.cos(angle) * outerRadius;
        yy = centerY + Math.sin(angle) * outerRadius;
        drawObj.graphics.lineTo(xx,yy);
    }

    drawObj.graphics.lineTo(xxInit,yyInit);
};

var myArc:Shape = new Shape(); //or another DisplayObject

myArc.graphics.beginFill(0xcccccc, 0.50);
//objName, centerX,centerY, innerRadius, outerRadius, startAngle (12 o'clock is -90), arcAngle (degrees from startAngle), steps (smoothness)
drawSolidArc (myArc,250, 250, 180, 200, -90, 65, 100);
myArc.graphics.endFill();
this.addChild(myArc);

【问题讨论】:

    标签: flash actionscript-3 actionscript drawing


    【解决方案1】:

    Graphics.cubicCurveTo() 将比curveTo 提供更好的圆弧近似值。但它仍然不完美。

    【讨论】:

    • 我在文档中没有看到任何名为cubicCurveTo 的函数,当我尝试使用该函数时出现错误。
    • 点击链接即可;) 语言版本:ActionScript 3.0 运行时版本:Flash Player 11、AIR 3
    • 我什至无法在 CS5 中发布到 flash player 11 - 现在对我来说不是一个真正可行的选择。我看到一个添加此功能的 MXP,但您必须在计算机上以管理员身份运行才能安装它,这也不是我在工作中的选择。但如果在较新版本的 flash 中有更准确的曲线方法,那就太好了。
    • 哦,抱歉,我不知道你是用 Flash 编译的。
    【解决方案2】:

    这就是我的做法:

    画一个甜甜圈并遮住它:

    _foreground = new Sprite();
    _foreground.graphics.beginFill(_colour)
    _foreground.graphics.drawCircle(0, 0, _outerRadius);
    _foreground.graphics.drawCircle(0, 0, _innerRadius);
    _foreground.graphics.endFill();
    _container.addChild(_foreground);
    
    _mask = new Sprite();
    _mask.graphics.beginFill(0xff0000);
    _foreground.mask = _mask;
    

    然后使用此方法绘制它 - 通过在蒙版中绘制一个楔子

    private function draw(e:Event):void //Called each frame (if animating)
    {
    // No need to draw more than 360
    if (Math.abs(_arc) > _endAngle) 
    {
        _arc = _endAngle;
        stop();
    }
    
    _numOfSegs = Math.ceil(Math.abs(_arc) / 45);
    _segAngle = _arc / _numOfSegs;
    _segAngle = (_segAngle / 180) * Math.PI;
    _angle = (_startAngle / 180) * Math.PI;
    
    // Calculate the start point
    _ax = Math.cos(_angle) * _outerRadius;
    _ay = Math.sin(-_angle) * _outerRadius;
    
    // Draw the first line
    _mask.graphics.lineTo(_ax, _ay);
    
    for (var i:int=0; i<_numOfSegs; i++) 
    {
        _angle += _segAngle;
        _angleMid = _angle - (_segAngle / 2);
        _bx = Math.cos(_angle) * _outerRadius;
        _by = Math.sin(_angle) * _outerRadius;
        _cx = Math.cos(_angleMid) * (_outerRadius / Math.cos(_segAngle / 2));
        _cy = Math.sin(_angleMid) * (_outerRadius / Math.cos(_segAngle / 2));
        _mask.graphics.curveTo(_cx, _cy, _bx, _by);
    }
    
    // Close the wedge
    _mask.graphics.lineTo(0, 0);
    _arc += 3.6; //This gives a 100 steps to complete the circle
    }
    

    【讨论】:

      【解决方案3】:

      下面是我编写的几个不同形状绘图类的链接。您可以通过绘制一个楔形并用第二个圆形遮住它的中心来获得所需的圆段。

      https://github.com/makemachine/makemachine.actionscript/tree/master/src/makemachine/display/shapes

      【讨论】:

      • 谢谢 - 这是一个不错的图书馆。
      【解决方案4】:

      我做了类似于 Jeremy 的解决方案的事情,虽然我没有掩盖它。显然,如果您从同一中心点创建另一个半径较小的弧,它将从现有形状中减去,所以我只是在第一个之后和 endFill 之前再次调用 drawSolidArc,以零为中心点,外半径是第一个楔子的所需内半径:

      var myArc:Sprite = new Sprite();
      myArc.graphics.beginFill(0xcccccc, 1);
      drawArc(myArc, 275, 200, 60, 150, 35); //spriteName, startX, startY, innerRadius, radius, arcAngle, startAngle
      drawArc(myArc, 275, 200, 0, 60, 35); //subtract out the middle by drawing a new circle over the top of it
      myArc.graphics.endFill();
      this.addChild(myArc);
      

      【讨论】:

        【解决方案5】:

        然后是this implementation。但它几乎和你发布的一样混乱。恐怕没有优雅的方式(几条线左右)来绘制弧线。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-09
          相关资源
          最近更新 更多