0
\$\begingroup\$

I am trying to figure out how to calculate the angle to rotate a sprite in z axis to look towards the mouse.

I declared one index -and vertexbuffer and set following vertices in it: VertexBuffer vBuffer; IndexBuffer iBuffer;

    VertexPositionColor[] vertices = new VertexPositionColor[4];
    short[] indices;

       vertices[0] = new VertexPositionColor(new Vector3(0, 0, 0) + position, Color.Blue);
        vertices[1] = new VertexPositionColor(new Vector3(1, 0, 0) + position, Color.Blue);
        vertices[2] = new VertexPositionColor(new Vector3(0, 1, 0) + position, Color.Blue);
        vertices[3] = new VertexPositionColor(new Vector3(1, 1, 0) + position, Color.Blue);


        indices = new short[] { 0, 1, 3, 3, 2, 0 };

        vBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), 4, BufferUsage.WriteOnly);
        iBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, 6, BufferUsage.WriteOnly);

        vBuffer.SetData<VertexPositionColor>(vertices);
        iBuffer.SetData<short>(indices);

Rendering:

            GraphicsDevice.SetVertexBuffer(vBuffer);
        GraphicsDevice.Indices = iBuffer;


      effect.View = Matrix.CreateLookAt(new Vector3(0, 0, -5), new Vector3(0, 0, 1), new Vector3(0, 1, 0));
        effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 0.1f, 1000.0f);
        effect.VertexColorEnabled = true;

        effect.World = Matrix.CreateRotationZ(radians);
        effect.CurrentTechnique.Passes[0].Apply();

        GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 2);

The variable radians is set in the update-method :

            center = new Vector3(0, 0, 0) + position;
        mousePosition = new Vector3(Mouse.GetState().X, Mouse.GetState().Y, 0);

        mousePosition = GraphicsDevice.Viewport.Unproject(mousePosition, effect.Projection, effect.View, Matrix.Identity);

        Vector3 dir = center - mousePosition;

        radians = (float)Math.Atan2(dir.Y, dir.X);

Now I want to solve this problem by avoiding using the method atan2.

Given is the xy-plane. How is it possible to calculate the angle of a vector with the direction (0,0,0) to (mouseX,mouseY,0)? Trying to use a reference vector and calculating then the dot product, dividing it by length to put it in the acos function had given false results.

Can You suggest a solution to this?

Thank you.

EDIT: I just read http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/ which states that many acos implementations give a result between zero and pi... makes sense.

\$\endgroup\$
3
  • \$\begingroup\$ To decide whether the value that acos returns should be taken as-is or negated, you need to know whether the target direction points left or right of the reference. This corresponds to the sign of the sin of the angle, which is a factor in the cross product (a scalar, when performed in 2D). Also, I'm curious why you would want to avoid atan2, specifically. \$\endgroup\$
    – Victor T.
    Apr 15, 2017 at 21:20
  • \$\begingroup\$ Hello, thanks for your reply. I was wondering whether this is possible by avoiding atan2. \$\endgroup\$ Apr 16, 2017 at 23:49
  • \$\begingroup\$ It is, by using the sign of the sin of the angle to decide whether or not to negate the value returned by acos. \$\endgroup\$
    – Victor T.
    Apr 17, 2017 at 3:43

1 Answer 1

1
\$\begingroup\$

I would recommend not using angles. Use linear algebra instead. Once you know the world space location of the mouse pointer pass that onto a method that creates the world matrix for the sprite, then use that matrix for effect.World.

Matrix BuildWorldMatrix(Vector3 mouseWorldLocation, Vector3 spriteWorldLocation)//can eliminate spriteWorldLocation if its always at 0,0,0
{
   Vector3 dirToMouse = mouseWorldLocation - spriteWorldLocation;
   dirToMouse.Normalize();
   return Matrix.CreateWorld(spriteLocation, dirToMouse, Vector3.Forward);
} 
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .