Sign in to follow this  

moving back to origin for a scale

This topic is 3741 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm making a small 3d matrix library to try and understand 3d programming a little better. My library is doing translations and scaling fine, independently. But if I translate my polygon from the origin, then try scaling, I get the effect of the polygon getting scaled AND translating off at the same time. I think I'm supposed to translate to the origin first, then scale, then translate back to where the polygon was. But how do you know how to translate back to the origin? Do you just build a translation matrix that's the inverse of the ucrrent matrix? Something like: 1) Translate object off somewhere 2) When a scaling operation starts, build some sort of 'inverse' translation matrix to get back to origin? If the ucrrent matrix of the polygon is: a b c d e f g h i j k l m n o p Then I just make an empty matrix, do identity(), then fill it in like: 1 0 0 -d 0 1 0 -h 0 0 1 -l 0 0 0 1 something like that? Then I apply that above matrix to get back to the origin, then do my scaling, then apply its inverse AGAIN to get back to where the polygon was? Then it should appear as if it were scaled "in place"? Thanks

Share this post


Link to post
Share on other sites
Hmm ok that's a good idea.

I guess I need to rethink how I apply these transforms to my polygons. Is the below idea along the right lines of how to approach this - I don't see another way to make sure translations occurr last on a geometry besides keeping them separated from the rotation/scaling matrices:


class Polygon {
list<point3d> m_vertices; // always the original points at creation.

list<Transform_Translate> m_Translations;
list<Transform_Scale> m_Scales;
list<Transform_Rotations> m_Rotations;

void Translate(Transform t)
{
m_Translations.push_back(t);
}
void Scale(Transform t)
{
m_Scales.push_back(t);
}
void Rotate(Transform t)
{
m_Rotations.push_back(t);
}

void UpdateGeometry()
{
// Apply all scale transforms.
// Apply all rotation transforms.
// Apply all translation transforms last.

// Original points are now transformed, draw those
// to screen.
}
};


I thought though that a big feature of matrices was that you could combine any number of them together and apply it to your vertices as just one matrix. Something like:

matrix scale + rotate + translate + translate + rotate = some_new_matrix;
vertices.ApplyMatrix(some_new_matrix);

How could I still take advantage of that?

Thank you.

Share this post


Link to post
Share on other sites
This isn't really your problem, as the coder of the matrix library. The rotation matrix should rotate; the scale scale; and the translate translate. The order in which the user chooses to apply them is entirely their decision. Indeed, it may be my intention to use a scaling matrix to move the object.

But from the perspective of the user, it is exactly as the others have said. The typical arrangements will have all of your objects centred at their local origin, each maintaining their current scale, orientation and position. Then, when it comes time to set the world-matrix, perform the three operations in alphabetical order. That is, rotate first, then scale, then translate. It doesn't actually matter which order you do the first two, but translation should always be last.

Admiral

Share this post


Link to post
Share on other sites
Ok I see your point that the matrix implementation as I have it right now is correct (a scale WILL move the object if the user chooses to apply out of order, that's just the nature of these transformations).

I guess what I'm looking for then is a wrapper function which the user can use to ScaleInPlace() / RotateInPlace().

What should I look for to implement those two types of functions? I just don't know where to start creating the above two functions - is there some method of for each polygon, mainting its own local origin point, and then modifying any applied matrices so they act upon its local origin? Something like:


void Polygon::ScaleInPlace(Matrix4x4 matScale)
{
// matScale is just a plain old scaling matrix.
1) Somehow modify matScale so it's acting upon the local coordinate
system of this polygon.
2) Apply the matrix.
3) It will now seem as if the polygon was scaled "in place".
}


Any general information on this would be really helpful,

Thanks

Share this post


Link to post
Share on other sites
In order to scale a polygon in place, you first have to choose a point about which the scaling should occur. A reasonable choice for this might be the average of the polygon vertices.

The scaling would then proceed as follows:

1. Translate by the negative of the scale 'center point'.

2. Scale.

3. Translate back to the center point.

You can think of the initial translation in terms of matrix inversion if you wish, but it's probably overkill - it'll be easier to just negate the translation vector.

I gather from your posts that you're using column-vector notation, in which case the construction of the scaling matrix might look something like this:
vector3 center = get_polygon_center(...);

matrix44 T1 = matrix_translation(-center);
matrix44 S = matrix_scale(scale_x, scale_y, scale_z);
matrix44 T2 = matrix_translation(center);

matrix44 M = T2*S*T1;

Share this post


Link to post
Share on other sites

This topic is 3741 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this