2011-04-09 1 views
2

У меня проблема с координатами, которые не являются точными после вращения, поскольку я изменяю значения полигонов, так как многие из моих вычислений используют удвоение, а конструктор Polygon принимает только int[]. Есть ли лучший способ сделать это и добиться тех же результатов?Вращение многоугольника вокруг оси x и y

Обратите внимание, что вращения вершин в «z-направление» (вне рамы) достигаются путем масштабирования; и что координатные оси для каждой буквы имеют относительное положение относительно осей координат кадра.

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.Point2D; 

import javax.swing.*; 
import java.lang.reflect.Array; 

public class test extends JPanel implements ActionListener{ 

double[] p1x = {200,200,260,260,220,220,260,260,200}; 
//int[] p1y = {300,360,360,340,340,320,320,300,300}; 

double[] p1y = {240,300,300,280,280,260,260,240,240}; 

double[] p2x = {600,600,620,620,640,640,660,660,600}; 
double[] p2y = {500,520,520,560,560,520,520,500,500}; 

double[] p3x = {500,500,560,560,540,540,520,520,500}; 
double[] p3y = {400,460,460,400,400,440,440,400,400}; 

int delay = 500; 
int dx=0; 
int dy=5; 
int steps = 120; 

Polygon t; 

Timer tim = new Timer(delay,this); 

public void actionPerformed(ActionEvent event){ 

    for (int i=0; i<Array.getLength(p2x);i++){ 
     //p2x[i] = (int) (p2x[i]*Math.cos(Math.toRadians(1))- p2y[i]*Math.sin(Math.toRadians(1))); 
     //p2y[i] = (int) (p2x[i]*Math.sin(Math.toRadians(1))+ p2y[i]*Math.cos(Math.toRadians(1)));; 
     //p2x[i] -=10; 
     //p3x[i]-= 10; 
     if(steps>100){ 
      p2y[i] -=10; 
      p1y[i] +=10; 
      p3x[i] -=10; 
      if(i==0){ 
       p1y[i] += 6; 
      } 
      if(i==1){ 
       p2y[i] -= 1.5; 
       System.out.println("steps: " + steps +" "+ p2y[i]); 
      } 
      if(i==2){ 
       p2y[i] -= 1.5; 
       p3x[i] -= 6; 
      } 
      if(i==3){ 
       p2y[i] -= 6; 
       p1y[i] += 1.5; 
       p3x[i] -= 6; 
      } 
      if(i==4){ 
       p2y[i] -= 6; 
       p1y[i] += 1.5; 
       p3x[i] -= 4.5; 
      } 
      if(i==5){ 
       p2y[i] -= 1.5; 
       p1y[i] += 4.5; 
       p3x[i] -= 4.5; 
      } 
      if(i==6){ 
       p2y[i] -= 1.5; 
       p1y[i] += 4.5; 
       p3x[i] -= 1.5; 
      } 
      if(i==7){ 
       p1y[i] += 6; 
       p3x[i] -= 1.5; 
      } 
      if(i==8){ 
       p1y[i] += 6; 
      } 


     } 
     else if((steps<=100) && (steps>80)){ 
      p2y[i] +=10; 
      p1y[i] -=10; 
      p3x[i] +=10; 
      if(i==0){ 
       p1y[i] -= 6; 
      } 
      if(i==1){ 
       p2y[i] += 1.5; 
       System.out.println("steps: " + steps +" "+ p2y[i]); 
      } 
      if(i==2){ 
       p2y[i] += 1.5; 
       p3x[i] += 6; 
      } 
      if(i==3){ 
       p2y[i] += 6; 
       p1y[i] -= 1.5; 
       p3x[i] += 6; 
      } 
      if(i==4){ 
       p3x[i] += 4.5; 
       p2y[i] += 6; 
       p1y[i] -= 1.5; 
       //p3x[i] += 4.5; 
      } 
      if(i==5){ 
       p2y[i] += 1.5; 
       p1y[i] -= 4.5; 
       p3x[i] += 4.5; 
      } 
      if(i==6){ 
       p2y[i] += 1.5; 
       p1y[i] -= 4.5; 
       p3x[i] += 1.5; 
      } 
      if(i==7){ 
       p1y[i] -= 6; 
       p3x[i] += 1.5; 
      } 
      if(i==8){ 
       p1y[i] -= 6; 
      } 
     } 

     else if((steps<=80) && (steps>60)){ 
      p2y[i] -=10; 
      p1y[i] +=10; 
      p3x[i] -=10; 
      if(i==0){ 
       p1y[i] += 6; 
      } 
      if(i==1){ 
       p2y[i] -= 1.5; 
       System.out.println("steps: " + steps +" "+ p2y[i]); 
      } 
      if(i==2){ 
       p2y[i] -= 1.5; 
       p3x[i] -= 6; 
      } 
      if(i==3){ 
       p2y[i] -= 6; 
       p1y[i] += 1.5; 
       p3x[i] -= 6; 
      } 
      if(i==4){ 
       p2y[i] -= 6; 
       p1y[i] += 1.5; 
       p3x[i] -= 4.5; 
      } 
      if(i==5){ 
       p2y[i] -= 1.5; 
       p1y[i] += 4.5; 
       p3x[i] -= 4.5; 
      } 
      if(i==6){ 
       p2y[i] -= 1.5; 
       p1y[i] += 4.5; 
       p3x[i] -= 1.5; 
      } 
      if(i==7){ 
       p1y[i] += 6; 
       p3x[i] -= 1.5; 
      } 
      if(i==8){ 
       p1y[i] += 6; 
      } 


     } 

     else if((steps<=60) && (steps>40)){ 
      p2y[i] +=10; 
      p1y[i] -=10; 
      p3x[i] +=10; 
      if(i==0){ 
       p1y[i] -= 6; 
      } 
      if(i==1){ 
       p2y[i] += 1.5; 
       System.out.println("steps: " + steps +" "+ p2y[i]); 
      } 
      if(i==2){ 
       p2y[i] += 1.5; 
       p3x[i] += 6; 
      } 
      if(i==3){ 
       p2y[i] += 6; 
       p1y[i] -= 1.5; 
       p3x[i] += 6; 
      } 
      if(i==4){ 
       p3x[i] += 4.5; 
       p2y[i] += 6; 
       p1y[i] -= 1.5; 
       //p3x[i] += 4.5; 
      } 
      if(i==5){ 
       p2y[i] += 1.5; 
       p1y[i] -= 4.5; 
       p3x[i] += 4.5; 
      } 
      if(i==6){ 
       p2y[i] += 1.5; 
       p1y[i] -= 4.5; 
       p3x[i] += 1.5; 
      } 
      if(i==7){ 
       p1y[i] -= 6; 
       p3x[i] += 1.5; 
      } 
      if(i==8){ 
       p1y[i] -= 6; 
      } 
     } 

     else if((steps<=40) && (steps>20)){ 
      p2y[i] -=10; 
      p1y[i] +=10; 
      p3x[i] -=10; 
      if(i==0){ 
       p1y[i] += 6; 
      } 
      if(i==1){ 
       p2y[i] -= 1.5; 
       System.out.println("steps: " + steps +" "+ p2y[i]); 
      } 
      if(i==2){ 
       p2y[i] -= 1.5; 
       p3x[i] -= 6; 
      } 
      if(i==3){ 
       p2y[i] -= 6; 
       p1y[i] += 1.5; 
       p3x[i] -= 6; 
      } 
      if(i==4){ 
       p2y[i] -= 6; 
       p1y[i] += 1.5; 
       p3x[i] -= 4.5; 
      } 
      if(i==5){ 
       p2y[i] -= 1.5; 
       p1y[i] += 4.5; 
       p3x[i] -= 4.5; 
      } 
      if(i==6){ 
       p2y[i] -= 1.5; 
       p1y[i] += 4.5; 
       p3x[i] -= 1.5; 
      } 
      if(i==7){ 
       p1y[i] += 6; 
       p3x[i] -= 1.5; 
      } 
      if(i==8){ 
       p1y[i] += 6; 
      } 


     } 

     else if((steps<=20) && (steps>0)){ 
      p2y[i] +=10; 
      p1y[i] -=10; 
      p3x[i] +=10; 
      if(i==0){ 
       p1y[i] -= 6; 
      } 
      if(i==1){ 
       p2y[i] += 1.5; 
       System.out.println("steps: " + steps +" "+ p2y[i]); 
      } 
      if(i==2){ 
       p2y[i] += 1.5; 
       p3x[i] += 6; 
      } 
      if(i==3){ 
       p2y[i] += 6; 
       p1y[i] -= 1.5; 
       p3x[i] += 6; 
      } 
      if(i==4){ 
       p3x[i] += 4.5; 
       p2y[i] += 6; 
       p1y[i] -= 1.5; 
       //p3x[i] += 4.5; 
      } 
      if(i==5){ 
       p2y[i] += 1.5; 
       p1y[i] -= 4.5; 
       p3x[i] += 4.5; 
      } 
      if(i==6){ 
       p2y[i] += 1.5; 
       p1y[i] -= 4.5; 
       p3x[i] += 1.5; 
      } 
      if(i==7){ 
       p1y[i] -= 6; 
       p3x[i] += 1.5; 
      } 
      if(i==8){ 
       p1y[i] -= 6; 
      } 
     } 


    } 
    repaint(); 

    if (--steps ==0) tim.stop(); 
} 

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 

