首页 > 解决方案 > 圆球弹跳的角度反射

问题描述

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

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°)有人可以建立关系吗第一个角度和第二个角度之间?

画质更好...

标签: pythonpygamegeometryanglebounce

解决方案


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

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

使用pygame.math.Vector2.

要计算法线向量,您必须知道“命中”点 ( 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])

推荐阅读