Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing two 3D strings on Canvas?

I have to draw 2 Strings on canvas.Strings must be drawn with the same coordinates and second string must be result of rotating first string 45 degrees around axis Y.The result must looks like this:

enter image description here

This is my code:

Matrix matrix = new Matrix();
matrix = canvas.getMatrix();
mCamera = new Camera();


canvas.drawText("In the name of God", 30, 100, redPaint);
mCamera.rotateY(45);
mCamera.getMatrix(matrix);

matrix.preTranslate(30, 100);
//      matrix.postTranslate(-30, -100);

canvas.setMatrix(matrix);
canvas.drawText("In the name of God", 0, 0, greenPaint);

But result of above code is:

enter image description here

You can see that coordinates of strings are different.So what did I do wrong?I guess that it is be caused by incorrect arguments for matrix.preTranslate().

Update:

I change my code like:

canvas.drawText("In the name of God", 30, 100, redPaint);
mCamera.rotateY(45);
mCamera.getMatrix(matrix);
matrix.preTranslate(-30, -100);
matrix.postTranslate(30, 100);
canvas.setMatrix(matrix);
canvas.drawText("In the name of God", 0, 0, greenPaint);

or like:

canvas.drawText("In the name of God", 30, 100, redPaint);
mCamera.rotateY(45);
mCamera.getMatrix(matrix);
matrix.preTranslate(-30, -100);
//matrix.postTranslate(30, 100);
canvas.setMatrix(matrix);
canvas.drawText("In the name of God", 0, 0, greenPaint);

or like:

canvas.drawText("In the name of God", 30, 100, redPaint);
mCamera.rotateY(45);
mCamera.getMatrix(matrix);

matrix.preTranslate(-30, -100);
//      matrix.postTranslate(30, 100);
canvas.setMatrix(matrix);
canvas.drawText("In the name of God", 30, 100, greenPaint);

And for all three above codes, result looks like this:

enter image description here

I guess that second text is drawn out of range or behind the status bar and so it is not visible.

Then change my code to:

mCamera.rotateY(45);
mCamera.getMatrix(matrix);
matrix.preTranslate(-30, -100);
matrix.postTranslate(30, 100);
canvas.setMatrix(matrix);
canvas.drawText("In the name of God", 30, 100, greenPaint);

result:

enter image description here

like image 827
hasanghaforian Avatar asked Nov 18 '12 06:11

hasanghaforian


3 Answers

Thanks for replies.I solved the problem.I have to use canvas.concat() instead of canvas.setMatrix.This is correct code:

Matrix matrix = new Matrix();
mCamera = new Camera();

canvas.drawText("In the name of God", 30, 100, redPaint);
mCamera.rotateY(60);
mCamera.getMatrix(matrix);

matrix.preTranslate(-30, -100);
matrix.postTranslate(30, 100);
canvas.concat(matrix);
canvas.drawText("In the name of God", 30, 100, greenPaint);
like image 160
hasanghaforian Avatar answered Nov 12 '22 02:11

hasanghaforian


Try this out:

Matrix matrix = new Matrix();
matrix = canvas.getMatrix();
mCamera = new Camera();


canvas.drawText("In the name of God", 30, 100, redPaint);
mCamera.translate(30, 100);
mCamera.rotateY(45);
mCamera.getMatrix(matrix);

canvas.setMatrix(matrix);
canvas.drawText("In the name of God", 0, 0, greenPaint);

I never mess with pre and post translate, but you can probably debug it and try doing a posttranslate instead of a pretranslate and supply (30, 100) and see if that works.

like image 2
Michael Dotson Avatar answered Nov 12 '22 03:11

Michael Dotson


The rotation described by the matrix object always has the property that its axis of rotation pass through the origin. Every point in the axis of rotation is invariant under the rotation, which is a fancy (and compact) way of saying that it doesn't change. The way you've described your desired outcome, you want left edge of the text not to move. That means the left edge of the text has to be on that invariant axis.

This is what pretranslate() is for. You want a translation that takes the position of the text to the origin. The coordinates of that translation are the negative of the coordinates:

matrix.preTranslate(-30, -100);

This translation is applied to the text, not to the axis of rotation. That confusion seems to have been the source of your problem. To put the text back where it was before, use postTranslate with the negative of the pre-translation, that is, with the original coordinates.

To understand this better overall, read up on similarity transforms.

like image 1
eh9 Avatar answered Nov 12 '22 01:11

eh9