Rotating Axis/Vector2 around origin - c#

I have a problem. I would like to rotate a vector2/values i get from the x and y of my controller joystick by an angle.
for example a basic example would be if i was to press forward with the stick giving me a a value of x: 0 & y: 1, then rotated that by 90 degrees it would give me a value of x:1 & y:0.
This image demonstrates what i want to do also. I appologies that it is poorly drawn its just quick.
I need help where i am going wrong.
I'm not great with vectors but i tried this equation which makes sense to me.
I translated that into c# like this, but it doesn't work properly as the axis aren't producing values as they should do and the values they give are often exceeding 1 which is the max value i put into it.
Vector2 rotatedAxis = new Vector2 (
inputValues.right * Mathf.Cos(rotationAngle) - inputValues.forward * Mathf.Sin(rotationAngle),
inputValues.forward * Mathf.Cos(rotationAngle) + inputValues.right * Mathf.Sin(rotationAngle)
);
The angle isn't an issue that gives me the the rotation from the forward line, which on the graph would be (0.1). Bit of added info if wanted about this angle, just gets the angle player is rotated from normal forward. I want to just transfer that rotation angle onto the axis as well so i get values that have been offset by that angle.
Can anyone help. What am i doing wrong?
Thanks :)

Related

Creating turning animation for up and down or rubiks cube

im creating a rubiks cube solver and simulator for my a level project and i have come across the problem of the top face of the cube not rotating properly. After a few tests of it i have come to the conclusion that the top face is rotating around the axis properly but in order for it to stay in line witht eh rest of the cube i also need to update the other axis. This is my code to rotate the face
for (int i = 0; i < 90 * n; i++)
{
cube[0].rotateY(degree); // degree is defined as Math.PI / 180 as its in radians
cube[3].rotateY(degree);
cube[6].rotateY(degree);
cube[9].rotateY(degree);
cube[12].rotateY(degree);
cube[14].rotateY(degree);
cube[17].rotateY(degree);
cube[20].rotateY(degree);
cube[23].rotateY(degree);
Invalidate();
}
I have tried also rotating the left and right side and they both work correctly while using the same function but for the other axis. i have definitions for the entire cubes rotation stored in rotation with x y and z properties. Initially i thought this wouldnt be a very hard fix so as well as rotating each cube on the y axis i rotated them along the x axis but for -rotation.x * 2 in order to counteract the problem however this didnt work and just transformed it into very weird positions. Im sure its just a simple maths expresion that i need to rotate it by but i cant work it out.
As i found it hard to explain my problem ive created this video to show it visually. You can see that the left and right rotations work although they are not yet animated and the top face rotates round and always snaps back into the original position but not the other 4 correctly. I am also aware that the colours dont come round the cube like they should but this is something i will work on once all the rotations work
Video of current coded soloution
the functions for the rotations simply update the rotation variable and redraws the cube and all the different cube's in the array are just there as i have created 26 smaller cubes to create 1 bigger cube so that rotations can work without just changing the colour.
If anyone has a nice maths equation to rotate this correctly that would be great but if not and you have another way of rotating the cubes in the cube then that would also be great.
Also just a side quest if anyone knows why my code doesnt rotate the side by 1 degree and then redraw it again inside the Invalidate command then id love to hear why.
Many thanks in advance.

How can we calculate Rotation3D Axis (Vector3D) by Line angle in 2D

I have some shapes in the 2D and also I have 3D models created exactly by 2D Shapes that I have , Now I want to rotate my 3d models by bottom line of them and I'm usinf from RotateTransform3D and also AxisAngleRotation3D , So I need Angle,CenterPoint and Vector3D of Axis x,y,z.
Angle to rotate model to up is always 90 degrees.
Also I can calculate angle of each line that I want to rotate 3d model by that line ( Red Lines in the example picture) and center point by 2d but my question is how can I calculate Axis to say it should rotate by which axis(or axises).
var myRotateTransform = new RotateTransform3D(
new AxisAngleRotation3D(
new Vector3D(?, ?, ?), angle),
new Point3D(getCenter.X, getCenter.Y, getCenter.Z));
Also in the picture I attached it here you can see and example to understand it better.
Example
I believe for 0 degree Vector3D must be (-1,0,0) or for 180 degree Vector3D must be (1,0,0), but how can I calculate it automatically?
If you want to rotate the object around the red lines, you need to calculate the direction of the line. I.e. calculate end - start. This direction can then be used as the rotation-axis. You might also want to use a point on said line as the rotation-center since this will make the rotation work similar to a hinge.
You do not specify how you are describing the lines, so it is difficult to provide more specific instructions.

