Вращение 2-векторов, перемещение назад и пропуск областей. C#

#c# #rotation #2d #vectormath

#c# #вращение #2d #vectormath

Вопрос:

Я пытаюсь использовать вращение 2-векторов, но столкнулся с двумя проблемами. Во-первых, кажется, что векторы вращаются в обратном направлении, а во-вторых, векторы перемещаются между двумя областями при вращении.

это код, который я использую для вращения (в векторном классе, с double x и double y ):

 public double radians()
{
    return Math.Atan2(y, x);
}

public double len()
{
    return Math.Sqrt(Math.Pow(x, 2)   Math.Pow(y, 2));
}

public vector mul(double d)
{
    return new vector(x * d, y * d);
}

public vector div(double d)
{
    return new vector(x / d, y / d);
}

public vector unit()
{
    return div(len());
}

public vector rotate(vector v)
{
    double theta = v.radians();

    return new vector(
        x * Math.Cos(theta) - y * Math.Sin(theta),
        x * Math.Cos(theta)   y * Math.Sin(theta))
        .unit().mul(len()); // without this, the rotated vector is smaller than the original
}
  

Когда я использую их для поворота вектора, он вращается против часовой стрелки, а не по часовой стрелке, я думаю, так и должно быть. Чтобы продемонстрировать, изображение:

исходный вектор в золотом цвете, повернутый в синий

Он также вращался намного больше, чем я думаю. Другая проблема, которую сложнее объяснить, заключается в том, что вращение работает плавно примерно на две четверти его диапазона, но пропускает два других. Еще одна проблема, которую я обнаружил, заключается в том, что если угол, на который я поворачиваю вектор, мал (в моем тестировании все, что прошло (1, 10)), вращение начинается сильно, но замедляется и в конечном итоге просто останавливается. Мне кажется, что это проблема точности с C # double , но я попытался это исправить, убедившись, что длина повернутого вектора не меняется.

В любом случае, если вы сможете определить причину одной или всех моих проблем, это было бы очень ценно.

Ответ №1:

Я решил свои проблемы, изменив функции radians() и rotate() . Другие функции были в порядке.

radians() исправлено:

 public double radians()
{
    return Math.Atan2(x, y); // swap the x and y
}
  

rotate() исправлено:

 public vector rotate(vector v)
{
    double theta = v.radians();

    // use the clockwise rotation matrix:
    // |  cos(theta) sin(theta) |
    // | -sin(theta) cos(theta) |
    return new vector(
        x * Math.Cos(theta)   y * Math.Sin(theta),
        x * -Math.Sin(theta)   y * Math.Cos(theta));
}
  

это исправило пропуск, поворот назад, сокращение длины и остановку.

Надеюсь, это поможет кому-то вроде меня.