用Matrix旋转后得到新的坐标位置

我想知道如何使用matrix来获得旋转后矩形内的坐标的新位置。 我想要做的是:

  1. 定义一个矩形
  2. 定义该矩形内的坐标
  3. 旋转矩形
  4. 获得旋转后坐标的新位置

我无法弄清楚的部分是2和4.任何想法?

Solutions Collecting From Web of "用Matrix旋转后得到新的坐标位置"

我为此创build了一个简单的演示。 它有一点额外的,所以你也可以看到如何在绘图中使用它。

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> 

而活动:

 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) {} } 

使用Matrix.mapPoints按matrix转换2D点。

我知道很长一段时间,但这也是我仍然困惑的事情。 API的整个领域似乎更多地集中在为我们做事上,而不是让我们了解实际发生的事情,毫无疑问,因为它在幕后做了非常聪明的事情。

设点和让他们回来是相当分离的。

有各种各样的方法来设置一个特定的点,Entreco的优秀答案显示的一种方法。

为了得到一个点,你必须得到一个matrix的值链接到这一点,然后从中select正确的部分。 这也是非常好的答案( Androidmatrix,getValues()返回的是什么? )非常清楚地解释了matrix的情况,你可以看到你想要的x,y值是由2和5索引的元素。

以下是我用来获取它们的(稍微伪造的)代码。

 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]; 

我对此并不高兴,但似乎没有更正式的方式来做到这一点。