gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 02:42:07 26 4
gpt4 key购买 nike

我试图在 flash 中绘制一条连续的曲线。有很多方法,但到目前为止我发现没有一种方法完全符合我的要求。首先,我想使用 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 .

这是一张图片:

A continuous curved line using the actual points as control points

问题是线条实际上并没有通过线条的“真实”点(灰色圆圈)弯曲。有没有办法利用数学的力量来调整控制点,以便曲线实际上通过“真实”点?仅将当前点及其上一个/下一个点作为参数?复制上图的代码如下。如果我可以修改它以满足这个要求,那就太好了(注意第一点和最后一点的异常(exception))。

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),
new Point(80, 160),
new Point(20, 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, point, 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

关于apache-flex - 如何一次从3个给定点绘制连续曲线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5946304/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com