How to add camera to Matrix4x4 rotation - c#

I am trying to rotate a cube using System.Numerics.Matrix4x4 and SDL2 for graphic output. i have a hard time understanding the Matrix rotation concept.
I can do it, like so:
matrix *= Matrix4x4.CreateRotationX(deg);
matrix *= Matrix4x4.CreateRotationY(deg);
matrix *= Matrix4x4.CreateRotationZ(deg);
Then I'm using Vector3.Transform() on the points in the cube and draw lines between them. Looks... alright, it's rotating in place. But how do I get perspective? How to get a camera into the mix?
What about this method:
matrix *= Matrix4x4.CreateFromAxisAngle(new Vector3(2, 2, 2), (float)rad);
I am not sure how I'm supposed to use the vector there, or what it's supposed to do. My cube grows and stretches out weirdly... see pic of when the matrix is applied 10, 45 and 90 degrees on the cube:
https://www.dropbox.com/s/hui5jvky7cexciq/10_45_90.png?dl=0
How should I do this properly?

Related

Problems using camera in OpenGL

Hi, I am making an application which can make camera rotate around the model, I have successfully imported the obj format model
But I meet the problem when rotate the camera, the model will disappear as you can see
gl.Perspective(180, (double)Width / (double)Height, 100, 50000f);
The key code for rotating camera:
Calculate the center point of the model
currentX = Math.Sin(angle) * radius;
currentZ = Math.Cos(angle) * radius;
gl.LookAt(currentX,0,currentZ,
centerPoint.X, centerPoint.Y, centerPoint.Z,
0, 1, 0
);
Try modifying the near clipping plane to be much closer to the camera, and also lower the FoV angle. Try this:
gl.Perspective(90, (double)Width/(double)Height, 0.01f, 100.0f);
Check if the model is not closer than the near clipping plane. Check also the face culling: if your camera is inside the mesh, you are looking at the back faces of the polygons, which probably are not rendered.

How to increase rotation angle with Unity using Quaternion

In my Unity scene, I'm trying to rotate a cube wrt the head movement. Here's my code:
m_cubeName.rotation = Quaternion.Lerp(m_cubeName.rotation, m_Camera.rotation, Time.deltaTime);
It seems to work and rotates exactly the same angle as the head. I want to use a multiplying factor so that when the head rotates, say 1 degree, the cube rotates 2 degrees.
So how do I convert the qauternion rotation value to something I can multiply with a factor?
To rotate the cube by a factor of 2, just rotate it twice:
Quaternion doubleCameraRotation = m_Camera.rotation * m_Camera.rotation;
m_cubeName.rotation = Quaternion.Lerp(
m_cubeName.rotation,
doubleCameraRotation,
Time.deltaTime);
To multiply the rotation by a non-integer factor, you can use Quaternion.LerpUnclamped, (or SlerpUnclamped for better accuracy) then pass the scaling factor as t. For example:
Quaternion doubleCameraRotation =
Quaternion.LerpUnclamped(Quaternion.identity, m_Camera.rotation, 2f);

Specify a Triangle's Vertices based on radius and center coordinate

Is there a code formula for this? I am using C# and XNA, and in my class I have an array of three vectors (representing the vertices of the triangle), as well as a separate vector coordinate.
I plan to update these positions in the loop as it escalates further towards the top of the screen.
I'd ask maths.stackexchange.com, but seeing as how this applies to programming (and I personally am better at reading code as opposed to math itself - I'm still taking Algebra in school), I think it would make more sense for me to ask it here.
Edit
Yes, I am looking for an equilateral triangle. Or any triangle, for that matter. It doesn't matter what it is. All I am looking for is a formula; is that so hard to ask for?
Teh Problem
Basically, the problem I am trying to solve is to shoot a triangle out of my player (think Space Invaders; i.e., the triangle acts as a ray from the ray gun). What I need is a formula of code which will allow the triangle to be rendered based on its center position and radius, as the triangle will move upwards on its Y coordinate. I have the draw calls, and they work, but the problem is that the triangle when put in a for loop draw iteration (where the center vector position - on the Y coordinate - is incremented by N) simply sits next to the player's position when being drawn.
I think this is what you are looking for...
the angle is the orientation of the triangle...
this build a triangle....
void BuildTriangle(Vector2 Center, float Radius, float Angle, Vector2[] tri)
{
for (int i=0; i<3; i++)
{
t[i].X = Center.X + Radius * (float) Math.Cos(Angle + i * 2 * MathHelper.PI/3);
t[i].Y = Center.Y + Radius * (float) Math.Sin(Angle + i * 2 * MathHelper.PI/3);
}
}
if you want to move it, add to the center a velocity vector and rebuild it...

