我试图在闪光灯中画一条连续的曲线.有很多方法,但到目前为止我找到的方法都不符合我的要求.首先,我想使用flash图形api的curveTo()方法.我不想
@L_404_0@.我的经验和理解是线段是处理器重. 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); } }
解决方法
我想你正在寻找Catmull-Rom花键.我已经为你搜索了AS3实现,但没有尝试过,所以请自行决定使用: