OpenGL rotation and scaling - c

Does rotation always occur about the origin (0,0,0)?
Does translation always occur relative to previous translation?
Does scaling increase the coordinates axes size?

I suggest that a good way for a beginner is to start by thinking about points rather than 3D objects. Then all the transformation can be thought of as functions to change a point position to a new position.
First imagine an XYZ cartesian coordinate space, then imagine a point (X,Y,Z) in space with origin (0, 0, 0). All OpenGL knows at this stage is the point X,Y,Z. Now you are ready to begin:
Rotation requires an angle and a center of rotation. glRotate allows you to only specify the angles. By virtue of mathematics, conceptually, the center of rotation is at the location (X-X,Y-Y,Z-Z) or (0,0,0).
Translation is just an offset from the current position. Since OpenGL knows your point (X,Y,Z) it simply adds the offest to the position vector. It is therefore more correct to say it is relative to the current position rather than previous translation.
Scaling is a multiplication of the point vector (X.m,Y.m,Z.m) hence it simply just translating that point by a factor of m. Hence conceptually one can say it doesn't change the coordinate axes size.
However, when you start to think in 3D things get abit tricky because you will realise that if you are not careful, the all the points in a single 3D object doesn't always change position in the way you desire relative to each other. You will learn for example that if you want to rotate about the object's center, you will have to "move it to the origin, rotate, and then move it back again". This process of moving it back an forth can be thought as specifying the center of rotation. These are actually mathematical "tricks" that you apply.

Does rotation always occur about the origin (0,0,0)?
Indeed this is the case.
Does translation always occur relative to previous translation?
Does scaling increase the coordinates axes size?
This requires some explanation: OpenGL, and so many other software operating with geometry data don't build a list of chained transformations. What they maintain is one single homogenous transformation matrix.
"Appending" a transformation is done by multiplying the current transformation matrix with the transformation matrix describing the "next" transformation, replacing the old transformation. This also means that a compound transformation matrix, like what you end up having in the OpenGL modelview, may be applied as transformation as well.
To make a long story short, it depends all on the transformation applied. Old OpenGL gives you some basic matrix manipulations. In OpenGL-3 they have been removed, because OpenGL is not a math library, but draws stuff.
So how does such a transformation matrix look like? Like this:
Xx Yx Zx Tx
Xy Yy Zy Ty
Xz Yz Zz Tz
_x _y _z w
Maybe you noticed that there are 3 major columns designated by capital X, Y, Z. Those columns form vectors. And in the case of 3D transformations those are the base vectors of a coordinate system, relative the one the transformation is applied upon. However vectors only give "directions" and a length. So what's needed as well is the relative point of origin of the new coordinate system, and that's what the T vector contains.
Most of the time _x = _y = _z = 0 and w = 1
Transforming a point of geometry happens by multiplying the points vector with the matrix. Let such a matrix be M, the point p, then
p' = M * p
Now assume we chain transformations:
p'' = M' * p' = M' * M * p
We can substitute M_ = M' * M, so
p'' = M_ * p
It's easy to see, that we can chain this arbitrarily long
To answer your two last questions: Transformations (not just translations) do chain. And yes, applying a scaling transform will "scale" the axes.
And to clear up some commong misunderstanding: OpenGL is not a scene graph, it does not deal with "objects", but just lists of geometry. glScale, glTranslate, glRotate don't transform objects, but "chain up" transformation operations.

someone with more experience will surely point you to a good tutorial but your question reflect that you don't understand the 3D graphical pipeline and more precisely the concept of projection matrix (I might have the wrong name here since I studied this ages ago in French lol).
Basically whenever you apply a rotation/translation/scaling you are modifying the same matix
therefor when you each operation modifies the existing state.
For example doing rotation then a translation will give you a different result that translation then rotaiton (try doing the solar system sun earth moon it will help you understand)
regarding your questions:
No the basic rotation will not always occur in 0,0,0. for example if you first translate to 2,3,4 then the rotation will happen in 2,3,4.
the simple answer is yes, you are moving your matrice form its last position.(read my comment at the end for the not the simple answer ^^)
scaling will affect all the transformations done after. example scale 1,2,2 followed by a translation 2,3,4 could be seen as a a global translation 2,6,8
now for the not so simple part:
as explained each change will be affected by the previous changes (example of the scale)
also there is a lot of ways to do the same thing or to alter the behavior, for example:
achieving absolute translation can be done like this
-translate
-create an object
-indentity (reset the matrix to 0)
-translate2
-create object2
My advice is read tutorials but also global 3D programing blogs or a book (red book is good when you start lol)

