Obtener nueva posición de coordenadas después de la rotación con Matrix

Me pregunto cómo usar una matriz para obtener la nueva posición de una coordenada dentro de un rectángulo después de la rotación. Lo que me gustaría hacer es:

  1. Definir un rectángulo
  2. Definir una coordenada dentro de ese rectángulo
  3. Gire el rectángulo
  4. Obtener la nueva posición de la coordenada después de la rotación

Las partes que no puedo entender son 2 y 4. ¿Alguna idea?

He creado una demostración simple para esto. Tiene un poco más, así que también puedes ver cómo usar esto en Dibujo.

Main.xml

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="fill_parent" android:layout_height="fill_parent"> <SeekBar android:id="@+id/seekBar1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> </RelativeLayout> 

Y la Actividad:

 package nl.entreco.android.testrotation; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Point; import android.graphics.Rect; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; public class RotationActivity extends Activity implements OnSeekBarChangeListener { private MyDrawing myDrawing; private SeekBar mSeekbar; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Rect rect = new Rect(150,150,440,630); int x = (int) (rect.left + Math.random() * rect.width()); int y = (int) (rect.top + Math.random() * rect.height()); Point coordinate = new Point(x, y); // To draw the rect we create a CustomView myDrawing = new MyDrawing(this, rect, coordinate); RelativeLayout rl = (RelativeLayout)findViewById(R.id.container); rl.addView(myDrawing); mSeekbar = (SeekBar)findViewById(R.id.seekBar1); mSeekbar.setMax(360); mSeekbar.setOnSeekBarChangeListener(this); } private class MyDrawing extends View { private Rect myRect; private Point myPoint; private Paint rectPaint; private Paint pointPaint; private Matrix transform; public MyDrawing(Context context, Rect rect, Point point) { super(context); // Store the Rect and Point myRect = rect; myPoint = point; // Create Paint so we can see something :) rectPaint = new Paint(); rectPaint.setColor(Color.GREEN); pointPaint = new Paint(); pointPaint.setColor(Color.YELLOW); // Create a matrix to do rotation transform = new Matrix(); } /** * Add the Rotation to our Transform matrix. * * A new point, with the rotated coordinates will be returned * @param degrees * @return */ public Point rotate(float degrees) { // This is to rotate about the Rectangles center transform.setRotate(degrees, myRect.exactCenterX(), myRect.exactCenterY()); // Create new float[] to hold the rotated coordinates float[] pts = new float[2]; // Initialize the array with our Coordinate pts[0] = myPoint.x; pts[1] = myPoint.y; // Use the Matrix to map the points transform.mapPoints(pts); // NOTE: pts will be changed by transform.mapPoints call // after the call, pts will hold the new cooridnates // Now, create a new Point from our new coordinates Point newPoint = new Point((int)pts[0], (int)pts[1]); // Return the new point return newPoint; } @Override public void onDraw(Canvas canvas) { if(myRect != null && myPoint != null) { // This is an easy way to apply the same transformation (eg rotation) // To the complete canvas. canvas.setMatrix(transform); // With the Canvas being rotated, we can simply draw // All our elements (Rect and Point) canvas.drawRect(myRect, rectPaint); canvas.drawCircle(myPoint.x, myPoint.y, 5, pointPaint); } } } @Override public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) { Point newCoordinates = myDrawing.rotate(progress); // Now -> our float[] pts contains the new x,y coordinates Log.d("test", "Before Rotate myPoint("+newCoordinates.x+","+newCoordinates.y+")"); myDrawing.invalidate(); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} } 

Utilice Matrix.mapPoints para transformar puntos 2D por matriz.

Mucho tiempo tarde lo sé, pero esto era algo que yo también estaba confundido. Toda esta área de API parece estar más centrada en hacer cosas para nosotros que dejarnos llegar a lo que realmente está pasando, sin duda porque está haciendo cosas muy inteligentes detrás de las escenas.

Establecer puntos y recuperarlos son bastante diferentes.

Hay varias maneras de establecer un punto en particular, excelente respuesta de Entreco muestra una manera.

Para recuperar un punto debes obtener los valores de una matriz vinculados a ese punto y luego escoger las partes correctas de él. Esto, también excelente, responde ( Android Matrix, ¿qué devuelve getValues? ) Explica muy claramente lo que está pasando con la matriz, y puede ver que los valores x, y que desea son elementos indexados por 2 y 5.

El siguiente es un código (ligeramente pseudo-) que utilizo para llegar a ellos.

 float [] theArray = { <nine float zeroes> } Matrix m = new Matrix(); boolean success = myPathMeasure.getMatrix(m, theArray, Matrix.MTRANS_X+Matrix.MTRANS_Y); m.getValues(theArray); x = theArray[2]; y = theArray[5]; 

No estoy muy feliz por esto, pero no parece haber una forma más formal de hacerlo.

  • ¿Cómo restaurar la posición de desplazamiento de texto tras la rotación de la pantalla?
  • Sprite Rotación en Android con Canvas.DrawBitmap. Estoy cerca, ¿qué estoy haciendo mal?
  • Android: Manejo eficiente de la rotación de la pantalla
  • Obtener información de rotación automática en Android
  • Android visualiza la transformación de rotación 3D en pantallas de gran resolución
  • Stream de video de autorrotación TextureView en Nexus4 (pero no en Galaxy S4)
  • Android, App se estrelló en la rotación de la pantalla con el diálogo abierto
  • Cómo girar una vista en Android
  • Texto de vista de texto de android en dirección vertical
  • Android: gira la imagen en ImageView por 90degrees pero sin demora
  • Cómo controla la orientación de la pantalla del dispositivo Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.