How can I modify my code to line through the bezier control points?

风格不统一 提交于 2019-12-03 05:12:00
Sly_cardinal

Example project Source code

If you're not interested in how this is derived, skip down to the answer section.

Background Information


Bezier curves are interesting and fun to work with. This animation shows how your Quadratic curve is being drawn between the two anchor points (P0 and P2) over time with respect to the control point (P1).

What you need to do, instead of drawing the control point (P1), is draw the point on the curve at t=0.5:


(source: whilenotnull.com)

Luckily this is easy to do with the equation given on the Wikipedia page: http://en.wikipedia.org/wiki/Bezier_Curve#Quadratic_B.C3.A9zier_curves

Here is the formula in Actionscript:

public function calculatePoint(p0:Point, p1:Point, p2:Point, t:Number):Point
{
    var p:Point = new Point(calculateTerm(p0.x, p1.x, p2.x, t), calculateTerm(p0.y, p1.y, p2.y, t));
    return p;
}

public function calculateTerm(p0:Number, p1:Number, p2:Number, t:Number):Number
{
    var negT:Number = 1 - t;

    var a0:Number = Math.pow(negT, 2) * p0;
    var a1:Number = 2 * negT * t * p1;
    var a2:Number = Math.pow(t, 2) * p2;

    var pos:Number = a0 + a1 + a2;
    return pos;
}

So if you plug the three points: var t0:Point = calculatePoint(p0, p1, p2, 0.5); you'll get the point on the curve where you want to draw your "control point".


Answer

Now we can write a function that assumes the second parameter is a point on the curve and determine the co-ordinates of the control point:

public function derivePoint(p0:Point, b1:Point, p2:Point, t:Number = 0.5):Point
{
    var p:Point = new Point(deriveTerm(p0.x, b1.x, p2.x, t), deriveTerm(p0.y, b1.y, p2.y, t));
    return p;
}

public function deriveTerm(p0:Number, bt:Number, p2:Number, t:Number):Number
{
    var negT:Number = 1 - t;

    var a0:Number = Math.pow(negT, 2) * p0;
    var a1:Number = 2 * negT * t;
    var a2:Number = Math.pow(t, 2) * p2;

    var p1:Number = (bt - a0 - a2) / a1;
    return p1;
}

From this I've updated your code snippet to (hopefully) draw the curve through your "control points":

// clear old line and draw new / begin fill
var g:Graphics = graphics;
g.clear();
g.lineStyle(2, 0, 1);
g.beginFill(0x0099FF,.1);

//move to starting anchor point
var startX:Number = anchorPoints[0].x;
var startY:Number = anchorPoints[0].y;
g.moveTo(startX, startY);

// Connect the dots
var p0:Point = new Point(startX, startY);
var p2:Point;

var numAnchors:Number = anchorPoints.length;
for (var i:Number=1; i<numAnchors; i++) {

    p2 = new Point(anchorPoints[i].x, anchorPoints[i].y);

    // curve to next anchor through control
    var b1:Point = new Point(controlPoints[i].x,controlPoints[i].y);
    var p1:Point = derivePoint(p0, b1, p2);

    g.curveTo(p1.x, p1.y, p2.x, p2.y);

    p0 = p2;

}
// Close the loop
g.curveTo(controlPoints[0].x,controlPoints[0].y,startX,startY);

Example project Source code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!