Related

Differences in Differentiation Implementations in MATLAB

I'm trying to find the (numerical) curvature at specific points. I have data stored in an array, and I essentially want to find the local curvature at every separate point. I've searched around, and found three different implementations for this in MATLAB: diff, gradient, and del2.
If my array's name is arr I have tried the following implementations:
curvature = diff(diff(arr));
curvature = diff(arr,2);
curvature = gradient(gradient(arr));
curvature = del2(arr);
The first two seem to output the same values. This makes sense, because they're essentially the same implementation. However, the gradient and del2 implementations give different values from each other and from diff.
I can't figure out from the documentation precisely how the implementations work. My guess is that some of them are some type of two-sided derivative, and some of them are not two-sided derivatives. Another thing that confuses me is that my current implementations use only the data from arr. arr is my y-axis data, the x-axis essentially being time. Do these functions default to a stepsize of 1 or something like that?
If it helps, I want an implementation that takes the curvature at the current point using only previous array elements. For context, my data is such that a curvature calculation based on data in the future of the current point wouldn't be useful for my purposes.
tl;dr I need a rigorous curvature at a point implementation that uses only data to the left of the point.
Edit: I kind of better understand what's going on based on this, thanks to the answers below. This is what I'm referring to:
gradient calculates the central difference for interior data points.
For example, consider a matrix with unit-spaced data, A, that has
horizontal gradient G = gradient(A). The interior gradient values,
G(:,j), are
G(:,j) = 0.5*(A(:,j+1) - A(:,j-1)); The subscript j varies between 2
and N-1, with N = size(A,2).
Even so, I still want to know how to do a "lefthand" computation.
diff is simply the difference between two adjacent elements in arr, which is exactly why you lose 1 element for using diff once. For example, 10 elements in an array only have 9 differences.
gradient and del2 are for derivatives. Of course, you can use diff to approximate derivative by dividing the difference by the steps. Usually the step is equally-spaced, but it does not have to be. This answers your question why x is not used in the calculation. I mean, it's okay that your x is not uniform-spaced.
So, why gradient gives us an array with the same length of the original array? It is clearly explained in the manual how the boundary is handled,
The gradient values along the edges of the matrix are calculated with single->sided differences, so that
G(:,1) = A(:,2) - A(:,1);
G(:,N) = A(:,N) - A(:,N-1);
Double-gradient and del2 are not necessarily the same, although they are highly correlated. It's all because how you calculate/approximate the 2nd-oder derivatives. The difference is, the former approximates the 2nd derivative by doing 1st derivative twice and the latter directly approximates the 2nd derivative. Please refer to the help manual, the formula are documented.
Okay, do you really want curvature or the 2nd derivative for each point on arr? They are very different. https://en.wikipedia.org/wiki/Curvature#Precise_definition
You can use diff to get the 2nd derivative from the left. Since diff takes the difference from right to left, e.g. x(2)-x(1), you can first flip x from left to right, then use diff. Some codes like,
x=fliplr(x)
first=x./h
second=diff(first)./h
where h is the space between x. Notice I use ./, which idicates that h can be an array (i.e. non-uniform spaced).

Real time linear interpolation about 3-D servo motor

As we know in ordinary linear interpolation, the final destination is fixed. I want to use a camera to catch the moving objects and the coordinate can be the final destination. Anybody could help me finish this algorithm in C code?
Assuming that you're trying to track a moving object with a gimballed camera, the problem is the mismatch between the linear, constant speed assumption and the motion of the camera. Even if your object is moving at a constant speed, the camera will have to rotate at a non-constant speed to keep track of the object. For example, the camera will have to rotate quickly when the object is near the camera, but will rotate very slowly when the object is far away.
1) Figure out the Cartesian (XYZ) coordinates of the starting and ending points.
2) Compute a sequence of linear interpolations between the start and end point in Cartesian space. This is a sequence of points in Cartesian space that estimate the object's trajectory.
3) Convert the sequence of Cartesian points from the Cartesian coordinate system to the Spherical coordinate system.
4) The spherical coordinates Theta and Phi are the angles that your camera must move through in time.
All of the computations described above are simple and closed-form. You shouldn't need to apply any "real-time" programming techniques aside basic concepts like no dynamic allocation and no interpreted or garbage collected languages. If reliability is very important then you will want to employ a suitable real-time OS. Linux has a good real-time patch that provides pretty good soft-real-time performance.