Get rotation matrix between two two transform matrices (XNA)

I have an marker detection system for AR at the moment, it detects markers in the scene and gives the transform matrix of the camera for each marker in the scene.
Let's say I have found 2 markers. I am trying to find the rotation matrix I will have to apply to one of the markers in order to get it to match the orientation of the other marker.
I figured it should be the same as computing the transform matrix of one marker to another and decomposing the transform to obtain the x,y,z euler rotation matrix but I cannot seem to get this to work. I am using C# with XNA.
In code:
Matrix marker1 = markerTransforms[0];
Matrix marker2 = markerTransforms[1];
Matrix relativeTransform = Matrix.Invert(marker1) * marker2;
Quaternion rotation;
Vector3 scale;
Vector3 translation;
relativeTransform.Decompose(out scale, out rotation, out translation);
Matrix rotationMatrix = Matrix.CreateFromQuaternion(rotation);
This above doesn't seem to work.
Another question would be how to extract out the x,y,z euler rotations from the rotation matrix?
EDIT:
I found a function to convert the quaternion to euler following x,y,z order here: http://forums.create.msdn.com/forums/p/4574/23763.aspx
Applying this to my code I got the following results:
The actual rotation should be: x:0 y:0 z:-0.52
I also noticed that the y and z changed a lot depending on how I positioned the camera.
The two transform matrices I obtain from the marker detector contain the orientation and translation of the camera relative to one of the markers as explained here: http://www.hitl.washington.edu/artoolkit/documentation/tutorialcamera.htm
I have converted them to XNA format and I know them to work correctly as I can draw the corners onto the screen and it matches up with what the camera is seeing.
The solution I like the most is using quaternions. If you have one orientation described by q1, and other described by q2, you can get from one orientation to the other by
q1=q*q2
being q the rotation you are looking for.
q = q1 * (q2)^-1; q = q1 * conj(q2);
You just have to convert from rotation to quaternion and quaternion to rotation.
Just make sure that you normalize quaternions so the equivalences are true. In the pages I linked you have all the necessary formulas, explanations, even code in Java, c++. Really worth adding to favorites.

Rotation around a point

Can anyone help me with this please
I want to be able to rotate a 3D object around a stationary 3D object. Well there will be no movement involved as I just want to draw the objects at their locations once the game starts and then they will remain there for the remainder of the game.
Say for instance I have a object X that is stationary in 3D space. I then have 2 other objects, Y1 and Y2. Both of these objects are stationary as well and cant be moved. All 3 objects are on the same x and y axis. Lets say X is at (0,0,0) and Y1 is at (0,0,-50). I want to draw Y2 at a 45 degree angle from Y1 around the Y-axis but keep it the same distance from X.
Can anyone please suggest the best way of doing this please?
I have tried the following but that just rotates the object around its origin. So I guess I have to rotate it around the world origin? How is this done?
Matrix.CreateRotationY(Rotation)
I'm not sure what you want, but this is one method for rotate one object around another:
Vector3 Origin; // Stationary Object
float Yaw, Pitch; // Angles
float Distance;
Vector3 OrbitOffset = Vector3.UnitX * Distance;
// Other approach that consider the initial pos of the object to rotate
// Vector3 OrbitOffset = OrbitPos - Origin;
Matrix Rotation = Matrix.CreateFromYawPitchRoll(Yaw, Pitch, 0);
Vector3.Transform(ref OrbitOffset, ref Rotation, out OrbitOffset);
Vector3 OrbitPos = Origin + OrbitOffset; // Final position of the rotated object
if you dont need rotation about more than 2 angles at once, you can use basic Euler method.
see :
http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
thats a mathematical approach tough... but it works..
Just if you want a rotation around multiple axes, you will have serious problems with gimbal lock

Categories