2011-04-08 38 views
3

我有一个带有x和y轴的二维图形,我试图围绕一个轴旋转一个形状(一系列点)。这种轮换将需要包括一个比例函数。围绕x轴垂直旋转一个形状

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 { 

    int[] p1x = {200, 200, 240, 240, 220, 220, 200}; 
    int[] p1y = {200, 260, 260, 240, 240, 200, 200}; 
    int[] p2x = {600, 600, 620, 620, 640, 640, 660, 660, 600}; 
    int[] p2y = {400, 420, 420, 460, 460, 420, 420, 400, 400}; 
    int[] p3x = {400, 400, 460, 460, 440, 440, 420, 420, 400}; 
    int[] p3y = {400, 460, 460, 400, 400, 440, 440, 400, 400}; 
    int delay = 1000; 
    int dx = 0; 
    int dy = 5; 
    int steps = 121; 
    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)));; 

      Point2D original = new Point2D.Double(p2x[i], p2y[i]); 
      AffineTransform at = new AffineTransform(); 
      //at.setToRotation(.02, 250, 250); 
      at.scale(1, -1); 
      Point2D rotated = at.transform(original, null); 
      p2x[i] = (int) rotated.getX(); 
      p2y[i] = (int) rotated.getY(); 
     } 
     repaint(); 

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

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

     this.setBackground(Color.white); 

     g.drawLine(this.getWidth()/2, 0, this.getWidth()/2, this.getWidth()); 
     g.drawLine(0, this.getHeight()/2, this.getHeight(), this.getHeight()/2); 

     Polygon t = new Polygon(p2x, p2y, 9); 
     g.drawPolygon(t); 

     Letters u = new Letters(p3x, p3y, 9); 
     u.draw(g); 

     Letters l = new Letters(p1x, p1y, 7); 
     l.draw(g); 
    } 

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

重新格式化的代码;如果不正确请回复。 – trashgod 2011-04-08 09:30:55

回答

10

如果没有明确的问题,使用坐标数组的简单动画如下所示。一般来说,您可以转换图形上下文(​​)或多边形Shape本身(p3);该示例显示了两者。调整窗口大小以查看每个效果。

注意最后指定优先转换的顺序在at。首先,将p3上的合适点翻译为原点,然后对p3进行缩放,然后将p3转换为面板的中心。适用于p3+ 10巧妙因素是没有对称旋转点的伪影。定义相对于原点的多边形可能更容易,如example所示。

AffineTest

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

/** @see http://stackoverflow.com/questions/3405799 */ 
public class AffineTest extends JPanel implements ActionListener { 

    private static final double DELTA_THETA = Math.PI/45; // 4° 
    private static final double DELTA_SCALE = 0.1; 
    private int[] p1x = {200, 200, 240, 240, 220, 220, 200}; 
    private int[] p1y = {200, 260, 260, 240, 240, 200, 200}; 
    private int[] p2x = {600, 600, 620, 620, 640, 640, 660, 660, 600}; 
    private int[] p2y = {400, 420, 420, 460, 460, 420, 420, 400, 400}; 
    private int[] p3x = {400, 400, 460, 460, 440, 440, 420, 420, 400}; 
    private int[] p3y = {400, 460, 460, 400, 400, 440, 440, 400, 400}; 
    private Polygon p1 = new Polygon(p1x, p1y, p1x.length); 
    private Polygon p2 = new Polygon(p2x, p2y, p2x.length); 
    private Polygon p3 = new Polygon(p3x, p3y, p3x.length); 
    private AffineTransform at = new AffineTransform(); 
    private double dt = DELTA_THETA; 
    private double theta; 
    private double ds = DELTA_SCALE; 
    private double scale = 1; 
    private Timer timer = new Timer(100, this); 

    public AffineTest() { 
     this.setPreferredSize(new Dimension(700, 700)); 
     this.setBackground(Color.white); 
     p1.translate(-50, +100); 
     p2.translate(-100, -100); 
    } 

    @Override 
    public void actionPerformed(ActionEvent event) { 
     theta += dt; 
     scale += ds; 
     if (scale < .5 || scale > 4) { 
      ds = -ds; 
     } 
     repaint(); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     int w = this.getWidth(); 
     int h = this.getHeight(); 
     g2d.drawLine(w/2, 0, w/2, h); 
     g2d.drawLine(0, h/2, w, h/2); 
     g2d.rotate(theta, w/2, h/2); 
     g2d.drawPolygon(p1); 
     g2d.drawPolygon(p2); 
     at.setToIdentity(); 
     at.translate(w/2, h/2); 
     at.scale(scale, scale); 
     at.translate(-p3x[5] + 10, -p3y[5]); 
     g2d.setPaint(Color.blue); 
     g2d.fill(at.createTransformedShape(p3)); 
    } 

    public void start() { 
     timer.start(); 
    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame("Affine Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     AffineTest sl = new AffineTest(); 
     frame.add(sl); 
     frame.pack(); 
     frame.setVisible(true); 
     sl.start(); 
    } 
} 
+0

谢谢你们,非常有帮助。帮助澄清一些混淆。我正在试图围绕x轴旋转这些字母,而不是围绕2D图上的原点。请注意,通过缩放可以实现顶点向“z方向”(帧外)的旋转;并且每个字母的坐标轴相对于框架的坐标轴具有相对位置。 – 2011-04-08 18:30:05

+1

非常好。有一个[sscce](http://sscce.org/)供参考是非常宝贵的;但是,因为你是一名学生,所以我不想玩得很开心。 :-)您应该能够通过在正交方向上缩放和平移来模拟围绕轴的旋转;离轴通常需要剪切。请考虑接受和/或投票处理此问题以及您收到的其他答案。 – trashgod 2011-04-08 19:28:53

+0

+1非常好我喜欢:) – 2013-01-05 08:02:23