Моделирование отскока шайбы от наклонной стены
Разрабатываю модель, позволяющую описать полёт шайбы в туннеле соответствующей формы (2 прямые стены и 2 стены, наклонённые под одним и тем же углом). Алгоритм, который я использую, чтобы сделать отскок шайбы от наклонной стены:
- Получаем диапазон значений для
y: [y_шайбы-радиус_шайбы;y_шайбы+радиус_шайбы] - С небольшим шагом
stepдля каждогоyнаходимx = (y - tunnel_height) / tg(angleWall), гдеtunnel_height- высота "прямой части" туннеля (т.е начальный y для наклонной стены), аangleWall- угол, под которым расположены наклонные стены.
P.S Так как наклонные стены заданы прямой, то их уравнение: y = tg(angleWall)*x + tunnelHeight
- Для каждой полученной точки
(x, y)проверяем, "лежит" ли она на окружности шайбы (т.е есть ли соприкосновение с ней) - Если мы нашли такую точку, то делаем отскок шайбы от стены, если нет, то шайба летит дальше по туннелю.
Часть кода, в которой выполняется описанный алгоритм:
bool onCircle = false;
double y_min = hockeyPuck.y - hockeyPuck.radius;
double y_max = hockeyPuck.y + hockeyPuck.radius;
for (var temp_y = y_min; (temp_y + step <= y_max) && (!onCircle); temp_y += step)
{
double x = (temp_y - leftDown.y) / Math.Tan(leftUp.angleRadians); // doesnt matter left wall or right
onCircle = IsPointOnCircle(x, temp_y, hockeyPuck.x, hockeyPuck.y, hockeyPuck.radius, 0.01);
}
if (onCircle)
{
switch (hockeyPuck.direction)
{
case DIRECTION.LEFT:
hockeyPuck.BounceWall(leftUp.angleDegree);
break;
case DIRECTION.RIGHT:
hockeyPuck.BounceWall(rightUp.angleDegree);
break;
case DIRECTION.UP:
break;
case DIRECTION.DOWN:
break;
}
}
Функция, проверяющая, находится ли примерно точка на окружности шайбы:
public static bool IsPointOnCircle(double x, double y, double h, double k, double r, double eps)
{
double x1 = x - eps,
x2 = x + eps;
bool expr1 = (x1 - h) * (x1 - h) + (y - k) * (y - k) <= r * r,
expr2 = (x2 - h) * (x2 - h) + (y - k) * (y - k) >= r * r;
return expr1 && expr2;
}
Наконец-то, проблема: шайба проходит сквозь стену, от которой должен был быть отскок и совершает его в абсолютно другом месте.

Не могу понять, где допустил ошибку. Может быть кто-то заметит