2013-05-27 11 views
6

Ho un rettangolo che ruota attorno al centro e ho un altro rettangolo che voglio collegare all'angolo in alto a destra del rettangolo rotante. Il problema è che non ho idea di come ottenere l'angolo in modo che il secondo rettangolo rimanga sempre bloccato in quell'angolo.Ottieni gli angoli di un rettangolo rotante

Questo è il mio codice di esempio. In questo momento il secondo rettangolo sarà sempre nello stesso posto, il che non è il risultato che sto cercando.

package Test; 

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.*; 
import javax.swing.*; 

class Test{ 

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

    public Test(){ 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new Graphic()); 
       frame.setSize(1000,700); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 

class Graphic extends JPanel{ 
    private int x, y, windowW, windowH; 
    private double angle; 
    private Rectangle rect1, rect2; 
    private Path2D path; 
    private Timer timer; 
    private AffineTransform rotation; 

    public Graphic(){ 
     windowW = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth(); 
     windowH = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight(); 
     path = new Path2D.Double(); 
     rotation = new AffineTransform(); 
     angle = 0; 
     x = windowW/2; 
     y = windowH/2; 
     timer = new Timer(100, new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent e){ 
       angle += .1; 
       if(angle > 360) angle -= 360; 
       repaint(); 
      } 
     }); 
     timer.start(); 
    } 

    @Override 
    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     rotation.setToTranslation(500, 200); 
     rotation.rotate(angle, 32, 32); 
     rect1 = new Rectangle(0, 0, 64, 64); 
     path = new Path2D.Double(rect1, rotation); 
     rect2 = new Rectangle(path.getBounds().x, path.getBounds().y, 10, 50); 
     g2d.fill(path); 
     g2d.fill(rect2); 
    } 
} 
+0

il limite si mette su 'angle' sembra suggerire che si desidera esprimere in gradi; tuttavia la funzione 'ruota 'prende il suo primo parametro in radianti. La condizione 'if (angle> 360) angle - = 360' causa effettivamente uno strano salto quando viene raggiunta, e il rettangolo sta ruotando molto più velocemente di quanto tu abbia voluto. – Arend

risposta

4

soluzione matematica :)

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    Graphics2D g2d = (Graphics2D) g; 
    rotation.setToTranslation(500, 200); 
    rotation.rotate(angle, 32, 32); 
    rect1 = new Rectangle(0, 0, 64, 64); 
    path = new Path2D.Double(rect1, rotation); 
    double r = 32.0 * Math.sqrt(2); 
    // (532, 232) - coordinates of rectangle center  | 
    // you can change position of second rectangle by this V substraction (all you need to know is that the full circle corresponds to 2Pi) 
    int x2 = (int) Math.round(532 + r * Math.cos(angle - Math.PI/4)); 
    int y2 = (int) Math.round(232 + r * Math.sin(angle - Math.PI/4)); 
    rect2 = new Rectangle(x2, y2, 10, 50); 
    g2d.fill(path); 
    g2d.fill(rect2); 
} 

Naturalmente, alcune costanti dovrebbe essere campi di classe, non variabili di metodo.

2

non posso verificare questo codice per essere sicuro, ma credo che sia il codice di lavoro adeguato che si desidera

int hw = -width/2; 
int hh = -height/2; 
int cos = Math.cos(theta); 
int sin = Math.sin(theta); 
int x = hw * cos - hh * sin; 
int y = hw * sin + hh * cos; 

questo modo si ottiene l'angolo in alto a sinistra sulla base del theta, la rotazione, della piazza. Per ottenere gli altri angoli basta usare cambiare HW e hh valori:

//top right corner 
hw = width/2 
hh = -height/2 

//bottom right corner 
hw = width/2 
hh = height/2 

//bottom left corer 
hw = -width/2 
hh = height/2 

Spero che questo aiuta

Problemi correlati