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:
- Definir un rectángulo
- Definir una coordenada dentro de ese rectángulo
- Gire el rectángulo
- 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?
- ¿Cómo desactivar la rotación en modo horizontal?
- Fragmentos y problemas con la pantalla giratoria
- Android: gira la imagen en la vista de la imagen por un ángulo
- Widget Android ImageButton pierde imagen cuando se gira la pantalla
- Cómo evitar reiniciar la actividad cuando cambia la orientación en Android
- Cómo usar los datos del sensor onSensorChanged en combinación con OpenGL
- Android rotar mapa de bits sin hacer una copia
- Bloqueo de orientación de la pantalla
- Cómo iframe un video de youtube en HTML para teléfonos Android para poder ver y rotar a pantalla completa?
- Lienzo dirección drawtext
- Rotación del videobuffer real en Videoview
- Cómo crear una imagen giratoria controlada por gestos para una interfaz de usuario
- Gire la vista de imagen alrededor de su centro sin cortar sus bordes
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.
- Ocultar MenuItem en algunos fragmentos
- Mostrar un cuadro de diálogo de alerta en el receptor de difusión después de un reinicio del sistema