#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));
}
это исправило пропуск, поворот назад, сокращение длины и остановку.
Надеюсь, это поможет кому-то вроде меня.