AI, moving towards target by apply force

I have a level containing points in 2D, one being controlled by the user the rest being controlled by the required AI, the points move by applying a set amount of force each second which is pushed into the velocity divided by their mass, which is then pushed into the position each second, the velocity is maintained between calculations (momentum). What I'm looking for is a way to apply force so I can move towards a particular target and collide.
I've tried multiplying the normalized vector pointing towards the target by the set force, It works if the velocity of both is zero when starting, unfortunately points will need to attack multiple targets one after the other, what ends up happening is the predator will circle around the target getting closer with each rotation. Thanks.
tl;dr I need to the AI to move towards the targets by applying force in 2D. Thanks.
Let v' be the velocity vector that you want to assume with your seeker. Most simple, if the target were to move without accelleration and your seeker would go on with v' they would meet. (*)
Now don't just add some momentum in the form of v'! Let v be the current velocity of your seeker. You need to apply a force in the direction of v' - v to change your seeker velocity towards v'.
*) Ok, it's not that simple. There are infinitely many meeting points (unless the target is still). Deciding on a meeting point can be done by choosing the earliest point that can be reached with a given amount of momentum applied to the seeker.
Just a remark
Maybe your game (?) gets more realistic if you apply a fixed amount of energy instead of a fixed amount of momentum each round. But this is just a guess.
About mass
To make it realistic you should probably let the mass be proportional to either the square of the radius (assuming a 2D world with circles) or to the cubic of the radius (assuming a 3D world and a sphere).
Momentum vs. energy
Momentum is v m while energy is 1/2 v^2 m. When applying a fixed amount of energy it becomes harder to further accelerate fast objects.
In reality to maintain a fixed acceleration [m/s per s] you will need an ever encreasing amount of enery per time vs. you need a constant amount of momentum per time to do the same.
Caveat
If you make it follow the laws of physics more closely this does not necessarily make it look more realistic. My opinion is that you should try both ways and decide for what "feels" best. Or just leave it as it is if you're feeling happy with it.
Remember to move toward the target's position at time now + t. t is the collision time. You have to combine the seeker and target's motion equations and solve for t and the vector.

Compact representation of OpenGL modelview matrix 4x4

