Поворот 2D вектора на малый угол - по часовой стрелке и против часовой стрелки - PullRequest
0 голосов
/ 08 апреля 2020

Мне нужно создать поворот для 2D вектора на небольшой угол (около 0,01 радиана). Мне нужно сделать это в обоих направлениях. Так что в конце у меня есть начальный вектор и два одинаковых вектора на каждой стороне этого начального вектора, наклоненные на небольшой угол.

Я использую C# и WPF (writeablebitmap).

После изучения математики на топи c, если я правильно понимаю, следующий фрагмент кода должен повернуть вектор:

     double xRotated = vector.X * Math.Cos(radians) - vector.Y * Math.Sin(radians);
     double yRotated = vector.Y * Math.Cos(radians) + vector.X * Math.Sin(radians);

Полный код метода, который должен возвращать две точки, начальная точка и повернутая точка -

      public static Point[] RotateVector(PointF start, PointF end, double radians)
        {
            System.Windows.Vector vector = new System.Windows.Vector();
            vector.X = end.X - start.X;
            vector.Y = end.Y - start.Y;

            double xRotated = vector.X * Math.Cos(radians) - vector.Y * Math.Sin(radians);
            double yRotated = vector.Y * Math.Cos(radians) + vector.X * Math.Sin(radians);

            Point[] points = new Point[2];
            points[0].X = (int)start.X;
            points[0].Y = (int)start.Y;
            points[1].X = (int)xRotated;
            points[1].Y = (int)yRotated;

            return points;
        }

Я вызываю этот метод один раз с 0,01 для градусов и затем -0,01. Когда я стреляю лучом в каждый угол экрана, я ожидаю увидеть 2 дополнительных луча с обеих сторон, с небольшим наклоном, на каждом из этих основных лучей. Когда я проверяю это, новые повернутые лучи находятся далеко, хотя это выглядит так, как будто они могут работать на верхнем левом угловом луче.

Я думаю, что поскольку на экране компьютера используются координаты X, координаты Y начинаются с 0> вправо по оси X и от 0 вниз по оси Y, что это как-то связано со мной, так как я не получаю результат, но я не уверен, как это исправить или действительно ли он является источником проблемы. Поэтому я прошу помощи, что мне не хватает?

ОБНОВЛЕНИЕ :: Добавление нескольких фотографий для описания моей проблемы. Я создаю RayCaster. Каждая структура на карте, включая рамки, состоит из линий. Таким образом, каждая линия имеет начальную точку и конечную точку. Луч направляется в каждую начальную и конечную точку линии. Я вычисляю, пересекается ли что-нибудь, и если это так, луч заканчивается на пересечении. Если луч достигнет пункта назначения, конечной точки линии, два дополнительных луча будут выпущены маленькими наклонными ангелами в go за углом, чтобы создать многоугольник видимости. Вот где у меня проблемы. Я выкладываю следующие 3 изображения, которые показывают мой текущий метод и что происходит

Empty canvas, rays are shot to each corners

Поскольку лучи попадают в их конечные пункты назначения, они получают два дополнительных луча. Теперь в идеале эти два дополнительных луча наклоняются с каждой стороны основного луча, чтобы они могли go за углом. Но вы можете видеть на картинке, когда я обводил их кругами, эти дополнительные лучи, координаты которых получены из метода, описанного выше, еще далеко. они нигде не находятся рядом с небольшим наклоном, более того, они вместе на одной стороне главного луча.

Showing non empty map На втором изображении вы видите, что я потянул круги вокруг углов, где должно быть дополнительные лучи идут за углом. но нет ни одного

Caveman fix, but rotating vector is not working yet

Я сделал несколько альтернативных исправлений пещерного человека, которые я вручную установил в пунктах назначения этих дополнительных лучей. Я говорю им, что один луч имеет конечную точку, идущую +50 по x и y по сравнению с основным лучом, а другой -50. Такого рода работы, это создает некоторые ошибки в многоугольнике.

Еще нужно исправить мой вращающийся вектор!


ОБНОВЛЕНИЕ! Мне удалось заставить работать ротацию, я использовал следующий код для поворота точки. Затем проведите линию к этой повернутой точке. Он похож на мой оригинальный код, но содержит несколько дополнительных строк, которые я пока не уверен, как они влияют, но это заставляет его работать. Метод вращается по часовой стрелке, я называю его углами x и 360-x, чтобы получить наклоны с обеих сторон. p1 - ​​точка, которую нужно повернуть, p2 - точка, вокруг которой происходит вращение

  public static Point[] RotateVectorTEST(PointF p1, PointF p2, double angle)
    {
        double radians = (Math.PI / 180) * angle;

        double sin = Math.Sin(radians);
        double cos = Math.Cos(radians);

        // Translate point back to origin
        p1.X -= p2.X;
        p1.Y -= p2.Y;

        // Rotate point
        double xnew = p1.X * cos - p1.Y * sin;
        double ynew = p1.X * sin + p1.Y * cos;

        // Translate point back
        Point[] test = new Point[2];
        Point newPoint = new Point((int)Math.Round(xnew + p2.X), (int)Math.Round(ynew + p2.Y));
        test[0].X = (int)Math.Round(p2.X);
        test[0].Y = (int)Math.Round(p2.Y);
        test[1] = newPoint;


        return test;

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...