Android Matrix Operations like Rotation and translate

Started by
4 comments, last by AliAbdulKareem 3 months, 1 week ago

Hi!

I hope you can answer a question for me that has been bugging me for close to a week now. I cant seem to get the matrix operations correct. I am using android.graphics.Matrix.

I am trying to rotate the player char but it doesnt seem to work right. This is what i am doing at the moment.

matrix.preTranslate(lCenterX, lCenterY);
matrix.postRotate(entity.rotation);
matrix.postTranslate(entity.x-lCenterX,entity.y-lCenterY);

I am trying rotate the player vertices (a rectangle so it has 4 of them) by a differing amount of degrees (like 20d, 45d, 90d) but the player ends up displaced very far away. The higher amount of degrees the more the player is displaced. It gets really wierd.

public static Vector2D[] transform(Vector2D[] src, Vector2D[] dst, Matrix matrix){
for (int i = 0; i < src.length; i++){
transformBuffer[0] = src[i].x;
transformBuffer[1] = src[i].y;
matrix.mapPoints(transformBuffer);
dst[i].x = transformBuffer[0];
dst[i].y = transformBuffer[1];
}
return dst;
}

I am using matrix.mapPoints to move the vertices. Also worth knowing is that i have an array of vertices that represent the untransformed vertices (in model space) which i am transforming into a set of transformed vertices into world space.





Advertisement

Also as an ammendment I'd like to point out that i have also tried the following

matrix.preTranslate(-lCenterX, -lCenterY);
matrix.postRotate(entity.rotation);
matrix.postTranslate(entity.x+lCenterX,entity.y+lCenterY);

And i have also tried
matrix.postRotate(entity.rotation, lCenterX, lCenterY);
matrix.postTranslate(entity.x,entity.y);

And also (best results)
matrix.postRotate(entity.rotation, 0, 0);
matrix.postTranslate(entity.x,entity.y);

And the best results come from the above but it still ends up displacing the player by a big amount depending on how many degrees.

Well, it's annoying to me too. Even after decades i often stumble over such problems, and i have to trial and error each time. And it becomes worse with the years, not better. That just said for consolidation.

Btw, for 99% of work i dodge the problem by keeping rotation and translation separated. Using quaternions for rotation and a point for most things i never have such problems.
But ofc. if we want to transform a bunch of vertices, matrices are faster, so there is no way around it.

Gtadam said:
And also (best results)

matrix.postRotate(entity.rotation, 0, 0);

matrix.postTranslate(entity.x,entity.y);

Likely it's best because you rotate around the origin, eliminating one potential source of error. So that's a good start to begin the trial and error fun.

I'm not used to pre and post multiplication support, but here is an example of code i use to rotate around a given point:

Quat rotation = ...

vec3 centerOfRotation = ...

Mat4 xf;
xf.SetRotationFromQuat (rot); // sets the upper left 3x3 matrix 
xf.SetTranslation (centerOfRotation - xf.Rotate(centerOfRotation)); // need to rotate the desired cor by that

for (&object : objects) 
{
	onject.transform = xf * onject.transform; // transform multiple objets, would work for transforming just points too
}

I guess your mistake is not considering the rotation for setting the translation part. But i'm never sure. :D

Thanks JoeJ I'm chipping away at the problem and hopefully will find a solution.

I think i have managed to get the rotation matrix right this time. However, im still having the same problem as earlier with my char moving up and down as jittery movement. I'm not sure if im using the MTV (Minimum translation distance) from my SAT algorithm correctly. How is it usually done?


MinimumTranslationVector overlap = Shape.getOverlapSAT(this, that, false);

if(overlap != null){
this.x = x - overlap.min.x*overlap.overlap;
this.y = y - overlap.min.y*overlap.overlap;

if(mVelocity.y != 0f && overlap.min.y*overlap.overlap > 0f ){
mVelocity.y = 0;
mIsOnGround = true;
}
}

It is not clear to me actually if you are doing this in 3D or 2D. the fact you are using Model Space and matrices suggested to me you are doing this in 3D (in which rotation should be around an axis). I would assume that is not the case, because your sample code only has X and Y, and using Vector2D. If it is in 2D, I honestly don't understand the need to do matrices at all. so, my first suggestion is to just try the translation part alone, can you get the expected behavior by moving each vertex the desired vector?
i.e.

function TranslateObj(Entity Obj, Vector2D translation): // assuming we get a reference to the Obj and not a copy
{
	foreach (vertex in Obj.Vertices): // same here, assuming we get a reference to each vertex and not a copy
	{
		vertex.x += translation.x;
		vertex.y += translation.y;
	}
}

if that had worked I would try rotation around the origin:

float Angle = ...
Vector2D RectCenter = {BottomLeft.x + Width/2, BottomLeft.y + Height/2};
TranslateObj(MyObj, -RectCenter);
//--- rotate by angle ---//
float C = cos(Angle);
float S = sin(Angle);
MyObj.x = C*MyObj.x - S*MyObj.y;
MyObj.y = S*MyObj.x + C*MyObj.y;

TranslateObj(MyObj, RectCenter);

This should give you a simple test case to check against.

None

This topic is closed to new replies.

Advertisement