4

我一直在对该主题进行大量研究,并发现了一些有用的帖子,但我就是无法做到这一点。

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

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

梁的已知长度在哪里L(为简单起见,我们说它为 1)。是介于 0和X梁的长度之间的值。所以最终的公式是:

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

假设我的起点和终点是P0 = (0,0)and P2 = (1,0)。我怎样才能获得P2(控制点)??我一直在维基百科页面中搜索,但我不确定如何从二次贝塞尔曲线公式中获取控制点:

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

我敢肯定它一定是一个很容易解决的问题……有人可以帮我吗?

PS:我还发现了这个,如何找到定义贝塞尔曲线的数学函数,这似乎解释了如何做与我想要实现的相反的事情。我只是不知道如何扭转它。

4

2 回答 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,我们看到两条曲线重叠:

在此处输入图像描述


我怎么知道在达到最大高度t = 0.5时选择作为参数值?B(t)

嗯,它主要是基于直觉,但这里有一种更正式的方式来证明它:

的 y 分量在达到其最大高度B'(t)时等于 0 。B(t)所以,取 的导数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

于 2013-06-22T19:25:32.913 回答
2

你的二次贝塞尔曲线公式在中期有一个错字。应该是:
B(t) = (1 - t)^2 * P0 + 2 * (1 - t) * t * P1 + t^2 * P2
这意味着您应该取P1=(1,50)@unutbu 找到的那个并将坐标分成两半以获得P1=(.5,25). (如果您自己绘制参数方程,这无关紧要,但如果您想要 LaTeX 之类的东西\qbezier(0,0)(.5,25)(1,0),那么您将需要更正点。)

定义控制点,P1使切线在P0P2相交P1。这意味着如果(P1)x=(P2)x,图形在其右侧应该是垂直的(你不想要的)。

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

于 2013-06-22T20:46:04.853 回答