0

So i just learnt about affine transformation in java 2D and how each transformation behaves.So what i tried as a side project was to create a circle rotating around it's axis program,i tried translating first to the (0,0) then rotating by a degree then translating back to initial position,did that through 360 iterations with 1 degree increment but the circle still rotates out of that center points(although it goes back to its original point at last iteration). here's what have done so far:

public void paint(Graphics g)
  {
    Graphics2D g2d = (Graphics2D) g;

    //Use of antialiasing to have nicer lines.
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

    //The lines should have a thickness of 3.0 instead of 1.0.
    BasicStroke bs = new BasicStroke(3.0f);
    g2d.setStroke(bs);

    //The GeneralPath to decribe the car.
    //GeneralPath gp = new GeneralPath();

    //Start at the lower front of the car.
    g2d.setPaint(new Color(110, 100, 0));

    RenderingHints rh = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    //Draw the car.
    
    //g2d.fillOval(215, 135, 50, 50);
    Shape s = new Ellipse2D.Double(160,160,40,40);
    sustain(1000);
    for(int i=0;i<360;i++) {
        AffineTransform rotation = new AffineTransform();
        rotation.setToRotation(Math.PI/180+i);
        AffineTransform translate = new AffineTransform();
        translate.setToTranslation(-160, -160);
        AffineTransform translate2 = new AffineTransform();
        translate2.setToTranslation(160, 160);
        rotation.concatenate(translate);
        translate2.concatenate(rotation);
        clearWindow(g2d);
        g2d.setPaint(new Color(110, 100, 0));
        g2d.fill(translate2.createTransformedShape(s));
        
        
    }

  • One think you need to remember is, transforms are accumalitive – MadProgrammer Sep 16 '21 at 11:47
  • *I need it to rotate around its axis(have a circular motion in respect to its own center* - I'm not understanding that. A circle that rotates about its center will not appear to have any motion. Or are you talking about a moon rotating around the earth? I'm not understand why the answer below doesn't help? – camickr Sep 16 '21 at 13:25

1 Answers1

0

I've spent some time re-reading your question and looking over you code and I'm still unclear on

  1. What it is you want to do and
  2. What your problem is

But when has that ever stopped me from having a play

Spinning

Okay, so this has two circles (same shape) circling around a central point (translated) point.

Something to keep in mind is, transforms are accumulative, so you can see, between the second and third circle, I reset the transform (dispose of the graphics and take another snapshot) so my poor challenged brain doesn't get completely screwed up

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int angle = 0;

        public TestPane() {
            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    angle += 1;
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(120, 120);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            //Use of antialiasing to have nicer lines.
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            g2d.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
            g2d.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);

            RenderingHints rh = new RenderingHints(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

            Shape s = new Ellipse2D.Double(0, 0, 40, 40);
            g2d.transform(AffineTransform.getTranslateInstance(40, 40));
            g2d.setPaint(Color.RED);
            g2d.draw(s);
            g2d.transform(AffineTransform.getTranslateInstance(-30, -30));
            g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(angle), 50, 50));
            g2d.setPaint(new Color(110, 100, 0));
            g2d.drawRect(0, 0, 40, 40);
            g2d.draw(s);
            g2d.dispose();

            g2d = (Graphics2D) g.create();
            g2d.transform(AffineTransform.getTranslateInstance(40, 40));
            g2d.transform(AffineTransform.getTranslateInstance(-20, -20));
            g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(angle / 2), 40, 40));
            g2d.setPaint(Color.BLUE);
            g2d.drawRect(0, 0, 40, 40);
            g2d.draw(s);
        }

    }
}

I need it to rotate around its axis(have a circular motion in respect to its own center with out changing positions)

Okay, still not clear. If you want to rotate the object around it's centre point, but have it moving at the same time, then the order in which you apply your transformations is important.

For example, I'd translate it's position first, then rotate it, as it's easier to rotate about it's centre point without needing to calculate additional offsets

Rotate

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int angle = 0;
        private Path2D path;

        public TestPane() {

            path = new Path2D.Double();
            path.moveTo(20, 20);
            path.lineTo(0, 20);
            path.append(new Ellipse2D.Double(0, 0, 40, 40), false);

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    angle += 1;
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(120, 120);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            //Use of antialiasing to have nicer lines.
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            RenderingHints rh = new RenderingHints(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

            g2d.transform(AffineTransform.getTranslateInstance(40, 40));
            g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(angle), 20, 20));
            g2d.setPaint(Color.RED);
            g2d.draw(path);
            g2d.dispose();
        }

    }
}

And as an addition, you could also have a look at How to rotate an object around another moving object in java?

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • What I actually need is that for a particular shape,I need it to rotate around its axis(have a circular motion in respect to its own center with out changing positions) what my code does instead is rotate but changes position but goes back to its initial position after all iterations is done,but I want it to have a fixed rotational motion –  Sep 16 '21 at 13:00