Dhaval Patel
Dhaval Patel

Reputation: 10299

How to get the View position relative to Parent after Scale, Rotate and Translate Operation in Android?

I'm working on a feature which includes image Scale, Rotate and Translate Operations. All these operations are working fine for me.

Now, I have a requirement to check the view position relative to the parent. I have developed the below code to get the view position after scale and translate.

private fun findViewPosition(view: View) {
    val left = view.left.toFloat()
    val top = view.top.toFloat()

    val px = view.pivotX
    val py = view.pivotY

    val tx = view.translationX
    val ty = view.translationY

    val sx = view.scaleX
    val sy = view.scaleY

    val rx = view.rotationX
    val ry = view.rotationY
    val r = view.rotation

    // Getting correct value for startX  and startY after scale and translate.
    // After the rotation, I'm not sure how to applied the formula.
    val startX = left - (view.width * sx - view.width) / 2 + tx
    val startY = top - (view.height * sy - view.height) / 2 + ty
    Log.w("Start", "$startX , $startY")

    val endX = left + view.width + (view.width * sx - view.width) / 2 + tx
    val endY = top + view.height + (view.height * sy - view.height) / 2 + ty
    Log.w("End","$endX , $endY")
}

I'm facing difficulties in finding the position after Rotation of the view. If anyone can help me on this will be a great help to me.

Translate + Scale Translate + Scale + Rotate

Here is the sample code if you want to try out the code: AndroidViewScaleRotateTranslate.zip

Thank you!

Upvotes: 3

Views: 699

Answers (1)

cmak
cmak

Reputation: 649

You probably need to calculate the positions manually using the rotation value of the view.

Remember that the actual view doesn't rotate, only it's content. It can be represented like this (red=rotation, blue=actual view):

representation

A: center of the view.

B: upper-left edge of the actual view Rect.

C: upper-left edge of the view rotated.

𝛼 (alpha): angle between AB and AC.


We have A, B and 𝛼. We want to know C. So, using trigonometry, we get this formula:

enter image description here

Using the following values (assume B is the origin of coordinates):

  • A: (Ax = view.getWidth() / 2) (Ay = view.getHeight() / 2)

  • B: (Bx = 0), (By = 0)

  • 𝛼 (alpha): (𝛼 = view.getRotation())

Since B is always 0, we can simplify:

 𝐢π‘₯ = 𝐴π‘₯ - (𝐴π‘₯)cos𝛼 + (𝐴𝑦)sin𝛼

 𝐢𝑦 = 𝐴𝑦 - (𝐴π‘₯)sin𝛼 - (𝐴𝑦)cos𝛼

The code would be something like this:

float aX = view.getWidth() / 2.f;
float aY = view.getHeight() / 2.f;

float alpha = Math.toRadians(view.getRotation());

float sin = Math.sin(alpha);
float cos = Math.cos(alpha);

float cX = aX - aX * cos + aY * sin;
float cY = aY - aX * sin - aY * cos;

If now you want the position relative to the parent:

float relX = view.getX() + cX;
float relY = view.getY() + cY;

That's the position you were looking for.

Upvotes: 1

Related Questions