I'm wondering how to use a Matrix to get the new position of a coordinate within a rectangle after rotation. What I would like to do is:
The parts I can't figure out are 2 & 4. Any ideas?
Finding the Coordinates of a Polygon After a RotationStep 1: Find and label all vertices of the original polygon. Step 2: Find the coordinates of the vertices of the rotated polygon using the formulas: x′ → xcos(θ)−ysin(θ) x ′ → x cos ( θ ) − y sin
To find the rotation of a vector we simply multiply the required rotation matrix with the coordinates of the given vector. In 2D space, this is given by ⎡⎢⎣x′y′⎤⎥⎦ [ x ′ y ′ ] = ⎡⎢⎣cosθ−sinθsinθcosθ⎤⎥⎦ [ c o s θ − s i n θ s i n θ c o s θ ] ⎡⎢⎣xy⎤⎥⎦ [ x y ] .
I have created a simple Demo for this. It has a little extra, so you can also see how to use this in Drawing.
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>
And the Activity:
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 (e.g. 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) {} }
Use Matrix.mapPoints to transform 2D points by matrix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With