Sphere vs Rotation Box Custom Collision Problem (C#, Unity)

I'm not really like to post questions about problems without doing the research, but I'm close to give up, so I thought I give it a shot and ask you about my problem.
I want to create a custom collision detection in Unity ( So please don't advice "use rigidbody and\or colliders" because I don't want to use them by purpose).
The main idea: I want to detect Basic Sphere and Basic Box collision. I already find AABB vs Sphere theme with the following solution:
bool intersect(sphere, box) {
var x = Math.max(box.minX, Math.min(sphere.x, box.maxX));
var y = Math.max(box.minY, Math.min(sphere.y, box.maxY));
var z = Math.max(box.minZ, Math.min(sphere.z, box.maxZ));
var distance = Math.sqrt((x - sphere.x) * (x - sphere.x) +
(y - sphere.y) * (y - sphere.y) +
(z - sphere.z) * (z - sphere.z));
return distance < sphere.radius;
}
And this code does the job, the box bounding and the sphere center point with radius works fine, I can detect the Sphere collision on Box.
The problem is, I want to Rotating the Cube in Runtime, so that will screw up everything, the bounding will split away and the collision will gone (or collide on random places). I've read about some comments where they said, bounding not works with rotation, but I'm not sure what else can I use to solve this problem.
Can you help me with this topic please? I'll take every advice I can get (except Colliders & Rigidbodies of course).
Thank you very much.
You might try using the separating axis theorem. Essentially, for a polyhedron, you use the normal of each face to create an axis. Project the two shapes you are comparing onto each axis and look for an intersection. If there is no intersection along any of the axes, there is no intersection of shapes. For a sphere, you will just need to project onto the polyhedron's axes. There is a great 2D intro to this from metanet.
Edit: hey, check it out-- a Unity implementation.
A good method to find if an AABB (axis aligned bounding box) and sphere are intersecting is to find the closest point on the box to the sphere's center and determine if that point is within the sphere's radius. If so, then they are intersecting, if not then not.
I believe you can do the same thing with this more complicated scenario. You can represent a rotated AABB with a geometrical shape called a parallelepiped. You would then find the closest point on the parallelepiped to the center of the sphere and again check if that point exists within the sphere's radius. If so, then they intersect. If not, then not.
The difficult part is finding the closest point on the parallelepiped. You can represent a parallelepiped in code with 4 3d vectors: center, extentRight, extentUp, and extentForward. This is similar to how you can represent an AABB with a 3d vector for center along with 3 floats: extentRight, extentUp, and extentForward. The difference is that for the parallelepiped those 3 extents are not 1 dimensional scalars, but are full vectors.
When finding the closest point on an AABB surface to a given point, you are basically taking that given point and clamping it to the AABB's volume. You would, for example, call Math.Clamp(point.x, AABB.Min.x, AABB.Max.x) and so on for Y and Z.
The resulting X,Y,Z would be the closest point on the AABB surface to the given point.
To do this for a parallelepiped you need to solve the "linear combination" (math keyword) of extentRight(ER), extentUp(EU), and extentForward(EF) to get the given point. In other words, what scalars do you have to multiply ER, EU, and EF by to get to the given point? When you find those scalars you need to clamp them between 0 and 1 and then multiply them again by ER, EU, and EF respectively to get that closest point on the surface of the parallelepiped. Be sure to offset the given point by the Parallelepiped's min position so that the whole calculation is done in its local space.
I didn't want to spend any extra time learning how to solve for a linear combination (it seems it involves things like using an "augmented matrix" and "gaussian elimination") otherwise I'd include that here too. This should get you or anyone else reading this off to the right track hopefully.
Edit:
Actually I think its a lot simpler and you don't need a parallelepiped. If you have access to the rotation (Vector3 or Quaternion) that rotated the cube you could get the inverse of that and use that inverse rotation to orbit the sphere around the cube so that the new scenario is just the normal axis aligned cube and the orbited sphere. Then you can do a normal AABB - sphere collision detection.

XNA UnitCircle convert to Radians

I am doing a 2D (from above) game in XNA, but this is more of a math problem.
I am trying to rotate the sprite in the same direction as the direction I push the stick on the Xbox controller.
You see If I pull my stick in a direction I also want my character to face the same way. The Xbox controller gives me cordinates like in the UnitCircle, a X and Y value with the value +1 to -1 and 0 is standard position. And I need the angle in Radians to use it in XNA, please help me with this, I don't know how to convert from Unit Circle to Radians.
I found this http://en.wikipedia.org/wiki/Rotation_matrix but it was very hard to understand
Huge disclaimer: I'm working with ancient and forgotten trig, so please forgive me if I put you wrong!
First up, have a think about what the unit circle information is telling you. It looks something like this:
The orange (x,y) coordinates are telling you in which direction the controller has been moved.
The information tells you the height of the triangle, and the base of the triangle.
What you want to know is the angle at the tip of the triangle that touches the centre.
Another way of looking at our orange triangle is like this.
You want to know the angle in green, and you know the adjacent side (which is your x co-ordinate) and the opposite site (which is your y co-ordinate). A little SOHCAHTOA, and you can see that
tan(θ) = y / x
which we can solve with
θ = (inverse tan) (y/x)
It looks like C# uses radians in tan and atan.
I'd suggest spending some time here: http://www.mathsisfun.com/geometry/unit-circle.html to help get your head around some of these concepts.

Tracking Rotating Sprite

I am messing about in XNA and have run into a problem. I have a 48 * 48 sprite that I can keep track of its location in the game world by the top left corner of the sprite.
I want to be able to rotate the square and still keep track of the same point. For instance if I rotate 90degrees clockwise and the orginal X position was 200 the new X position should be 200 + 48(the size of the width of the image). Its fine for 90 degrees I am able to work that out in my head but each one in between is the problem!
I know there is probably some kind of formula to work this out.
Any help would be great! Oh the square is rotating on its center.
I'm just using spriteBatch.Draw()
spriteBatch.Draw( animations[currentAnimation].Texture,
Camera.WorldToScreen(WorldRectangle),
animations[currentAnimation].FrameRectangle,
color, rotationScale , new Vector2((float)frameHeight/2, (float)frameWidth/2), effect, TileMap.characterDepth);
If you have to keep track of a moving rotating sprite you can't use the top left corner, but its centroid. You already draw your sprite using the centroid to rotate it.
The problem is that the second parameter of your Draw call is a Rectangle, you sholud use a Vector2 position, instead.
You're building your application on top of a 3D graphics library. 3D graphics libraries are very good at solving this kind of problem! Break it down into smaller operations and let the library do the work for you.
First: it's easiest to think about these kinds of questions when you're working in model space rather than world space. In other words: you don't need to worry about where the rotating point is in absolute terms, you only need to worry about where it is relative to the untransformed model (in this case, your sprite without any rotation or translation).
So where is that? Simple:
var pt = new Vector3(-frameWidth / 2f, -frameHeight / 2f, 0f);
Your point of origin is the center of your sprite, so the center of your sprite in model space is (0, 0). This means that the top left corner of your sprite is half the width of the sprite in the negative x direction, and half the height of the sprite along the negative y direction.
Now create an object that represents the desired transformation. You can do this by creating a rotation matrix using XNA's built-in methods:
var transformation = Matrix.CreateRotationZ(MathHelper.ToRadians(90f));
Now apply the transformation to your original point:
var transformedPt = Vector3.Transform(pt, transformation);
This is still in model space, remember, so to get world coordinates you'll need to transform it into world space:
var transformedWorldX = transformedPt.X + spritePosition.X;
var transformedWorldY = transformedPt.Y + spritePosition.Y;
And there you go.

Categories