Transforming an object between two coordinate spac

2019-07-12 22:49发布

问题:

So I'm reading the "3D Math Primer For Graphics And Game Development" book, coming from pretty much a non-math background I'm finally starting to grasp vector/matrix math - which is a relief.

But, yes there's always a but, I'm having trouble understand the translation of an object from one coordinate space to another. In the book the author takes an example with gun shooting at a car (image) that is turned 20 degrees (just a 2D space for simplicity) in "world space". So we have three spaces: World Space, Gun Object Space and Car Object Space - correct? The book then states this:

"In this figure, we have introduced a rifle that is firing a bullet at the car. As indicated by the coordinate space on the left, we would normally begin by knowing about the gun and the trajectory of the bullet in world space. Now, imagine transforming the coordinate space in line with the car’s object space while keeping the car, the gun, and the trajectory of the bullet still. Now we know the position of the gun and the trajectory of the bullet in the object space of the car, and we could perform intersection tests to see if and where the bullet would hit the car."

And I follow this explanation, and when I beforehand know that the car is rotated 20* degrees in world space this isn't a problem - but how does this translate into a situation say when I have an archer in a game shooting from a hill down on someone else? I don't know the angle at which everything is displaced there?

And which object space is rotated here? The World or Gun space? Yeah as you can see I'm a bit confused.

I think the ideal response would be using the car and gun example using arbitrary variables for positions, angle, etc.

回答1:

You should read how to change basis and think in vector, not arrays but the math ones :P



回答2:

I used to be a game programmer and I did that time after time. Eventually, I got away from using angles. For every object, I had a forward-facing vector and an up vector. You can get the right-facing vector, then, from a cross-product. And all the conversions between spaces become dot products.



回答3:

Do you understand how the notion of how coordinate spaces and transforms work in 2D? I find that coordinate spaces and transforms are a lot easier to visualize in 2D before trying to move to 3D. That way you can work "what-if" scenarios out on paper, and helps you to just grok the major concepts.

In the image you posted I think the interpretation is that the car itself has not changed in its internal coordinate system, but that its system has been rotated with respect to the World's system.

You have to understand that the car has its own local coordinate system. The geometry of the car is defined in terms of its local coordinate system. So the length of the car always extends along the x-axis in its own local system regardless of its orientation in the World. The car can be oriented by transforming its local coordinate system.

Coordinate systems are always defined relative to another system, except for the root, in this case the World. So the gun has its own system, the car has its own system and they are both embedded into the World's system. If I rotate or move the car's system with respect to the World then the car will appear to rotate even though the geometry is unchanged.

This is something that is very hard to explain without being able to draw out visual scenarios and my google-fu is failing to find good descriptions of the basics.



回答4:

As a previous reply suggests, keeping an up, forward and right vector is a good way to define a (Euclidean) coordinate space. Its even better if you add an origin as well, since you can represent a wider range of spaces.

Lets say we have two spaces A and B, in A, up, forward and right are (0,1,0), (0,0,1) and (1,0,0) respectively, and the origin is at zero this gives the usual left-handed xyz coordinates for A. Say for B we have u=(ux,uy,uz), f=(fx,fy,fz) and r=(rx,ry,rz) with origin o = (ox,oy,oz). Then for a point at p = (x,y,z) in B we have in A (x*rx + y*ux + z*fx + ox, x*ry + y*uy + z*fy + oy, x*rz + y*uz + z*fz + oz).

This can be arrived at by inspection. Observe that, since the right, up and forward vectors for B have components in each axis of A, a component of some coordinates in B must contribute to all three components of the coordinates in A. i.e. since (0,1,0) in B is equal to (ux,uy,uz), then (x,y,z) = y*u + (some other stuff). If we do this for each coordinate we have that (x,y,z) = x*r + y*u + z*f + (some other stuff). If we make the observation that the at the origin these terms vanish except for (some other stuff) then we realise that (some other stuff) must in fact be o, which gives the coordinates in A as x*r + y*u + z*f + o, which is (x*rx + y*ux + z*fx + ox, x*ry + y*uy + z*fy + oy, x*rz + y*uz + z*fz + oz) once the vector operations are expanded.

This operation can be reversed as well, we just set the coordinates in A and solve equations to find them in B. e.g. (1,1,1) in A is equal to x*r + y*u + z*f + o in B. This gives three equations in three unknowns and can be solved by the method of simultaneous equations. I won't bother explaining that here... but here is a link if you get stuck: link

How does all of this relate to your original example of a bullet and a car? Well, if you rotate a set of up/right/forward vectors with the car, and update the origin as the car is translated you can move from world space to the car's local space and make some tests easier. e.g instead of transforming vertices for a collision model, you can transform the bullet into 'car local' space and use the local coordinates. This is handy if you are going to transform the car's vertices for rendering on a GPU, but don't want to suffer the overhead of reading that information back to use for physics calculations on the CPU.

In other uses it can save you transforming x points by transforming three points and performing these operations instead, this allows you to combine x transformations on a large number of points without a significant performance hit over a single transformation across the same number of points.



回答5:

In a game situation generally you wouldn't know the car was rotated 20 degrees, per se; instead your positioning information for the car would implicitly contain that knowledge. So in this two dimensional example, you'd know the x,y coordinates of the center of the car and x,y vector the car is pointing (both pieces of information in the world space) -- otherwise you wouldn't be able to draw it. Those two pieces of information are all you need to find the matrix to transform between world space and the car's object space. (And then a person could look at that matrix in this example and say, oh, look, rotation by 20 degrees -- but that's not a piece of information you'd normally worry about in the game.)

The problem of the gun and the car can be solved in any of the three spaces. So the question is, which is it easiest in? Presumably the gun's space is set up so that the bullet is fired down the X axis. So it's easy to translate that into either of the other spaces. A 2D car is probably going to be represented in its own object space -- maybe as a set of 2D line segments or 2D pixels or something. You certainly could translate those into world space or the gun's object space, but if you solve the problem in car object space you don't have to translate them at all, so that's the easiest one to work in for this problem.

It's sort of like relativity: from its own perspective, none of the spaces are rotated. Unlike relativity, though, we treat the world space as a privileged fixed frame of reference. So the objects' model spaces are rotated, mirrored, scaled, translated, etc with respect to the world space.