圆圈弹跳球的角度反射

Angle Reflexion for bouncing ball in a circle

我正在制作一个带有一些弹跳元素的游戏(我使用 pygame), 我的元素有两个属性,一个是角度,一个是速度 这是元素移动的方式:

mvx = math.sin(self.angle) * self.speed  
mvy = -math.cos(self.angle) * self.speed  
self.x += mvx  
self.y += mvy

我的问题是:我知道顶部的角度 (99.6°),我有碰撞点 (x 和 y),但我找不到底部的角度 (42.27°) 有人可以在第一个角度和第二个角度之间建立关系吗?

图片更好...

三角形的内角之和需要180°。此外,角度 99.96° 补充了它旁边三角形的角度(称为 A),即 99.96° + A = 180° 所以 A = 180° - 99.96°B = 42.27°底角的呼唤。对于最后一个角 C,我们可以使用它与另一个等于 2 * 28.85 = 57.7° 的角的顶点相对。 那么:

A + B + C = 180°

180° - 99.96° + 42.27°  + 2 * 28.85° = 180°

180° - 99.96° + 42.27°  + 2 * 28.85° = 180°

-99.96° + 42.27°  + 2 * 28.85° = 0°

42.27°  + 2 * 28.85° = 99.96°

B + C = Top angle

P.S.: 我知道数值不完全相等,但肯定是因为小数点四舍五入

我建议计算圆表面上入射矢量的 reflection 矢量。
下式中N为圆的法向量,I为入射向量(弹球的当前方向向量),R为反射向量(出射方向向量)弹跳球):

R = I - 2.0 * dot(N, I) * N.

使用pygame.math.Vector2.

要计算法向量,您必须知道 "hit" 点 (dvx, dvy) 和圆心 (cptx, cpty):

circN = (pygame.math.Vector2(cptx - px, cpty - py)).normalize()

计算反射:

vecR = vecI - 2 * circN.dot(vecI) * circN

新的角度可以通过math.atan2(y, x)计算得到:

self.angle  = math.atan2(vecR[1], vecR[0])

代码清单:

import math
import pygame
px = [...] # x coordinate of the "hit" point on the circle
py = [...] # y coordinate of the "hit" point on the circle

cptx = [...] # x coordinate of the center point of the circle
cpty = [...] # y coordinate of the center point of the circle

circN = (pygame.math.Vector2(cptx - px, cpty - py)).normalize()
vecI  = pygame.math.Vector2(math.cos(self.angle), math.sin(self.angle))
vecR  = vecI - 2 * circN.dot(vecI) * circN

self.angle = math.pi + math.atan2(vecR[1], vecR[0])