2011-10-17 11 views
26

行列を使って、回転後に矩形内の座標の新しい位置を取得する方法を知りたいと思います。私は何をしたいのです: 行列を回転させた後の座標の新しい位置を取得する

  • が長方形
  • に回転する矩形内座標

    1. が定義した矩形を定義する座標回転後
    の新しい位置を取得します。

    私が理解できない部分は2 アイデアはありますか?

  • 答えて

    32

    私はこのための簡単なデモを作成しました。 少し余分なものがありますので、これを描画でどのように使用するかもわかります。

    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 (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) {} 
    } 
    
    +0

    rl.addView(myDrawing)の 'public Point rotate(float degrees)'を読んでください;この行にエラーがあります –

    6

    Matrix.mapPointsを使用して、2Dポイントをマトリックスで変換します。

    +0

    答えをありがとうが、私はこれを見て、座標を設定し、回転後にそれを得る方法をまだ理解していません。 – DecodeGnome

    +0

    私は同じ問題があります:( – donmj

    +0

    Entrecoの回答 –

    0

    長い時間遅れて私が知っているが、これは私もまだについて混乱していたものでした。このAPIの全領域は、実際に起こっていることを私たちに伝えることよりも、私たちのために働くことに重点を置いているようです。間違いなく、背後で本当に賢いことをしているからです。

    設定ポイントとそれらを戻すことは全く別です。

    特定のポイントを設定するさまざまな方法がありますが、Entrecoの優れた答えは一方通行です。

    ポイントを取得するには、そのポイントにリンクされているマトリックスの値を取得し、正しいポイントを選択する必要があります。これもまた優れています。答え(Android Matrix, what does getValues() return?)は、マトリックスで何が起こっているかを非常にはっきりと説明しています。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]; 
    

    私はこのことについて非常に満足しているわけではありませんが、それを行うためのより正式な方法はないようです。

    関連する問題