如何通过已知半径和圆心计算圆上的一个点

4
我有一个复杂的问题,它涉及到我不太自信的数学理解。一些背景可能会有所帮助。我正在为儿童构建一个3D火车模拟器,并使用WebGL在浏览器中运行。我试图创建一个点网络来放置轨道资产(见图像)并为火车提供移动参考。为了帮助解释我的问题,我创建了一个可视化表示,因为我是一个可以编写脚本而不是程序员或数学家的设计师:
基本上,我有3个形状(图A、B和C),尽管它们有宽度,但可以表示为直线(A)和曲线(B和C)。曲线B和C是从A派生(弯曲修改)的,因此长度都相同(l),即112。曲线(B和C)的半径(r)分别为285.5,它们被弯曲的角度(a)为22.5°。
每个形状(A、B和C)都有一个注册点(起始点),由它们各自附加的绿色框的中心所示。
我要做的是创建一个以0,0为起点的“轨道”网络(使用标准笛卡尔坐标系)。
我的问题是在曲线之后放置下一个元素的位置。如果是直线轨道,那么没有问题,因为我可以使用长度作为沿y轴的恒定偏移量,但那会很无聊,所以我需要添加曲线。
D图演示了可能的轨道布局示例,但请理解,我不是在寻找静态答案(基于图像中所有位置的位置),我需要一个公式,无论如何配置轨道都可以应用。
使用D图,我尝试计算第一个弯曲元素之后放置第二个弯曲元素的位置。我使用绘制圆的周长点的公式,给出其圆心坐标和半径(E图)。
我将点1设置为直线的长度(y位置)。我可以轻松地计算出圆的中心,因为那只是偏移y位置、半径(r)的偏移量(x位置)和角度(a),它总是22.5°(顺便说一下,按照公式要求将其转换为弧度)。
通过公式传递值后,我没有得到正确的结果,因为该公式假设我是逆时针从3点钟开始工作,因此我必须从(a)中扣除180并将其转换为弧度才能得到预期的结果。
那确实起作用,如果我想创建一个180°的轨道曲线,我可以使用相同的中心点,并每次从角度中减去22.5°。太好了。但我想要一个更动态的轨道布局,就像D和E图一样。

那么,如何处理图E的第5个点呢?因为它代表了该曲线段的中心点。我完全不知道该怎么做。

另外,作为一个额外的问题,这样做是正确的吗?还是我把事情搞复杂了?

这个问题是阻止我制作游戏的唯一问题,正如您所理解的那样,这是一个相当大的问题,所以提前感谢任何人对此的贡献。


看起来你把事情复杂化了。也许你应该研究一下样条曲线。这是一种数学技术,可以将长路径分成几个较小的函数。因此,在这个例子中,你不需要处理圆形。你只需沿着从原点开始的直线路径行进。然后,你会沿着由函数定义的曲线路径行进(而不是这段圆弧的东西,这只会让你头疼)。每个片段都从前一个片段结束的地方开始,并且每个片段的曲率应该是自包含的。希望这有所帮助。 - bigbenbt
2个回答

7
当您构建轨道时,下一段待放置的轨道位置需要相对于当前轨道末端的位置和方向。我会存储一个(x,y)位置和一个角度a来表示当前点(其中x、y从0开始,a从pi/2弧度开始,这对应于“逆时针从3点钟方向”系统中的直线向上)。然后进行构造。
fx = cos(a);
fy = sin(a);
lx = -sin(a);
ly = cos(a);

这段文字涉及到IT技术,讲述了“前进”和“向左”的向量相对于我们当前面向方向的x和y分量。如果我们想向前移动一个单位,我们需要将(x,y)增加(fx,fy)。

在您的情况下,放置直线轨道的规则如下:

x=x+112*fx
y=y+112*fy

放置曲线的规则稍微复杂一些。对于向右转弯的曲线,我们需要向前移动112*sin(22.5°),然后向右侧步移动112*(1-cos(22.5°),最后顺时针旋转22.5°。在代码中,

x=x+285.206*sin(22.5*pi/180)*fx // Move forward
y=y+285.206*sin(22.5*pi/180)*fy

x=x+285.206*(1-cos(22.5*pi/180))*(-lx) // Side-step right
y=y+285.206*(1-cos(22.5*pi/180))*(-ly)

a=a-22.5*pi/180 // Turn to face new direction

向左转就像向右转一样,只是角度为负。

要放置后续的轨道块,只需再次运行此过程,使用现在更新的a值计算fxfylxly,然后根据下一个轨道块的类型递增xy

还有一点需要考虑;根据我的经验,使用这些轨道块构建形成封闭环路的轨道通常可以按照90°转弯或对称布局来进行。但是,很容易制作出不能完全连接的轨道,而且不明显如何修改它们以使其连接。如果您的程序允许儿童设计自己的布局,则需要记住这一点。


感谢您的回复和详细的解释。我确实认为可能有更简单的方法,并且最终会通过使用三角函数简化这些部分之一,但我会尝试您的建议并回复您。顺便说一句,轨道的路线将由我自己设计,因为我将建立一个轨道编辑器,并且它们几乎不会是环形路线(除了将从主线分支出的小环线)。再次非常感谢,今晚稍后将实现此功能。 - jayfield1979
2
我得到的公式基本相同(只是太慢了... :-)。- 一点说明:如果 l = 112a = 22.5°,则半径为 r = l * 180 / (22.5 * π) = l * 8 / π ≈ 285.206,而不是 r = 285.5 - Martin R
谢谢 - 我太懒了,没有在原帖中检查数字! - Chris Johnson
1
@jayfield1979 哦,我看到我的答案中有一些未匹配的括号,而你的代码以一种不同于我预期的方式匹配了它们... 你需要 (1-cos(angle))(-lx) 而不是 (1-cos(angle)(-lx))。现在已经在答案中修复了。 - Chris Johnson
1
@jayfield1979 实际上,我认为可能还有一个错误;我所称之为“左”向量实际上是一个“右”向量。为了修复,请在出现的地方将 -lx(a) 更改为 lx(a),或者增加 a 而不是减少它。 - Chris Johnson
显示剩余2条评论

0

点5与3和2等距离,但方向相反。


在我贴出的静态示例中(轨道配置A B C),是的,但我的轨道布局会有所不同。虽然这给了我一个想法。我会回复你的。 - jayfield1979

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