在保持大小的同时以弧度旋转向量

时间:2019-02-23 11:58:08

标签: c# math vector 2d

在这个特殊的小游戏中,我需要能够向左或向右旋转汽车,同时仍要保持其面向任何方向的速度。这是我遇到的代码块:

private void turn(float angleDelta)
    {
        double r = Math.Sqrt(Math.Pow(carPosition.X, 2) + Math.Pow(carPosition.Y, 2));
        double theta = Math.Atan2(carPosition.Y, carPosition.X);

        carPosition = new Vector2((float)(r * Math.Cos(theta)), (float)(r * Math.Sin(theta)));


    }

    protected override void Update(GameTime gameTime)
    {
        base.Update(gameTime);
        float angularVelocity = MathHelper.ToRadians(3);
        if (Keyboard.GetState().IsKeyDown(Keys.Left))
        {
            turn(-angularVelocity);
        }
        if (Keyboard.GetState().IsKeyDown(Keys.Right))
        {
            turn(angularVelocity);
        }
        carPosition += carVelocity;
    }

特别是在turn(float angleDelta)方法中,我觉得我已经正确输入了代码,但是我不确定angleDelta可以放在哪里。我尝试将angleDelta添加到carPosition中,但这只会产生错误。

1 个答案:

答案 0 :(得分:0)

这是2D中众所周知的矩阵变换:

u' = A*u

其中

u = (ux, uy) as a column vector
u' = (ux', uy') as a column vector
A = | cos(theta) -sin(theta) |
    | sin(theta)  cos(theta) |

速度是一阶张量,是一个既具有大小又具有方向的向量。

如果您了解向量以及如何转换向量,这将是一个简单的问题。

这就是我用Java编写代码的方式。您应该能够轻松将其转换为C#。如您所见,二维平面旋转是一个单一的过程-大小可以按照您的意愿保留。

/**
 * Created by Michael
 * Creation date 2/23/2019.
 * @link https://stackoverflow.com/questions/54841329/rotate-a-vector-by-radians-whilst-preserving-magnitude/54843395#54843395
 */
public class VectorDemo {

    public static final int VECTOR_2D_SIZE = 2;

    public static void main(String[] args) {
        double [] u = { 4.0, 0.0 };
        double umag = magnitude(u);
        System.out.println(print(u));
        System.out.println(String.format("u magnitude: %10.4f", umag));
        double angle = Math.toRadians(45.0);
        double [] v = rotate2D(u, angle);
        double vmag = magnitude(v);
        System.out.println(print(v));
        System.out.println(String.format("v magnitude: %10.4f", vmag));
    }

    public static double magnitude(double [] u) {
        if (u == null) throw new IllegalArgumentException("Vector u cannot be null");
        double magnitude = 0.0;
        for (int i = 0; i < u.length; ++i) {
            magnitude += u[i]*u[i];
        }
        return Math.sqrt(magnitude);
    }

    public static double [] rotate2D(double [] u, double angleRadians) {
        if (u == null) throw new IllegalArgumentException("Vector u cannot be null");
        if (u.length != VECTOR_2D_SIZE) throw new IllegalArgumentException("2D vectors only");
        double [] v = new double[VECTOR_2D_SIZE];
        double [][] a = new double[VECTOR_2D_SIZE][VECTOR_2D_SIZE];
        a[0][0] = +Math.cos(angleRadians);
        a[0][1] = -Math.sin(angleRadians);
        a[1][0] = +Math.sin(angleRadians);
        a[1][1] = +Math.cos(angleRadians);
        for (int i = 0; i < VECTOR_2D_SIZE; ++i) {
            v[i] = 0.0;
            for (int j = 0; j < VECTOR_2D_SIZE; ++j) {
                v[i] += a[i][j]*u[j];
            }
        }
        return v;
    }

    public static String print(double [] v) {
        return String.format("(%10.4f, %10.4f)", v[0], v[1]);
    }
}

这是我的输出:

(    4.0000,     0.0000)
u magnitude:     4.0000
(    2.8284,     2.8284)
v magnitude:     4.0000