I'm attempting to get an object to rotate about the origin point (0,0,0)
I'm following some guidelines from this blog and was able to get the basic rotation about the Z axis and it makes a very tight circle about the Z azis.
When I change it to the X or Y axis the triangle I made goes behind me and then shows up from the other side.
The basic effect I'm hoping to achieve is to have it spin right infront of the camera.
I understand that I would have to rotate it by the amount I want and then translate it back to the origin, but I'm not quite sure on how to figure out how much to translate it by.
Can someone give me a push in the right direction about this especially the formula I would need to use to translate it properly?
Hard to answer without seeing your code, but it sounds like you want to first translate the center of the triangle to the origin, rotate, then translate back to the triangle's original position. glRotate() rotates around the origin, not an arbitrary point.
So, effectively,
glTranslatef(centerX, centerY, centerZ);
glRotatef(angle, 0, 0, 1);
glTranslatef(-centerX, -centerY, -centerZ);
Remember that OpenGL transformations are applied in reverse order that they are specified in the code, so the above translates by -(centerX, centerY, centerZ), then rotates, then translates back by (centerX, centerY, centerZ).
Check out Chapter 3 of the OpenGL Programming Guide for more information.
Related
Say my camera is rotated around the X axis 60 degrees and looking down on a 9x9 block chess board. As we adjust board size, I want to zoom out the camera. Say for arguments sake the camera's position is (4,20,-7) and like this the whole board is visible and taking up the full screen.
If I adjust my board size to say 11x11 blocks I will now need to zoom out the camera. Say I want to maintain the same 60 degree angle and want the board to fill as much of the screen as it did before. What should the camera's new position be and how do you calculate it?
The X part is easy since you simple give the camera the same X position as the middle of the board. I'm not sure about how to calculate the new Y and Z positions though.
Any advice appreciated. Thanks.
edit: and if i wanted to change the angle of the camera as well as zoom out, is that possible to calculate? this is less important since i'll probably stick with the same angle, but i'm interested to know the maths behind it anyway.
Transform.Translate() method will move the transform according to the rotation. So you don't have to worry about the direction where your camera is looking at, just
yourCamera.transform.Translate(Vector3.forward * moveAmount);
will move your camera forward, which means zoom in. If you want to zoom out, just change the sign of the value to minus.
When I didn't know this, I used Mathf.Sin() and Mathf.Cos() to calculate each y and z world coordinates, which sucks.
I have two directions and i am trying to calculate the angle on a specific axis. The object from which the directions are derived is not a static object so i'm struggling to get my head round the maths to work out what i need to do.
FYI, I have the start and end points that i have used to calculate the directions if they are needed.
Here's a diagram to show what i am looking for:
The above image is from a top-down view in unity and it shows the angle i want.
The problem can be seen from the above image, which is that the directions are not on the same height so i can't use the vector3.angle function as it won't give me the correct angle value.
In essence i want to know how much would i have to rotate the red line to the left (top view) so that it would line up with the blue (top-view).
The reason i need this is as i am trying to find a way of getting the side-to-side angles of fingers from my leap motion sensor.
This a generic version of my other question:
Leap Motion - Angle of proximal bone to metacarpal (side to side movement)
It will provide more specific information as to the problem if you need it and it has more specific screenshots.
**UPDATE:
After re-reading my question i can see it wasn't particularly clear so here i will hopefully make it clearer. I am trying to calculate the angle of a finger from the leap motion tracking data. Specifically the angle of the finger relative to the metacarpal bone (bone is back of hand). An easy way to demonstrate what i mean would be for you to move your index finger side-to-side (i.e. towards your thumb and then far away from your thumb).
I have put two diagrams below to hopefully illustrate this.
The blue line follows the metacarpal bone which your finger would line up with in a resting position. What i want to calculate is the angle between the blue and red lines (marked with a green line). I am unable to use Vector3.Angle as this value also takes into account the bending of the finger. I need someway of 'flattening' the finger direction out, thus essentially ignoring the bending and just looking at the side to side angle. The second diagram will hopefully show what i mean.
In this diagram:
The blue line represents the actual direction of the finger (taken from the proximal bone - knuckle to first joint)
The green line represents the metacarpal bone direction (the direction to compare to)
The red line represents what i would like to 'convert' the blue line to, whilst keeping it's side to side angle (as seen in the first hand diagram).
It is also worth mentioning that i can't just always look at the x and z axis as this hand will be moving at rotating.
I hope this helps clear things up and truly appreciate the help received thus far.
If I understand your problem correctly, you need to project your two vectors onto a plane. The vectors might not be in that plane currently (your "bent finger" problem) and thus you need to "project" them onto the plane (think of a tree casting a shadow onto the ground; the tree is the vector and the shadow is the projection onto the "plane" of the ground).
Luckily Unity3D provides a method for projection (though the math is not that hard). Vector3.ProjectOnPlane https://docs.unity3d.com/ScriptReference/Vector3.ProjectOnPlane.html
Vector3 a = ...;
Vector3 b = ...;
Vector3 planeNormal = ...;
Vector3 projectionA = Vector3.ProjectOnPlane(a, planeNormal);
Vector3 projectionB = Vector3.ProjectOnPlane(b, planeNormal);
float angle = Vector3.Angle(projectionA, projectionB);
What is unclear in your problem description is what plane you need to project onto? The horizontal plane? If so planeNormal is simply the vertical. But if it is in reference to some other transform, you will need to define that first.
I'm playing with OpenGL ES on iPhone and I'm trying to rotate a model by panning with the finger. I discovered the open source app Molecules that let's you do that and I'm looking at that code, but when it comes to rotate a model of mine I'm able to rotate it only around a point distant in the space (like it was in orbit as a satellite and I am the fixed planet).
Any suggestion on what can be wrong?
I can post the code later , maybe on demand (many lines)
For the most part refer to Molecules you can find it here MOLECULES
If my memory serves me correctly, I think you need to translate the model to the origin, rotate, and then translate back to starting position to get the effect you are after.
I think there is a glTranslate() function, Say the object is at 1,0,0. You should then translate by -1,0,0 to go to origin. That is translate by a vector going from the center of the object to the origin.
The draw code probably looks roughly like this:
glLoadIdentity();
glTranslate(0, 0, -10);
glRotate(...);
drawMolecule();
Now it's important to realize that these transformations are applied in reverse order. If, in drawMolecule, we specify a vertex, then this vertex will first be rotated about the axis given to glRotate (which by definition passes through the local origin of the molecule), and then be translated 10 units in the −z direction.
This makes sense, because glTranslate essentially means: "translate everything that comes after this". This includes the glRotate call itself, so the result of the rotation also gets translated. Had the calls been reversed, then the result of the translation would have been rotated, which results in a rotation about an axis that does not pass through the origin anymore.
Bottom line: to rotate an object about its local origin, put the glRotate call last.
I recently started working with OpenGL ES for the iPhone, and I am having a bit of trouble with it. I want to be able to rotate an object with your fingers. My problem is that I have my object placed at (0, 0, -3), and I would like to rotate it about its center. I know that I need to translate back to the origin, rotate, and then bring it back to the original place. I think I am facing a problem because I am using a matrix to keep track (?) of all of my rotations/translation/scaling etc, and I think it may be combining the operations in a way that order is not even considered (so the two translations would cancel each other). I just started learning OpenGL a day ago and am a complete newbie, so my assumption may be wrong.
Here is the part of the in drawView that I am having trouble with:
GLfloat matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
glLoadIdentity();
glTranslatef(0, 0, 3); // bring to origin
glRotatef(self.angle, self.dy, self.dx, 0); // rotate
glTranslatef(0, 0, -3); // put it back in place
glMultMatrixf(matrix); // save the transformations performed
Help would be much appreciated, thank you!
Retrieving the modelview matrix, and then multiplying it back on after your rotation seems fishy, but it depends on what your other transforms are and what coordinate space things are supposed to be. Your comment on the glMultMatrix line doesn't correspond with what you're doing.
Normally you would just do the translate+rotate+translate as the most local actions on the object, just before you render it. Also note that this would only apply if you're object is at (0, 0, -3) in object-space. If it's at that location in world space, then the rotation will already rotate the object around its own center if you have previously made a series of transform calls (translate, rotate, etc) to move the object to its intended position in the world.
Transform order is one of the tricky parts of learning OpenGL. As a general rule of thumb, your operations start with the outer-most and progress to the inner-most. So a typical simple set of transforms would be: the inverse of the camera transform to move the world to match up with the camera, then the object's translation to move it to its world-space position, then the rotation to set it's intended orientation. The PushMatrix/PopMatrix stack functions let you save and undo part of that series of transforms so that groups of objects can share portions of that chain.
I am wondering if there is a way to translate the underlying matrix of a layer much like you can in ActionScript3.
In AS3 I can get the transform of a layer and shift it to, let's say, make the center of the layer the anchor point, rather than the upper-left corner.
The reason I ask is because I am trying to rotate a layer (containing a square) along a diagonal axis. I thought it might be easy if I could rotate the matrix by 45 degrees, then I could just rotate around the X-axis and be done.
But I cannot figure out how to do that.
Any help, greatly appreciate, as always.
Cheers,
Chris
Use a CGAffineTransform.
Edit:
I am afraid I don't know what you mean by "rotating an object along a diagonal axis". What you most likely need to do is to concatenate two or more transforms.
See figure 5-8 in Quartz 2D programming Guide The concatenation of two transforms creates the appearance of the image rotating around its lower left corner.