2017-12-06 25 views
2

キャンバスにローテーションが適用されているときに、マウス座標系を回転させる方法を教えてください。キャンバスを回転させると、マウスは回転したコンポーネントと同じ位置にとどまります。私は、マウスの座標に、回転を考慮しないで、ウィンドウに対する相対位置である座標の代わりに、コンポーネントの回転を考慮したいと考えています。画面に対してマウスの位置を保持し、コンポーネントの回転を無視する方法は?

私は何を得ているのかをより詳しく説明するために画像を提供しました。黒いボックスは参照用の形状を表し、紫色のボックスはマウスの座標上にあります。 Rotation example image

左端の絵 - 非回転キャンバス 中東絵 - 回転したキャンバスJavaが見ていると、それ 右端の絵 - 私の例のコードは、左または右の矢印キーを押して回転させるキャンバスをシミュレートし

望ましい結果。このシミュレーションは、マウスがスクリーン上のマウスと相対的ではなく、回転したコンポーネントに対する相対的な位置にどのように留まるかを示しています。

これらの新しい座標(右端の画像に表示されています)を変換して計算する方法はありますか?ローテーションに関係なくウィンドウ内のマウスにロックされますか?

package rotation; 

    import java.awt.Canvas; 
    import java.awt.Color; 
    import java.awt.Graphics; 
    import java.awt.Graphics2D; 
    import java.awt.MouseInfo; 
    import java.awt.Point; 
    import java.awt.event.KeyAdapter; 
    import java.awt.event.KeyEvent; 
    import java.awt.geom.AffineTransform; 
    import java.awt.image.BufferStrategy; 

    import javax.swing.JFrame; 

    @SuppressWarnings("serial") 
    public class RotationExample extends Canvas implements Runnable{ 

     boolean isRunning = false; 
     boolean left = false; 
     boolean right = false; 
     AffineTransform transform = new AffineTransform(); 
     double rotation = 0.0d; 

     public RotationExample() { 
      //Create jframe 
      JFrame f = new JFrame(); 
      f.setSize(500, 500); 
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      f.setResizable(false); 
      f.setUndecorated(true); 

      //Add key listener 
      this.addKeyListener(new KeyAdapter() { 
       public void keyPressed(KeyEvent e) { 
        int k = e.getKeyCode(); 
        //Set left and right variables 
        if(k == KeyEvent.VK_LEFT) left = true; 
        if(k == KeyEvent.VK_RIGHT) right = true; 
       } 

       public void keyReleased(KeyEvent e) { 
        int k = e.getKeyCode(); 
        if(k == KeyEvent.VK_LEFT) left = false; 
        if(k == KeyEvent.VK_RIGHT) right = false; 
       } 
      }); 

      f.add(this); 
      f.setVisible(true); 
      start(); 
     } 

     public void render() { 
      BufferStrategy bs = this.getBufferStrategy(); 
      if(bs == null){ 
       this.createBufferStrategy(3); 
       return; 
      } 

      Graphics g = bs.getDrawGraphics(); 
      Graphics2D gt = (Graphics2D) g; 

      gt.setTransform(transform); 

      gt.clearRect(0, 0, 500, 500); 

      //Increment rotation based on left or right variables 
      if(left) rotation += 0.001; 
      else if(right) rotation -= 0.001; 

      //Rotate around middle of frame 
      gt.rotate(rotation, 250, 250); 

      //Draw black rectangle in middle 
      gt.setColor(Color.BLACK); 
      gt.fillRect(175, 175, 150, 150); 

      //Draw red up arrow 
      gt.setColor(Color.RED); 
      gt.fillPolygon(new int[] {250, 300, 270, 270, 230, 230, 200}, new int[] {200, 250, 250, 300, 300, 250, 250}, 7); 

      //Draw rectangle at mouse coordinates 
      gt.setColor(Color.MAGENTA); 
      Point m = MouseInfo.getPointerInfo().getLocation(); 
      gt.fillRect((int) m.getX() - 8, (int) m.getY() - 8, 16, 16); 

      bs.show(); 
      gt.dispose(); 
     } 

     public static void main(String[] args) { 
      new RotationExample(); 
     } 

     public void start() { 
      isRunning = true; 
      new Thread(this).start(); 
     } 

     public void run() { 
      //Continuous rendering 
      while(isRunning) { 
       render(); 
      } 

     } 
    } 
+0

'java.awt.Robot'?紫色の正方形の新しい位置を計算することは単純な幾何学的座標変換であり、マウスを新しい座標に移動します。座標変換は、プログラミングとは無関係の純粋な幾何学的問題であり、参照情報はウェブ上の多くの場所で利用可能である。 –

+0

@JimGarrison私は基本的なロボットを実装しようとしましたが、同じ結果が出ました。どのように私はロボットでこれを行うことができる任意のアイデア?私はこれにかなり新しいです、謝罪します –

答えて

3

マウスの位置は絶対的に報告されますが、ボックスの図は変換後です。マウスの位置を逆変換してポインタに戻す必要があります。

 //Draw rectangle at mouse coordinates 
     gt.setColor(Color.MAGENTA); 
     Point m = MouseInfo.getPointerInfo().getLocation(); 
     try { 
      gt.getTransform().createInverse().transform(m, m); 
      gt.fillRect((int) m.getX() - 8, (int) m.getY() - 8, 16, 16); 
     } catch (java.awt.geom.NoninvertibleTransformException e) { 
      System.err.println(e); 
     } 
関連する問題