flex – 如何一次从3个给定点绘制连续曲线

前端之家收集整理的这篇文章主要介绍了flex – 如何一次从3个给定点绘制连续曲线前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在闪光灯中画一条连续的曲线.有很多方法,但到目前为止我找到的方法都不符合我的要求.首先,我想使用flash图形api的curveTo()方法.我不想 simulate a curve with hundreds of calls to lineTo() per curved line segment.我的经验和理解是线段是处理器重. Flash的二次贝塞尔曲线应该占用较少的cpu功率.如果你认为我错了,请挑战这个假设.

我也不想使用以整行作为参数的预制方法(例如mx.charts.chartClasses.GraphicsUtilities.drawPolyline()).
原因是我最终需要修改逻辑以在我绘制的线上添加装饰,所以我需要在最低级别理解的东西.

我目前已经创建了一个方法,它将绘制一条曲线给出3点,using the mid-point method found here.

这是一张图片

问题是线条实际上并没有穿过线条的“真实”点(灰色圆圈).有没有办法使用数学的力量,我可以调整控制点,使曲线实际上通过“真实”点?仅给出当前点及其上一个/下一个点作为参数?复制上面图片代码如下.如果我可以修改它来满足这个要求会很棒(注意第一点和最后一点的例外).

package {
  import flash.display.Shape;
  import flash.display.Sprite;
  import flash.display.Stage;
  import flash.geom.Point;

  [SWF(width="200",height="200")]
  public class TestCurves extends Sprite {
    public function TestCurves() {
      stage.scaleMode = "noScale";
      var points:Array = [
        new Point(10,10),new Point(80,80),160),new Point(20,200),new Point(200,100)
      ];

      graphics.lineStyle(2,0xFF0000);

      var point:Point = points[0];
      var nextPoint:Point = points[1];

      SplineMethod.drawSpline(graphics,point,null,nextPoint);

      var prevPoint:Point = point;

      var n:int = points.length;
      var i:int;
      for (i = 2; i < n + 1; i++) {
        point = nextPoint;
        nextPoint = points[i]; //will eval to null when i == n

        SplineMethod.drawSpline(graphics,prevPoint,nextPoint);

        prevPoint = point;
      }

      //straight lines and vertices for comparison
      graphics.lineStyle(2,0xC0C0C0,0.5);
      graphics.drawCircle(points[0].x,points[0].y,4);
      for (i = 1; i < n; i++) {
        graphics.moveTo(points[i - 1].x,points[i - 1].y);
        graphics.lineTo(points[i].x,points[i].y);
        graphics.drawCircle(points[i].x,points[i].y,4);
      }

    }
  }
}
import flash.display.Graphics;
import flash.geom.Point;

internal class SplineMethod {
  public static function drawSpline(target:Graphics,p:Point,prev:Point=null,next:Point=null):void {
    if (!prev && !next) {
      return; //cannot draw a 1-dimensional line,ie a line requires at least two points
    }

    var mPrev:Point; //mid-point of the prevIoUs point and the target point
    var mNext:Point; //mid-point of the next point and the target point

    if (prev) {
      mPrev = new Point((p.x + prev.x) / 2,(p.y + prev.y) / 2);
    }
    if (next) {
      mNext = new Point((p.x + next.x) / 2,(p.y + next.y) / 2);
      if (!prev) {
        //This is the first line point,only draw to the next point's mid-point
        target.moveTo(p.x,p.y);
        target.lineTo(mNext.x,mNext.y);
        return;
      }
    } else {
      //This is the last line point,finish drawing from the prevIoUs mid-point
      target.moveTo(mPrev.x,mPrev.y);
      target.lineTo(p.x,p.y);
      return;
    }
    //draw from mid-point to mid-point with the target point being the control point.
    //Note,the line will unfortunately not pass through the actual vertex... I want to solve this
    target.moveTo(mPrev.x,mPrev.y);
    target.curveTo(p.x,p.y,mNext.x,mNext.y);
  }
}

稍后我会在draw方法添加箭头和东西.

解决方法

我想你正在寻找Catmull-Rom花键.我已经为你搜索了AS3实现,但没有尝试过,所以请自行决定使用:

http://actionsnippet.com/?p=1031

猜你在找的Flex相关文章