我在actionscript中创建了这个类,它返回bezier的给定点。而我想要达到的目的是获得当前点的角度。我在互联网上搜索但我找不到多少。我怎么能这样做?
public static function quadraticBezierPoint(u:Number, anchor1:Point, anchor2:Point, control:Point):Point {
var uc:Number = 1 - u;
var posx:Number = Math.pow(uc, 2) * anchor1.x + 2 * uc * u * control.x + Math.pow(u, 2) * anchor2.x;
var posy:Number = Math.pow(uc, 2) * anchor1.y + 2 * uc * u * control.y + Math.pow(u, 2) * anchor2.y;
return new Point(posx, posy);
}
答案 0 :(得分:11)
假设:
点B是在时间t由p0,p1和p2描述的二次贝塞尔曲线上的点。
q0是在时间t由p0和p1描述的线性贝塞尔曲线上的点。
q1是在时间t由p1和p2描述的线性贝塞尔曲线上的点。
q0和q1之间的线段与B点的二次贝塞尔曲线相切。
因此,时间t处的贝塞尔曲线的角度等于q0和q1之间的线段的斜率。
维基百科有lovely gif证明这一点。黑点是B点,绿线段的端点是q0和q1。
对于更高尺寸的贝塞尔曲线,原理是相同的。要找到N度贝塞尔曲线上某点的角度,找到q0和q1,它们是控制点[p0,p1,...,p(N-1)的N-1度贝塞尔曲线上的点。 )]和[p1,p2,...,pN]。该角度等于q0-q1线段的斜率。
在伪代码中:
def bezierCurve(controlPoints, t):
if len(controlPoints) == 1:
return controlPoints[0]
else:
allControlPointsButTheLastOne = controlPoints[:-1]
allControlPointsButTheFirstOne = controlPoints[1:]
q0 = bezierCurve(allControlPointsButTheLatOne, t)
q1 = bezierCurve(allControlPointsButTheFirstOne, t)
return (1-t) * q0 + t * q1
def bezierAngle(controlPoints, t):
q0 = bezierCurve(controlPoints[:-1], t)
q1 = bezierCurve(controlPoints[1:], t)
return math.atan2(q1.y - q0.y, q1.x - q0.x)
答案 1 :(得分:3)
凯文的解释之后,我做了一个动态但简单的解决方案:
public static function quadraticBezierAngle(u:Number, anchor1:Point, anchor2:Point, control:Point):Number {
var uc:Number = 1 - u;
var dx:Number = (uc * control.x + u * anchor2.x) - (uc * anchor1.x + u * control.x);
var dy:Number = (uc * control.y + u * anchor2.y) - (uc * anchor1.y + u * control.y);
return Math.atan2(dy, dx);
}