What is the most user friendly way to store only the rotation part of an OGL modelview (4x4) matrix?
For example; in a level editor to set the rotation for an object it would be easy to use the XYZ Euler angles. However this seems a very tricky system to use with matrices.
I need to be able to get AND set the rotation from this new representation.
(The alternative is to store the rotation part (4*3 numbers) but it is hard for a user to manipulate these)
I found some code here http://www.google.com/codesearch/p?hl=en#HQY9Wd_snmY/mesh/matrix3.h&q=matrix3&sa=N&cd=1&ct=rc that allows me to set and get rotation from angles (3 floats). This is ideal.
Although they're used regularily, I disregard the use of Euler angles. They're problematic as they only preserve the pointing direction of the object, but not the bitangent to that direction. More important: They're prone to gibal lock http://en.wikipedia.org/wiki/Gimbal_lock
A far superior method for storing rotations are Quarternions. In layman terms a quaternion consists of the rotational axis and the angle of rotation around this axis. It is thus a tuple of 4 scalars a,b,c,d. The quaternion is then Q = a + i*b + j*c + k*d, |Q| = 1, with the special properties of i,j,k that i² = j² = k² = i·j·k = -1 and i·j = k, j·k = i, k·i = j, which implies j·i = -k, k·j = -i, i·k = -j
Quaterions are thus extensions of complex numbers. If you recall complex number theory, you'll remember that the product of two complex numbers a =/= b with |a| = |b| = 1 is a rotation in the complex plane. It is thus easy to assume that rotations in 3D can be described by an extension of complex numbers into a complex hyperplane. This is what quaternions are.
See this article on the details.
http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
In a standard 3D matrix you only need the top left 3x3 values to give the rotation. To apply the matrix as a 4x4 later on, you need to make the other values 0 apart from on the diagonal.
Here's a rotation only matrix where the values vXY give the rotations.
[v00 v01 v02 0]
[v10 v11 v12 0]
[v20 v21 v22 0]
[ 0 0 0 1]
Interestingly, the values form the bases of the coordinate system you have rotated the object into, so in the new system, the x-axis is along [v00 v01 v02], the y-axis is along [v10 v11 v12] and the z-axis obviously [v20 v21 v22].
You could show these axes beside the object and let the other drag them around to change the rotation, perhaps.
I would say this depends on the user, but to me the most "user friendly" way is to store "roll", "pitch" and "yaw". These are very non-technical terms that an average user can understand and adjust, and it should be easy for you to take these values and compute the matrix.
IMO, the most 'user friendly format' for rotation is storing Euler XYZ angles, this is generally how rotations are exposed in any 3d content creation software.
Euler angles are easy to transform to matrices, see here for the involved matrix product.
But you should not confuse the format given to the GUI/user and the storage format of the data: Euler XYZ angles have problems of their own when doing animation, gimbal lock can introduce unwanted behaviour.
Another candidate for storing/computing rotations is quaternions. They offer mathematical advantages over XYZ angles, essentially when interpolating between two rotations. Of course, you don't want to expose the quaternion values directly to any human user, you'll need to convert them to XYZ angles. You'll find plenty of code to that on the Web.
I would not recommend storing the rotation directly in matrix format. Extracting user friendly values from it is difficult, it does not offer any interesting behaviour for animation/interpolation, it takes for storage. IMO, matrices are to be created when needed to transform the geometry.
To conclude, there are a few options, you should select what suits you most. Do you plan to having animation or not ? etc.
EDIT
Also, you should not make an amalgam with model and view matrices. They are semantically very different, and are combined in OpenGL only for performance reasons. What I had in mind above in the 'model matrix'. The view matrix is generally given by your view system/camera manager, and is combined with you model matrix.
A quaternion is, although the math is "obscure and unintellegible" surprisingly user friendly, as it represents rotation around an axis by a given angle.
The axis of rotation is simply a unit vector pointing in that direction, multiplied by the sine of 1/2 the rotation angle, and the "obscure" 4th component equals the cosine of 1/2 the rotation angle.
It feels kind of "unnatural" at first sight, but once you grasp it... can it be any easier?

Spatial Data Structures in C

