全部 -
我使用锚点和控制点来使用curveTo创建形状。这一切都很好,但我不明白如何在线不直的时候让我的线穿过控制点的中心(蓝点)。
以下是我绘制形状的代码:
// 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 numAnchors:Number = anchorPoints.length;
for (var i:Number=1; i<numAnchors; i++) {
// curve to next anchor through control
g.curveTo(controlPoints[i].x,controlPoints[i].y, anchorPoints[i].x, anchorPoints[i].y);
}
// Close the loop
g.curveTo(controlPoints[0].x,controlPoints[0].y,startX,startY);
我正在绘制的形状供参考:
如何修改我的代码以便直接通过蓝色控制点?
提前致谢!
B'/ P>
答案 0 :(得分:7)
示例项目Source code
如果您对如何推导出来感兴趣,请跳到答案部分。
Bezier curves使用起来既有趣又有趣。 This animation显示了如何相对于控制点(P1)在两个锚点(P0和P2)之间绘制二次曲线。
您需要做的是,而不是绘制控制点(P1),在t = 0.5时绘制曲线上的点:
Point at t=0.5 http://whilenotnull.com/files/imagedump/stackoverflow/Bezier_2_t05.gif
幸运的是,这很容易用维基百科页面上给出的等式来表达:http://en.wikipedia.org/wiki/Bezier_Curve#Quadratic_B.C3.A9zier_curves
以下是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;
}
因此,如果您插入三个点:var t0:Point = calculatePoint(p0, p1, p2, 0.5);
,您将获得曲线上您想要绘制“控制点”的点。
现在我们可以编写一个函数,假设第二个参数是曲线上的一个点并确定控制点的坐标:
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;
}
由此我将您的代码片段更新为(希望)通过“控制点”绘制曲线:
// 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);
示例项目Source code