    this.setBackground(Color.white); 

    g.drawLine(400, 0,400, 800); 
    g.drawLine(0, 400, 800, 400); 

    int[] p2xintarray =new int[9]; 
    int[] p2yintarray =new int[9]; 
    int[] p1xintarray =new int[9]; 
    int[] p1yintarray =new int[9]; 
    int[] p3xintarray =new int[9]; 
    int[] p3yintarray =new int[9]; 
    for (int i=0; i<Array.getLength(p2x);i++){ 
     int p2xint= (int)p2x[i]; 
     p2xintarray[i]=p2xint; 
     int p2yint= (int)p2y[i]; 
     p2yintarray[i]=p2yint; 

     int p1xint=(int)p1x[i]; 
     p1xintarray[i]=p1xint; 
     int p1yint= (int)p1y[i]; 
     p1yintarray[i]=p1yint; 

     int p3xint=(int)p3x[i]; 
     p3xintarray[i]=p3xint; 
     int p3yint= (int)p3y[i]; 
     p3yintarray[i]=p3yint; 
    } 

    Polygon t = new Polygon(p2xintarray, p2yintarray, 9); 
    g.drawPolygon(t); 

    //Polygon ti = new Polygon(p2xi, p2yi, 9); 
    //g.drawPolygon(ti); 

