已知 f(x) 为线性函数,如何获取二次贝塞尔曲线的控制点

4

我对这个话题进行了大量研究,发现了一些有帮助的文章,但我就是无法做到正确。

我正在开发一个非常简单的结构分析应用程序。在这个应用中,我需要显示一张图表,展示梁的内部应力。该图表是通过以下公式获得的:

y = (100 * X / 2) * (L - X)

其中 L 是梁的已知长度(为了简单起见,我们假设为1)。X 是一个介于0和梁长度之间的值。因此,最终公式如下:

y = (100 * X / 2) * (1 - x) where  0 < X < 1.

假设起点和终点是 P0 = (0,0)P2 = (1,0)。那么我如何得到控制点P1呢?我在维基百科页面上搜索了很久,但不确定如何从二次贝塞尔曲线公式中获取控制点:

B(t) = (1 - t)^2 * P0 + 2*(1 - t)*t * P1 + t^2 * P2

我确定这应该是一个很容易解决的问题...有人可以帮忙吗?

P.S.: 我也找到了这篇文章,如何找到定义贝塞尔曲线的数学函数,它似乎解释了我试图实现相反的事情。只是我搞不清楚如何扭转它。


如果您还没有,可以看看Math.SE http://math.stackexchange.com/。 - Aboutblank
谢谢!我已经查看了数学部分。我只是不知道如何处理“t”值。我尝试做与我链接的问题相同的事情,但“t”仍然存在,所以我得到了一个无用的坐标。 - Alan Rynne
2个回答

4
我们希望由y定义的二次曲线与由B(t)定义的二次贝塞尔曲线匹配。

必须匹配的众多点中,其中一个是在x = 0.5处发生的峰值。当x = 0.5时,

y = (100 * x / 2) * (1 - x)

    100     1      25
y = ---- * ---  = ---- = 12.5
     4      2       2

因此,让我们安排B(0.5) = (0.5, 12.5)
B(t) = (1-t)^2*(0,0) + 2*(1-t)*t*(Px, Py) + t^2*(1,0)
(0.5, 12.5) = B(0.5) = (0,0) + 2*(0.5)*(0.5)*(Px, Py) + (0.25)*(1,0)

0.5 = 0.5 * Px + 0.25
12.5 = 0.5 * Py

解决 PxPy 的问题,我们得到:
(Px, Py) = (0.5, 25)

这里是Python的可视化确认,证明我们已经找到了正确的点:

# test.py
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 1, 100)
y = (100*x/2)*(1-x)
t = np.linspace(0, 1, 100)
P0 = np.array([0,0])
P1 = np.array([0.5,25])
P2 = np.array([1,0])
B = ((1-t)**2)[:,np.newaxis]*P0 + 2*((1-t)*t)[:,np.newaxis]*P1 + (t**2)[:,np.newaxis]*P2
plt.plot(x, y)
plt.plot(B[:,0], B[:,1])
plt.show()

运行 python test.py ,我们可以看到两条曲线重叠:

enter image description here


B(t)达到最大高度时,我如何知道要选择t = 0.5作为参数值?

这主要是基于直觉,但以下是一种更正式的证明方法:

B(t)达到最大高度时,B'(t)的y分量等于0。因此,对B(t)进行求导,我们得到

0 = 2*(1-2t)*Py
t = 0.5 or Py = 0

如果 Py = 0,则 B(t) 是从 (0,0) 到 (1,0) 的水平线。拒绝这种退化情况,我们可以看到 B(t) 在 t = 0.5 时达到最大高度。

哇!非常感谢unutbu。那真是太简单了……让我确认一下,从你的代码中可以得出结论,贝塞尔曲线的最大点出现在t = 0.5。这总是成立的吗? - Alan Rynne
@t0t3m:那只是瞎猜而已。但我已经添加了一个更正式的论据,说明为什么t=0.5是正确的选择。 - unutbu
我根据@Teeppeem指出的更改编辑了控制点数学。我认为我做对了,但请随时检查。用于视觉确认的图形仍然是相同的。 - Alan Rynne

2
您的二次贝塞尔曲线公式中间项有一个错字。应该是:
B(t) = (1 - t)^2 * P0 + 2 * (1 - t) * t * P1 + t^2 * P2
这意味着您应该使用@unutbu找到的P1=(1,50)并将坐标除以二,从而得到P1=(.5,25)。(如果您自己绘制参数方程则无所谓,但如果您想得到类似于LaTeX的\qbezier(0,0)(.5,25)(1,0),那么就需要修正点。)

控制点P1是这样定义的:在P0P2处的切线相交于P1。这意味着如果(P1)x=(P2)x,图形在其右侧会垂直(这不是您想要的)。

回答您的评论,如果您有一个二次函数y=f(x),那么它关于它的轴对称(几乎是重言)。因此,最大/最小值将出现在根的平均值(以及控制点)。


我正打算问这个问题。 新的控制点(0.5,25)比之前的(1,50)更有意义。 我已经更正了公式。 谢谢! - Alan Rynne

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