Моделирование отскока шайбы от наклонной стены

Разрабатываю модель, позволяющую описать полёт шайбы в туннеле соответствующей формы (2 прямые стены и 2 стены, наклонённые под одним и тем же углом). Алгоритм, который я использую, чтобы сделать отскок шайбы от наклонной стены:

  1. Получаем диапазон значений для y: [y_шайбы - радиус_шайбы; y_шайбы + радиус_шайбы]
  2. С небольшим шагом step для каждого y находим x = (y - tunnel_height) / tg(angleWall), где tunnel_height - высота "прямой части" туннеля (т.е начальный y для наклонной стены), а angleWall - угол, под которым расположены наклонные стены.

P.S Так как наклонные стены заданы прямой, то их уравнение: y = tg(angleWall)*x + tunnelHeight

  1. Для каждой полученной точки (x, y) проверяем, "лежит" ли она на окружности шайбы (т.е есть ли соприкосновение с ней)
  2. Если мы нашли такую точку, то делаем отскок шайбы от стены, если нет, то шайба летит дальше по туннелю.

Часть кода, в которой выполняется описанный алгоритм:

            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; 
        }

Наконец-то, проблема: шайба проходит сквозь стену, от которой должен был быть отскок и совершает его в абсолютно другом месте. Пример

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


Ответы (0 шт):