    Polygon u = new Polygon(p3xintarray, p3yintarray, 9); 
    g.drawPolygon(u); 

    Polygon l = new Polygon(p1xintarray, p1yintarray, 9); 
    g.drawPolygon(l); 

} 

public static void main(String[] args) { 

    JFrame frame = new JFrame("Drawing line and a moving polygon"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    test sl = new test(); 
    frame.getContentPane().add(sl); 
    frame.setSize(700,700); 
    frame.setVisible(true); 

    sl.tim.start(); 
    } 
} 
+3

Что все эти магические числа добавляются и вычитаются? – luqui

+1

Второе, что я сделал бы (после избавления от магических чисел), было бы реорганизовать этот код, поскольку, похоже, очень много ненужного повторения делает еще более сложной отладку. –

+0

Возможный дубликат [Вращение фигуры по вертикали вокруг оси x] (http://stackoverflow.com/questions/5593066/rotating-a-shape-vertically-around-the-x-axis) – trashgod

ответ

3

В дополнение к рефакторингу и изменению магических чисел, рассмотрите возможность использования объекта Path2D.Double вместо Polygon.

+1

+1 для повторного факторинга. Я бы сказал, что любая ['Shape'] (http://download.oracle.com/javase/6/docs/api/java/awt/Shape.html) была бы разумной альтернативой. – trashgod

+0

@trashgod: Я согласен, но был удивлен, узнав, что Polygon ** является ** Shape в том, что он реализует интерфейс, но у него есть запах прошлого. –

+0

Ага, я понимаю, что вы имеете в виду: это _is_ наследство от 1.0. Большинство остальных, похоже, вошли в «Graphics2D». Благодаря! – trashgod

2

Используйте AffineTransform для масштабирования в направлении, ортогональном к нужной оси, как указано в этом answer на ваш вопрос. Также обратите внимание, что Polygon имеет метод translate(), который значительно упростит ваш код.

Добавление: Вот еще две методики, которые могут усилить иллюзию:

  1. Поочередно показать и скрыть выбранную ось как Shape меняет направление в пределах своей поездки. Это может быть достигнуто путем изменения порядка, в котором каждый нарисован.

  2. Инвертировать Shape, поскольку он меняет направление, отрицая масштаб в ортогональном направлении. Например, когда Shape «позади» оси x, используйте scale(1, -scaleFactor), что влияет на размер по вертикали.

+0

Я искал AffineTransform, но не могу понять, как масштабировать его в ортогональном направлении. –

+0

[Orthogonal] (http://en.wikipedia.org/wiki/Orthogonality) означает перпендикуляр. Если вы имитируете вращение вокруг оси _x_, тогда вы хотите масштабировать, когда будете переводить в направлении _y_. – trashgod