【问题标题】:How to nearly connect two points with arc-like angled segments?如何用弧形角段几乎连接两个点?
【发布时间】:2021-09-06 18:41:25
【问题描述】:

假设我们在 2D 空间中有两个点:A(蓝色正方形的中心)和 B(橙色正方形的中心)。 我们还得到了几条固定大小的线以及一条具有最小长度的无限线(如射线)。 此外,我们还有 A 的起始角 alpha。

现在我们如何才能连续排列从 A 开始的固定长度线,然后是无限线,以使第一条线的角度为 alpha 并且无限线正好穿过 B? 另外还有一个限制:

  • 两条线之间的角度应该相同(这意味着许多值的星座使解决方案成为不可能,但只考虑具有可能解决方案的那些)

结果可能如下所示(在此示例中,所有段的长度都相同)。想象一条从最后一段延伸的线(代表最小长度的射线)击中 B。

现在我找到了一个程序解决方案,从 A 开始,线段之间的夹角为 180°,并检查来自最终线段的射线是否击中 B。根据这条射线的哪一侧,B 位于,它从 A 重新开始减少或增加角度,直到它超过目标。然后它将步长减半并继续反向直到下一个过冲,依此类推。最终,当步数降至阈值以下时,这将结束。

这张图片展示了寻找半精确角度的所有尝试: 黄色部分是长度有限的部分,其他颜色是无限光线(其中蓝色是解决方案)。

不幸的是,当需要高精度时,这很快就会变得计算量很大。

是否必须有数学方法\解决方案?

我已经意识到这条弧线显然是一个圆的一部分,而且该圆的原点必须位于 A 线的某处,角度为 alpha+/-90°(因此起始线是圆的切线并且具有精确的角度 alpha)。 现在的问题是,如何计算这个圆的半径,使得沿其圆周上的点截取的线段具有所需的长度?

希望有人有想法。 非常感谢!

如果有人感兴趣,请参考上下文:这是针对物理模拟中的一种特殊类型的“关节”,例如用于使网格动画对象灵活且可真实弯曲但不可拉伸。以人体脊柱为例。

这就是为什么线段有一个强制的固定长度,在实践中,B 被强制在射线段的最小长度的末端,但是物理影响可能会稍微拉开它,所以它有要不断修正。 该解决方案将产生比分段之间的单个接头更好的结果,这些接头可以以丑陋的方式以之字形塌陷。 如果准确度足够高,程序计算解决方案看起来已经很有前景,但它的性能不如实时模拟的预期......

【问题讨论】:

  • 如果你想要一种数学方法,那么最好在 math.stackexchange.com 上询问
  • 起始角 alpha 在什么线/方向和什么线/方向之间?因为我没有看到第二张图片上的迭代解决方案尊重这个 alpha。射线的最小长度是多少?是固定数量的一个段和相同的固定长度还是每个段都有自己的长度?
  • 这个问题的未知数是线段之间的角度alpha(与最后一段和射线之间的角度相同)。使用三角函数和坐标(点 A、B)通常意味着求解未知数为 alpha 的超越方程。这个方程需要通过迭代来求解。但是你已经找到了一个迭代算法。恕我直言,您最好专注于改进算法。

标签: math geometry game-physics


【解决方案1】:

如果我正确地理解了这个问题,那么解决方案似乎可以一次性计算出来,而无需像您一直在实施的那样进行迭代近似。这是我对这个问题的看法:

【讨论】:

  • 你能进一步解释为什么角度EAD必须是n theta吗?我没看到
  • @AakashM EAD = EOD / 2 = AOF / 2 = ADFEOD = 2 n theta。参见例如en.wikipedia.org/wiki/Inscribed_angle
  • 抱歉耽搁了,我需要一些时间来解决这个问题。非常感谢您的帮助!这令人印象深刻。然而,还不能把它变成代码。被困在我们在θ公式中从哪里得到α射线?或者那是哪个角度?
  • @DragonGamer alpha 是水平轴x 与图片上第一段AE 的夹角。至少我是这样解释你的条件的:“第一行的角度是 alpha”。
  • @DragonGamer 哦,那是a_ray 不是alpha,是乳胶字体使它看起来像alpha。 |BF| = a_ray 是最后一段的长度,你称之为射线。因此,|BD| = |BF| - |DF| = a_ray - a。当您修复它时,您可以计算其余部分。
【解决方案2】:

因此,您正在搜索通过定义切线穿过两个端点的圆。两个轴之间的简单 O(1) 交点就可以了:

  1. 从垂直于切线的每个端点投射光线/轴

    所以在二维中要么使用参数圆方程,参数为切线 +/- 90deg 或者如果你有方向矢量交换 x,y 并否定其中一个

  2. 找到光线/轴的交点(圆心(x0,y0)

    只需在谷歌上搜索方程式或从此处提取自己的内容:

  3. 计算圆半径r作为圆心到任意端点的距离

    r = sqrt( (ax-x0)^2 + (ay-y0)^2 );
    

  4. 计算每个端点的起始结束角度

    a = atan2(ay-y0,ax-x0);
    b = atan2(by-y0,bx-x0);
    
  5. 计算缺失点

    c = a + (b-a)*(i/(n-1))
    x(i) = x0 + r*cos(c)
    y(i) = y0 + r*sin(c)
    i = 0,1,2,3,...,n-1
    

    注意a,b 可能需要稍作调整才能覆盖圆的正确部分(匹配切线并避免交叉 0/360 度)。通常的补救措施是交换a,b 和/或将 360 度添加到其中之一。基于切线的缠绕和a<b的结果...

【讨论】:

  • 我认为这不能回答 OP 的问题。 “给定切线”不是一个要求。最后一个“段”的长度可能与前一个不同,它是一条射线。
【解决方案3】:

无论是通过几何方法还是分析方法,都可以稍微简化迭代中要求解的方程。然而,以任何方式避免求助于数值计算可能是不可能的。

原来的问题

据我了解,原来的问题总结如下:

解析解

虽然有一个geometry 标签,但我想在下面展示我的analytical 方法。

注意:tan^(-1)[y, x] = atan2(y, x)

虽然我们可以在方程 (2) 中消除代价高昂的 summation,但是最终方程 (3) 无法解析求解。因此,我们仍然需要使用bisection method 或适当范围内的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    • 2010-12-21
    • 2016-12-29
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多