Calculate degrees from a 2D heading vector - c#

I am trying to add sprites to a game I am currently working on. I have sprites for north, south, west & east directions. I've already found how to get a direction from degrees, the problem is that I can't seem to calculate the right amount of degrees (0° to 360°) from a normalized velocity vector, called heading. Check figure 1 below for my velocity vector, my heading vector is a normalized clone of this vector.
What I want to achieve is that:
A property degrees: returns the right amount of degrees, based on a current heading/velocity vector.
A method receiving degrees as parameter, which in turn can return a direction which I can use when drawing my sprite.
Figure 1: my 2D velocity vector
My code for calculating the heading vector:
Vector2D heading = Velocity.Clone.Normalize();
I am also not sure if using a heading vector is necessary, so if it's possible or preferred to use the velocity vector, please tell me and include this in your answer.

Related

Unity change vertex normals on collision

I want to change the floor's vertex normals' direction as the ball is rolling on the floor. I just need some direction on how to achieve this.
So far this is the direction that I'm heading:
Make a copy of all the vertex normals of the floor on start.
On collision get the contact point and raycast/spherecast/boxcast to get the affected vertices. (Set variable offset to control how much vertices I want to be affected by the casting)
Find normals related to the vertices.
Rotate the affected normals parrallel to the ball's closest surface point.
As ball moves away from affected's floor's vertices, slowly return the floor normals back to original direction. (Set a variable to control the movement speed of the normal's rotating back to original direction)
I just need help figuring out which type of casting to use and how to rotate the normals parallel to the ball's surface. This is for a mobile platform so performance is a must.
Thanks in advance.
Here's how you'd go about modifying the normals:
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
You'd want to use the vertices list to figure out which indexes to modify (presumably also needing to convert from local space to world space). You could then raycast from the worldspace coordinate to the ball's center,1 and use the raycasthit.normal to figure out what the angle to the ball is.
Some clever vector math from there to figure out the new normal for your plane:
Find the vector perpendicular between hit.normal and Vector3.Up: this vector will be parallel to the plane. If the two vectors are parallel, dump out: your normal is unchanged (or should be returned to its original value, which will be the same vector as the raycast to find the sphere).
Find the vector perpendicular to that vector and hit.normal: this vector will be your new normal.
1 Actually, you'll want to know how far down from the ball's center you should target, otherwise, you'll get the most extreme offsets as the ball moves farther away from the plane. So you want the ball's position on X and Z, but a fixed offset up from the plane for Y. This won't be too difficult to calculate.
I would try something like:
Create a texture for the normals. Each pixel is a normal of a vertex(like a grid). Calculate the correspoding coord between the 3d ball and the position of the normal in the texture and draw a ball/circle/sprite on it (like a sprite) each frame. Then you could use a compute shader to revert them slowy to the default up vector.

Unable to rotate an image in clockwise direction in unity c#

I have an image to be rotated in a pivot point(top) through animation. I am able to rotate it in anti-clockwise direction by simply changing the z-rotation value. But I want to rotate an image in clockwise direction.
If I put a z-rotation value -45 degree, unity converts it to 315 degree and rotates an image in anti-clockwise direction.
The image to be rotated has pivot point at top as shown in the figure below.
You could lerp the angle (single float) instaed of the entire rotation. Lerp from your min angle to max angle and just directly set ,rotation = Quaternion.Euler(0,angle,0).
There shouldn't be any issue with wrapping from 0 to 360; those are the same rotation (and so are 720 and -360, etc).
(you can't force slerp to go a different direction; it's wired to take the shortest route, just like lerp is (though, understandably, it's harder to tell with lerp))
maybe this code help :
needleHub.transform.localRotation = Quaternion.Euler(0, 0, Mathf.LerpAngle(90f, -90f, lerpFactor));
Try changing the interpolation type. I remember having almost the exact same problem and fixing it by changing the interpolation to something other than Eulers Angles.
Thanks #UriPopov for your reference. Finally I am able to rotate an image in clockwise direction through animation. I change the rotation to EulerAngles(Quaternion) as said by UriPopov. But main point to be remember during this animation is that each animation frame should be considered. If one frame is placed empty, then the animation will be in anti-clockwise direction.

I have two points specified as lat/long(s) and would like to insert a new point in between them

I have two points specified as lat/long(s) and would like to insert a new point in between them a certain distance (in meters) from point the initial point.
Presumably I convert the lat/longs to radians and then use a version of midpoint formula?
How can i accomplish this task?
I'm living in c# land btw.
TIA
The exact solution is not that simple (an approximate solution is just given by linear interpolation). You're not going to love it.
The trajectory follows a great circle, which is the intersection between the sphere and a plane through the center and the two given points.
First convert from spherical to Cartesian coordinates. Then by the cross product of the vectors from the center to the two points, determine the direction of the normal to the plane (normalize the vector). Then use the formula for 3D rotation around this axis and rotate the starting point. The rotation angle is given by the desired distance divided by the radius of the Earth. Finally, convert back to spherical coordinates.

Get rotation of a 3D triangle

I have three Vector3 points in 3D space. I need to copy the rotation (the tangent?) of this triangle to the orientation of a 3D model. How can I calculate the triangles Vector3 tangent or create a rotation matrix out of those points?
Finding the angle of a triangle is described here: Find the normal angle of the face of a triangle in 3D, given the co-ordinates of its vertices
Suppose you find the normal and call it N'. It should be trivial for you to write the normal of the "unrotated" triangle, N, eg <1, 0, 0>. It should also be trivial to figure out how to rotate from N to N' and you can create a rotation matrix for it with Matrix.CreateFromAxisAngle in XNA. This matrix should rotate everything like you want.

XNA Rotating a tank properly

Im making a 2D game where the player controls a tank.
I can make the tank, and all, but whats really messing with my mind is how to make it rotate accordingly.
I want it to behave just like the Wii game, Tanks.
Fixed directions, and with no real front and back on the tank.
Driving up, then left should make it rotate to the left.
Driving up, then down should not make it rotate, just drive the other direction.
I red a tutorial a while back about some way to do that by dividing the degrees into 2 180 degree parts. But i have simply not been able to find that damn site again.
I hope you guys are able to understand what im trying to say.
Thanks in advance :)
I assume you're drawing your tank as a sprite? In that case there's an overload of the SpriteBatch.Draw method that allow you to specify the rotation angle around the origin.
SpriteBatch.Draw overload
Here's an example on how to use it from MSDN
The example above will keep rotating your sprite, so you will need to add some custom logic so it will only rotate it according to keyboard input. Here's a simple example on how to check for keyboard input. So add logic that checks if the right or left button has been pressed, and update the rotation angle if they have. If it's the up or down button that has been pressed you simply modify the position of your sprite.
I hope it makes sense, otherwise just let me know.
I think what you're looking for is simply the best way to minimize the rotation of the tank, modulo 180 degrees.
I would use the angle between the desired movement direction and the tank's current direction to start. Make sure this is the minimum angle, then compare that with the angle between the tank's current direction + 180 degrees. Something like:
// smallest angle between the current direction and the desired direction
minAngle1 = Math.Abs(Math.Min(tankAngle - desiredAngle, desiredAngle - tankAngle));
// smallest angle between the opposite direction and the desired direction
oppositeAngle = (tankAngle + 180) % 360;
minAngle2 = Math.Abs(Math.Min(oppositeAngle - desiredAngle, desiredAngle - oppositeAngle));
// get the smaller of two to rotate to
if (minAngle1 < minAngle2) {
// we know that we should rotate the current direction to the desired direction
} else {
// rotate the opposing direction to the desired direction
}
Note you'll need to play with your rotation signs to ensure you're rotating the right way. Also, I've assumed you know your rotation angles, if you have vectors you can simplify this a little bit by using the dot product between the two vectors instead of the angle for comparisons.
Is your problem with the direction of movement based on the angle they have rotated?
Vector2 moveDir = new Vector2(Math.Cos(rotation), Math.Sin(rotation));
position += (moveDir * speed);
Speed here would be a number for how fast you want to move in that direction. position is another Vector2 for the position of the sprite. As Tchami says you can draw it with the rotation using the SpriteBatch.Draw overload. Rotation for the the Cos and Sin methods should be in radians but I think Draw should be in degrees if I remember correctly. MathHelper.ToRadians(degrees) and MathHelper.ToDegrees(radians) should solve that.
There is lots of XNA tutorials and examples on the site http://creators.xna.com/en-US/education/catalog/

Categories

Resources