I do work in theoretical chemistry on a high performance cluster, often involving molecular dynamics simulations. One of the problems my work addresses involves a static field of N-dimensional (typically N = 2-5) hyper-spheres, that a test particle may collide with. I'm looking to optimize (read: overhaul) the the data structure I use for representing the field of spheres so I can do rapid collision detection. Currently I use a dead simple array of pointers to an N-membered struct (doubles for each coordinate of the center) and a nearest-neighbor list. I've heard of oct- and quad- trees but haven't found a clear explanation of how they work, how to efficiently implement one, or how to then do fast collision detection with one. Given the size of my simulations, memory is (almost) no object, but cycles are.
How best to approach this for your problem depends on several factors that you have not described:
- Will the same hypersphere arrangement be used for many particle collision calculations?
- Are the hyperspheres uniform size?
- What is the movement of the particle (e.g. straight line/curve) and is that movement affected by the spheres?
- Do you consider the particle to have zero volume?
I assume that the particle does not have simple straight line movement as that would be the relatively fast calculation of finding the closest point between a line and a point, which is likely going to be about the same speed as finding which of the boxes the line intersects with (to determine where in the n-tree to examine).
If your hypersphere positions are fixed for a lot of particle collisions then computing a voronoi decomposition/Dirichlet tessellation would give you a fast way of later finding exactly which sphere is closest to your particle for any given point in the space.
However to answer your original question about octrees/quadtrees/2^n-trees, in n dimensions you start with a (hyper)-cube that contains the area of space that you are interested in. This will be subdivided into 2^n hypercubes if you deem the contents to be too complicated. This continues recursively until you have only simple elements (e.g. one hypersphere centroid) in the leaf nodes.
Now that the n-tree is built you use it for collision detection by taking the path of your particle and intersecting it with the outer hypercube. The intersection position will tell you which hypercube in the next level down of the tree to visit next, and you determine the position of intersection with all 2^n hypercubes at that level, following downwards until you reach a leaf node. Once you reach the leaf you can examine interactions between your particle path and the hypersphere stored at that leaf. If you have collision you have finished, otherwise you have to find the exit point of the particle path from the current hypercube leaf and determine which hypercube it moves to next. Continue until you find a collision or entirely leave the overall bounding hypercube.
Efficiently finding the neighbouring hypercube when exiting a hypercube is one of the most challenging parts of this approach. For 2^n trees Samet's approaches {1, 2} can be adapted. For kd-trees (binary trees) an approach is suggested in {3} section 4.3.3.
Efficient implementation can be as simple as storing a list of 8 pointers from each hypercube to its children hypercubes, and marking the hypercube in a special way if it is a leaf (e.g. make all pointers NULL).
A description of dividing space to create a quadtree (which you can generalise to n-tree) can be found in Klinger & Dyer {4}
As others have mentioned kd-trees may be more suited than 2^n-trees as extension to an arbitrary number of dimensions is more straightforward, however they will result in a deeper tree. It is also easier to adapt the split positions to match the geometry of your
hyperspheres with a kd-tree. The description above of collision detection in a 2^n tree is equally applicable to a kd-tree.
{1} Connected Component Labeling, Hanan Samet, Using Quadtrees Journal of the ACM Volume 28 , Issue 3 (July 1981)
{2} Neighbor finding in images represented by octrees, Hanan Samet, Computer Vision, Graphics, and Image Processing Volume 46 , Issue 3 (June 1989)
{3} Convex hull generation, connected component labelling, and minimum distance
calculation for set-theoretically defined models, Dan Pidcock, 2000
{4} Experiments in picture representation using regular decomposition, Klinger, A., and Dyer, C.R. E, Comptr. Graphics and Image Processing 5 (1976), 68-105.
It sounds like you'd want to implement a kd-tree, which would allow you to more quickly search the N-dimensional space. There's some more information and links to implementations at the Stony Brook Algorithm Repository.
Since your field is static (by which I'm assuming you mean that the hyper spheres don't move), then the fastest solution I know of is a Kdtree.
You can either make your own, or use someone else's, like this one:
http://libkdtree.alioth.debian.org/
A Quad tree is a 2 dimensional tree, in which at each level a node has 4 children, each of which covers 1/4 of the area of the parent node.
An Oct tree is a 3 dimensional tree, in which at each level a node has 8 children, each of which contains 1/8th of the volume of the parent node. Here is picture to help you visualize it: http://en.wikipedia.org/wiki/Octree
If you're doing N dimensional intersection tests, you could generalize this to an N tree.
Intersection algorithms work by starting at the top of the tree and recursively traversing into any child nodes that intersect the object being tested, at some point you get to leaf nodes, which contain the actual objects.
An octree will work as long as you can specify the spheres by their centres - it hierarchically bins points into cubic regions with eight children. Working out neighbours in an octree data structure will require you to do sphere-intersecting-cube calculations (to some extent easier than they look) to work out which cubic regions in an octree are within the sphere.
Finding the nearest neighbours means walking back up the tree until you get a node with more than one populated child and all surrounding nodes included (this ensures the query gets all sides).
From memory, this is the (somewhat naive) basic algorithm for sphere-cube intersection:
i. Is the centre within the cube (this gets the eponymous situation)
ii. Are any of the corners of the cube within radius r of the centre (corners within the sphere)
iii. For each surface of the cube (you can eliminate some of the surfaces by working out which side of the surface the centre lies on) work out (this is all first-year vector arithmetic):
a. A normal of the surface that goes to the centre of the sphere
b. The distance from the centre of the sphere to the intersection of the normal with the plane of the surface (chord intersets plane the surface of the cube)
c. Intersection of the plane lies within the side of the cube (one condition of chord intersection to the cube)
iv. Calculate the size of the chord (Sin of Cos^-1 of ratio of normal length to radius of sphere)
v. If the nearest point on the line is less than the distance of the chord and the point lies between the ends of the line the chord intersects one of the edges of the cube (chord intersects cube surface somewhere along one of the edges).
Slightly dimly remembered but this is something I did for a situation involving spherical regions using an octee data structure (many years ago). You may also wish to check out KD-trees as some of the other posters suggest but your initial question sounds very similar to what I did.

Resources