0

我目前正在尝试为我用 Python 编写的 2D 游戏实现平面阴影效果。我在网上找到了大量的教程和方法(http://ncase.me/sight-and-light/)但是,这些都使用多边形作为障碍物,其中所有角点都是已知的,而我的游戏包括界。

我想知道如果 A 和 O 的情况以及圆的半径已知,是否可以计算每个接触点(P 和 Q)的 X 和 Y 坐标或线的梯度。

如果问题不在主题范围内,请提前致谢并道歉,但我无法在其他任何地方找到答案。

4

2 回答 2

1

让我们矢量 V = OP(未知),矢量 Q = AP,矢量 U = AO(已知)
注意 Q = U + V

矢量 V 的长度是半径 R,所以

VX^2 + VY^2 = R^2   //1

向量 V 和 A 是垂直的,所以它们的标量积为零

VX * QX + VY * QY = 0
VX * (VX + UX) + VY * (VY  + UY) = 0
VX * VX + VX * UX + VY * VY  + VY * UY = 0
R^2 + VX * UX + VY * UY = 0   //2

求解方程组 1 和 2 并获得解

LL = U.X^2 + U.Y^2

VY = (R^2 * UY  +/- R * UX * Sqrt(LL - R^2)) / LL
VX = (R^2 - VY * UY) / UX

最后

P.X = O.X + VX
P.Y = O.Y + VY
于 2016-07-07T06:41:50.893 回答
1

诀窍是注意 P 点发生的情况。在 P 点,线 AP 与圆相切,因此角度 APO 为 90 度。同样 AQO 是 90 度。

现在我们知道我们有一个三角形,我们知道 2 个长度和一个角度(我们知道 AO、OP / OQ(相同的东西)和 APO / AQO)。

我们现在使用正弦定理。

 AO/sin(APO) = OP/sin(PAO)
 PAO = asin(OP*(sin(APO)/AO))

记住要注意单位(即使用 90 度作为输入值,然后忘记您的 sin 库函数可能以弧度而不是度返回)。

从这里,您可以通过知道三角形中所有角度的总和为 180 度来找到所有角度。所以现在你有了所有三个角度。

当你从上面的计算中得到角 AOP 时,你可以再次使用正弦定律来计算 AP 的长度。

 AP = sin(AOP) * AO / sin(APO).

请注意 sin(90 度) == 1 (请记住 APO 和 AQO 是 90 度 | pi/2 弧度)。

现在我们有了 AP 的长度。我们现在可以找到 P 的坐标 (x, y),假设 A 在 (0, 0) 处。如果 A 不是原点,只需添加 A 的坐标作为偏移量。

要找到 P 的坐标:

 PxCoord = AxCoord + AP * cos(PAO)
 PyCoord = AyCoord + AP * sin(PAO)

提醒:请检查您的三角函数(sin / asin)是否使用度数或弧度,如果您的函数使用弧度,请确保将 90 度转换为弧度(即 pi/2 弧度)。另请注意,如果是这种情况,您的输出将以弧度表示角度,同样,您将使用 pi 弧度代替三角形中的 180 度。

于 2016-07-06T21:15:03.420 回答