在安卓画布中通过三个点的曲线

3
我需要的是,通过三个点绘制一条曲线。使用“.Path.cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)”方法可以实现这一点,但在这种情况下,我的中间点不在曲线上。 我需要绘制一个“︶”形曲线,而不是“V”形曲线。即曲线必须在曲线上的每个点处弯曲。

1
使用Catmull-Rom曲线。这是另一种Hermite曲线,它穿过点而不是被点所跨越,需要复杂的数学来确定曲线外壳在哪里。如果您真的想使用Bezier曲线,虽然我不建议这样做,请前往http://pomax.github.io/bezierinfo/#moulding和下一节。 - Mike 'Pomax' Kamermans
1个回答

1
假设我们有三个点D0(x0,y0)D1(x1,y1)D2(x2,y2)。 我们还需要找到通过D0D1D2的Bezier立方样条P0-P1-P2-P3
显然,
P0 = D0
P3 = D2

那么经过由方程定义的点 D1 的贝塞尔样条曲线数是无限的。

P2 = (D1 - (1-t)^3 * P0 - t^3 * P3) / (3*(1-t)*t^2) -
     (1-t) * P1/t;

其中t是对应于点D1的Bezier曲线参数。

为了找到真实的曲线,我们需要指定一些t,为了简单起见,让我们取t = 0.5并选择P1。然后可以从上面的方程中找到P2

这里是一种基于P1-P2D0-D2平行的限制条件的解决方案:

% vector pointing from D0 to D2
baseSides = 0.3 * (D2 - D0)
% vector moving D1 towards D0 - D2 base
baseDown = 0.1 * (D0 - D1) + (D2 - D1))
% moving D1 down to the base and split to left and right
P1" = D1 + baseDown - baseSides
P2" = D1 + baseDown + baseSides
P1' = P1" + (P1" - D1) * 2 / 3
P2' = P2" + (P2" - D1) * 2 / 3
P1 = P1' + P1' - D0
P2 = P2' + P2' - D2

然后您可以将P1P2P3坐标用作Path.cubicTo()的参数。这里的0.3是一个缩放因子,更改它会使曲线变宽或变窄。
这些计算基于De Casteljau的贝塞尔曲线分裂算法。

Bezier spline passing through a point

这里红色钻石为P1"P2",绿色钻石为P1'P2',蓝色圆圈为P1P2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接