Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why postRotate() method change X axis direction

I'm trying to reflect a drawn sticker like this

Original Sticker ---------- Reflected Sticker

      ↓                           ↓
public void reflectCurrentSticker(int windowWidth) {

    //     Y
    // ----|----- x
    //     |

    //creation of the cloned sticker
    //getWidth() == width of the FrameLayout (where the stickers drawn)

    Matrix originalMatrix = getReflectedMatrix(getWidth(), originalSticker);
    addSticker(clonedSticker);
    clonedSticker.setMatrix(originalMatrix);
    invalidate();

}

public Matrix getReflectedMatrix(int wrapperWidth, Sticker sticker) {
    Matrix matrix = sticker.getMatrix();
    float transX = getMatrixValue(matrix, 2);
    float transY = getMatrixValue(matrix, 5);
    float newX = (((float) wrapperWidth) - transX) - ((float) sticker.getCurrentWidth());
    float currentAngle = sticker.getCurrentAngle();
    float currentScale = sticker.getCurrentScale();
    Matrix newMatrix = new Matrix();
    newMatrix.postRotate(currentAngle);
    newMatrix.postScale(currentScale, currentScale);
    newMatrix.postTranslate(newX, transY);
    return newMatrix;
}

public float getMatrixValue(@NonNull Matrix matrix, @IntRange(from = 0, to = 9) int valueIndex) {
        final float[] matrixValues = new float[9];
        matrix.getValues(matrixValues);
        return matrixValues[valueIndex];
}

My code works fine, but the issue starts when I rotate the original sticker, and try to create a reflected sticker from it, unfortunately, I got this, the reflected sticker positioned in the wrong place, with the wrong rotation angle.

Original Sticker -- Reflected Sticker

      ↓                 ↓

The expected output is :

Original Sticker ---------- Reflected Sticker

      ↓                           ↓
like image 670
Mouaad Abdelghafour AITALI Avatar asked Oct 27 '22 10:10

Mouaad Abdelghafour AITALI


1 Answers

Why postRotate() method change X axis direction?

It might look like it is, it is not. First at all, you need to understand that translate(), rotate() and screw() operations require a pivot point. The pivot point is at the most top-left of any image/bitmap. Secondly, Android always rotate an image/bitmap clockwisely and not anti-clockwise. If you want to rotate it anti-clockwise, you could negate the angle e.i. 90 to -90 but it is not recommended -- it might causes bugs. Rather 360 - angle - 180. So, this is probably what you wanted.

newMatrix.postScale(-currentScale, currentScale);
newMatrix.postTranslate(sticker.getCurrentWidth, transY);
newMatrix.postRotate(360 - currentAngle - 180);
like image 121
Darkman Avatar answered Nov 15 '22 06:11

Darkman