简体   繁体   中英

Rotating a shape vertically around the x-axis

I have a 2d graph with an x and y axis and im trying to rotate a shape (series of points) around an axis. This rotation will need to include a scale function.

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

Absent a clear question, a simple animation using your coordinate arrays is shown below. In general you can transform the graphics context ( g2d ) or the polygonal Shape itself ( p3 ); the example shows both. Resize the window to see the effect of each.

Note the last-specified-first-applied order of the transformations in at . First, a suitable point on p3 is translated to the origin, then p3 is scaled, and then p3 is translated to the center of the panel. The + 10 fudge factor applied to p3 is an artifact of having no symmetric rotation point. It may be easier to define your polygons relative to the origin, as shown in this 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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM