【问题标题】:Detect "Kinks" in Parallel Lines to Bezier Curves检测贝塞尔曲线平行线中的“扭结”
【发布时间】:2012-04-17 12:56:57
【问题描述】:

我希望有人可以帮助我找出一种计算成本低廉的方法来检测与贝塞尔曲线平行的直线上的扭结,正如您在此处看到的那样

我想要做的是能够确定扭结的交点,在交点之前具有起点的线段以及在扭结之后具有终点的第一段。这样我就可以简单地删除任何不必要的路段,并调整第一个和最后一个路段以在交叉路口相遇。

抱歉,如果我使用了不正确的术语。但据我了解,我定位这些线段的方式是确定贝塞尔曲线(黄色)的线段的单位向量并将其乘以偏移量并找到法线向量以创建两个新的起点和终点用于偏移段(白色)。

数学不是我的强项,所以我希望有人能推动我朝着正确的方向前进。

编辑:图像实际上已由 HTML 调整大小,所以如果您很难看到我在说什么,这里是直接链接:http://i.stack.imgur.com/xtils.png

【问题讨论】:

标签: c# math bezier


【解决方案1】:

作为第一个近似值,计算您的Bezier curveradius of curvature。如果偏移量大于或等于曲率半径,则应寻找扭结。

具体来说,对于带有控制点P0, P1, P2, P3 的三次贝塞尔曲线:

B(t) = P0 * (1-t)^3 + P1 * 3*t*(1-t)^2 + P2 * 3*t^2*(1-t) + P3 * t^3
-> B'(t)  = (P1-P0) * 3*(1-t)^2 + (P2-P1) * 6*t*(1-t) + (P3-P2) * 3*t^2 
-> B''(t) = (P2+P0-2*P1) * 6*(1-t) + (P3+P1-2*P2) * 6*t

let:  cross2d(p, q) = p.x*q.y - p.y*q.x
then, radius of curvature = |B'(t)|^3 / cross2d(B'(t), B''(t))

我已将曲率半径保留为带符号的形式;该标志应指出您可以预期扭结的曲线一侧。

注意:你可以有零曲率半径,或无限曲率半径;将|B'(t)|^3signed_offset * cross2d(B'(t), B''(t)) 进行比较可能会更好。

【讨论】:

  • 太棒了。这似乎会奏效。我会试一试,然后回复你。可能需要我一段时间。 :) +1
  • 如果这是一个愚蠢的问题,请原谅我,但就像我说的数学不是我的强项。虽然您的 cross2d(p, q) 函数注意到我的点 P 是 x 和 y 坐标,但 B、B' 和 B'' 函数没有。这是否意味着我只为每个轴运行一次?
  • B(t)B'(t)B''(t) 应该是二维向量,就像 P0P1P2P3 一样。另外,请注意|B'(t)| 应该采用二维向量的长度。最好使用Vector2 结构(或您当前用于二维点的任何现有结构),因此您不必多次重新计算贝塞尔权重。但是,如果需要,您可以编写标量函数并为每个轴运行它们。请记住,在计算向量长度和 cross2d() 时,您需要再次将它们放在一起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 2013-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多