参数离散曲线的切线

时间:2010-03-31 12:56:04

标签: c++ qt math geometry

我有一条参数曲线,比如说参数是索引的两个双精度矢量,我必须计算任意给定点(索引)处该曲线的切线角度。

有关如何操作的任何建议或链接?

感谢。

6 个答案:

答案 0 :(得分:6)

这是一个简短的公式,相当于(我认为)pau.estalella的回答:

m [i] =(y [i + 1] - y [i-1])/(x [i + 1] - x [i-1])

这恰好很接近于该点的斜率(x [i],y [i])。

你的问题提到了“切线的角度”。具有斜率m [i]的切线使得具有正x轴的角度反正切(m [i])。如果这是您所追求的,您可以使用双参数arctangent(如果可用):

angle [i] = atan2(y [i + 1] - y [i-1],x [i + 1] - x [i-1])

这将正常工作,即使x [i + 1] == x [i-1]。

答案 1 :(得分:3)

您遇到的第一个问题是甚至定义曲线顶点之一的切线。考虑例如你有两个数组:

x = { 1.0, 2.0, 2.0 };
y = { 1.0, 1.0, 2.0 };

然后在第二个顶点,你有一个90度的线方向变化。在那个地方,切线甚至没有数学定义。

回答下面gregseth的评论

我想在你的例子中,第二点的“切线”是平行于(P0,P2)穿过P1的线......哪种给我答案:对于索引N的任何点平行于(N-1,N + 1)通过N.这是一个不太接近的近似值吗?
这取决于你使用它的是什么。考虑例如:

x = { 1.0, 2.0, 2.0 };
y = { 1.0, 1000000, 1000000 };

这基本上是具有非常高的垂直线的L形。在你的建议中它会给你一个几乎垂直的切线。这是你想要的,或者你更喜欢在这种情况下需要45度切线?它还取决于您的输入数据如何定义它。

一种解决方案是将两个矢量连接到顶点,对它们进行标准化,然后使用您的算法。这样你就可以在上面的例子中得到一个45度的切线。

答案 2 :(得分:3)

我建议您查看the Wikipedia article on numerical differentiation作为开始。在你走得更远之前,确定你想要切线的目的,并决定你是否需要尝试比文章中的简单方案更复杂的方案。

答案 3 :(得分:2)

计算一阶导数:dy / dx。这给你切线。

答案 4 :(得分:1)

点P处的平滑曲线的切线是参数直线P + tV,其中V是曲线相对于“参数”的导数。但是这里参数只是数组的索引,数值微分是一个难题,因此近似我将使用(加权)least squares approximation的正切。

换句话说,选择围绕您的兴趣点P的曲线的三个或五个点(即P [i-2],P [i-1],P [i],P [i + 1]和P [i + 2],如果P == P [i],并且在最小二乘意义上用直线近似它们。分配给中间点P的权重越大,该线越接近P;另一方面,你赋予极值点的权重越大,直线越“正切”,也就是说,它越接近你在P附近的曲线。

例如,关于以下几点:

x = [-1, 0, 1]
y = [ 0, 1, 0]
没有定义切线的

(如Anders Abel的答案), 这种方法应该产生一条接近点(0,1)的水平直线。

答案 5 :(得分:0)

您可以尝试计算通过给定点的插值曲线的正切(我想到的是一个非常容易导出的三次样条)或直接从数据点计算切线。

您可以通过以下方式找到导数的粗略近似值 设曲线C通过点p1,p2和p3。在点p2处,您有两个可能的切线:t1 = p2-p1和t2 = p3-p2。您可以通过简单计算它们的平均值来组合它们:0.5 *(t1 + t2)  或者你可以根据它们的长度(或它们的倒数1 /长度)来组合它们

请记住规范化生成的切线。

为了计算切线和曲线之间的角度,请记住两个单位矢量的点积给出它们之间角度的余弦。取得到的切线t和单位向量v2 = | p3-p2 |,acos(dot(t,v2))给出你需要的角度。