Results 1 to 8 of 8
  1. #1
    driiper is offline Member
    Join Date
    Apr 2012
    Posts
    25
    Rep Power
    0

    Default Rotating a Polygon (Manually)

    Hello!

    I have a homework task where i'm supposed to rotate a Polygon (which i create myself with free drawing in my application).
    I have gotten the Polygon to rotate, but something is messing up after a while.

    I'm not completly sure why its happening, but i think it has to be somthing with the double --> integer casting, slowly changing some of the points in negative and positive direction.
    After a while the displacement of the points stop and it rotates like it should (with that wierd new shape).

    Rotating a Polygon (Manually)-ca6fc9f1bee167469fca80bda88b9a9a900f59d8.jpg Transforms into (after x rotations at 90 deg) Rotating a Polygon (Manually)-08903f2635532f7769b20581c98e9cdb1c348ec2.jpg, but it doesnt change from here.

    Code for rotating the Polygon ( a point in the polygon, i have for loop which calls this method for all points) is:
    Java Code:
    public Point rotatePoint(Point pt, Point center, double angleDeg) {
            // http://en.wikipedia.org/wiki/Rotation_matrix
            
            double angleRad = Math.toRadians(angleDeg);
            double cosThetha = Math.cos(angleRad); //The angle COS
            double sinThetha = Math.sin(angleRad); //The angle SIN
            double dx = (pt.x - center.x); //Difference (Point in transformed to origo)
            double dy = (pt.y - center.y); //Difference -- || --
    
            int ptX = center.x + (int) (dx * cosThetha - dy * sinThetha);
            int ptY = center.y + (int) (dx * sinThetha + dy * cosThetha);
    
            return new Point(ptX, ptY);
        }
    Have a nice day/evening!
    Driiper

  2. #2
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,657
    Rep Power
    5

    Default Re: Rotating a Polygon (Manually)

    Your rotation method looks ok. Can you include the rest of your code?

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  3. #3
    driiper is offline Member
    Join Date
    Apr 2012
    Posts
    25
    Rep Power
    0

    Default Re: Rotating a Polygon (Manually)

    Hello!

    Sure can
    Java Code:
        
    public void rotation() {
    
            Point panelSize = new Point(this.getWidth()/2, this.getHeight()/2);
    
            for (int i = 0; i < this.xPoly.length; i++) {
                Point p = this.rotatePoint(new Point(xPoly[i], yPoly[i]) , panelSize, 90);
                xPoly[i] = p.x;
                yPoly[i] = p.y;
            }
            System.out.println("\r\n");
            this.repaint();
        }
    the xPoly and yPoly array is just locations i clicked on the screen.
    Java Code:
     @Override
        public void mousePressed(MouseEvent e) {
    
            /* Record points */
            if (e.getButton() == MouseEvent.BUTTON1) {
                this.pointList.add(new Point(e.getX(), e.getY()));
            }
    
            /* Construct the polygon */
            if (e.getButton() == MouseEvent.BUTTON3) {
                xPoly = new int[this.pointList.size()];
                yPoly = new int[this.pointList.size()];
    
                for (int i = 0; i < this.pointList.size(); i++) {
                    xPoly[i] = this.pointList.get(i).x;
                    yPoly[i] = this.pointList.get(i).y;
                }
                this.pointList.clear();
            }
            this.repaint();
        }

    Thanks!

    Driiper
    Last edited by driiper; 09-22-2013 at 11:35 PM.

  4. #4
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,657
    Rep Power
    5

    Default Re: Rotating a Polygon (Manually)

    This can't be all your code! You need to provide the minimum required to allow compilation an execution.

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  5. #5
    driiper is offline Member
    Join Date
    Apr 2012
    Posts
    25
    Rep Power
    0

    Default Re: Rotating a Polygon (Manually)

    You are correct :) Sorry

    Java Code:
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.util.ArrayList;
    import java.util.ConcurrentModificationException;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    
    public class GUISkeleton {
    
        public static void main(String[] args) {
            new Frame();
        }
    }
    
    class Frame extends JFrame {
    
        public Frame() {
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setBounds(0, 0, 500, 500);
            this.setLocationRelativeTo(null);
    
            this.add(new Panel());
    
    
            this.setVisible(true);
        }
    }
    
    class Panel extends JPanel implements MouseListener, KeyListener {
    
        
        String legend = "|Translation: Arrow keys | Rotation: ,(-) and .(+) | Scale: k (-) and l (+) |";
        ArrayList<Point> pointList = new ArrayList<Point>();
        /* For drawing the polygon, will be null by default. this makes sure it wont be drawed until its set. */
        int[] xPoly = null;
        int[] yPoly = null;
    
        public Panel() {
            this.setFocusable(true);
            this.addMouseListener(this);
            this.addKeyListener(this);
    
        }
    
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            /* Draw Cosmetics */
            g.drawString(this.legend, 60, 20);
            g.setColor(new Color(255, 250, 205));
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            g.setColor(Color.GRAY);
    
            /* X lines */
            g.drawLine(0, (this.getHeight() / 2) + this.getHeight() / 4, this.getWidth(), (this.getHeight() / 2) + this.getHeight() / 4);
            g.drawLine(0, this.getHeight() / 2, this.getWidth(), this.getHeight() / 2);
            g.drawLine(0, this.getHeight() / 4, this.getWidth(), this.getHeight() / 4);
    
            /* Y lines */
            g.drawLine(this.getWidth() / 2, 0, this.getWidth() / 2, this.getHeight());
            g.drawLine(this.getWidth() / 4, 0, this.getWidth() / 4, this.getHeight());
            g.drawLine((this.getWidth() / 2) + (this.getWidth() / 4), 0, (this.getWidth() / 2) + (this.getWidth() / 4), this.getHeight());
    
            /* Draw "ORIGO" Point */
            g.fillOval((this.getWidth()/2)-5, (this.getHeight()/2)-5, 10, 10);
            
            g.setColor(Color.BLACK);
    
            /* Draw points which is clicked on the screen, also draws a line between them to mimic a polygon */
            Point lastPt = null;
            for (Point pt : this.pointList) {
                g.fillOval(pt.x - 5, pt.y - 5, 10, 10);
    
                /* Draws a line between current and the last Point */
                if (lastPt != null) {
                    g.drawLine(lastPt.x, lastPt.y, pt.x, pt.y);
                }
                lastPt = pt;
    
                /* Draw Line between First and last, (like we do in a polygon) */
                g.drawLine(this.pointList.get(0).x, this.pointList.get(0).y, this.pointList.get(this.pointList.size() - 1).x, this.pointList.get(this.pointList.size() - 1).y);
            }
    
            /* Whenever the polygon arrays are not null, we can draw it */
            if (xPoly != null && yPoly != null) {
                g.drawPolygon(xPoly, yPoly, xPoly.length);
            }
    
            // g.dispose();
        }
    
        @Override
        public void mouseClicked(MouseEvent e) {
            //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    
        @Override
        public void mousePressed(MouseEvent e) {
    
            /* Record points */
            if (e.getButton() == MouseEvent.BUTTON1) {
                this.pointList.add(new Point(e.getX(), e.getY()));
            }
    
            /* Construct the polygon */
            if (e.getButton() == MouseEvent.BUTTON3) {
                xPoly = new int[this.pointList.size()];
                yPoly = new int[this.pointList.size()];
    
                for (int i = 0; i < this.pointList.size(); i++) {
                    xPoly[i] = this.pointList.get(i).x;
                    yPoly[i] = this.pointList.get(i).y;
                }
                this.pointList.clear();
            }
            this.repaint();
        }
    
        @Override
        public void mouseReleased(MouseEvent e) {
            //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    
        @Override
        public void mouseEntered(MouseEvent e) {
            //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    
        @Override
        public void mouseExited(MouseEvent e) {
            //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    
        @Override
        public void keyTyped(KeyEvent e) {
            //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            if (xPoly != null && yPoly != null) {
                /* Translation */
                if (e.getKeyCode() == KeyEvent.VK_UP) {
                    this.translation(-1, true);
                }
                if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                    this.translation(1, true);
                }
                if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                    this.translation(-1, false);
                }
                if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                    this.translation(1, false);
                }
                if (e.getKeyCode() == KeyEvent.VK_0) {
                    this.rotation(true);
                }
            }
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    
        public void translation(int sign, boolean top) {
            if (xPoly.length != yPoly.length) {
                throw new ConcurrentModificationException("Xpoly and Ypoly should be the same lenght!");
            }
    
            for (int i = 0; i < this.xPoly.length; i++) {
                if (top) {
                    this.yPoly[i] = this.yPoly[i] + (1 * sign);
                } else {
                    this.xPoly[i] = this.xPoly[i] + (1 * sign);
                }
            }
            this.repaint();
        }
    
        public void rotation(boolean positive) {
    
            Point panelSize = new Point(this.getWidth()/2, this.getHeight()/2);
    
            for (int i = 0; i < this.xPoly.length; i++) {
                Point p = this.rotatePoint(new Point(xPoly[i], yPoly[i]) , panelSize, 90);
                xPoly[i] = p.x;
                yPoly[i] = p.y;
            }
            System.out.println("\r\n");
            this.repaint();
    
    
        }
    
        public Point rotatePoint(Point pt, Point center, double angleDeg) {
            // http://en.wikipedia.org/wiki/Rotation_matrix
            
            double angleRad = Math.toRadians(angleDeg);
            double cosThetha = Math.cos(angleRad); //The angle COS
            double sinThetha = Math.sin(angleRad); //The angle SIN
            double dx = (pt.x - center.x); //Difference (Point in transformed to origo)
            double dy = (pt.y - center.y); //Difference -- || --
    
            int ptX = center.x + (int) (dx * cosThetha - dy * sinThetha);
            int ptY = center.y + (int) (dx * sinThetha + dy * cosThetha);
    
            return new Point(ptX, ptY);
        }
    }
    Should be able to run it now. (Rotate with the 0 key).

    Thanks
    Driiper
    Last edited by driiper; 09-22-2013 at 11:41 PM.

  6. #6
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,657
    Rep Power
    5

    Default Re: Rotating a Polygon (Manually)

    Okay, I figured out your problem. If you change the rotation increment from 90 to 10 and hold down 0 after drawing the polygon you can see the image slowly shrinking toward the center. This is due to induced error from your calculations. You are storing the values as ints which is okay for plotting. But then you use those same ints again to recalculate then next set of points. Each time you do that you loose precision. I suggest you maintain a separate list of points just for plotting and keep the original polygon around for computing purposes. And instead of rotating 10 or 20 or 90 each time. Rotate an additive amount. That is rotating a set of points by 10 over and over for a 10 degree rotation is the same as rotating the original points first by 10, then by 20, then by 30 and so on. That way you wont loose precision.

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  7. #7
    driiper is offline Member
    Join Date
    Apr 2012
    Posts
    25
    Rep Power
    0

    Default Re: Rotating a Polygon (Manually)

    Hey,

    First, thanks ALOT for your help. Amazing!

    If i understand correctly i could just have a integer called, lets say angle. And lets say i then press my 0 key 10 times it the rotation angle would be 90 * 10?, And then never change the plot Array from the one i draw on the screen, making it computation wise only a single rotation on my points?

    (Dont know if that made sense :P hopefully it did)

    Again, thanks alot! Ill try it out!

    EDIT:
    Got it to work with the way you described!
    Thanks alot and have a nice Day/Evening !

    Driiper
    Last edited by driiper; 09-23-2013 at 12:23 AM.

  8. #8
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,657
    Rep Power
    5

    Default Re: Rotating a Polygon (Manually)

    You are correct! Rotating a set of integral coordinates each time for a fixed angle introduces error. But if you rotate the same set over and over again, changing the angle instead, you pretty much eliminate the error.

    And you're very welcome!
    Regards
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

Similar Threads

  1. manually trigger tooltips
    By stringargs in forum AWT / Swing
    Replies: 1
    Last Post: 05-04-2011, 08:51 PM
  2. Manually install Tomcat 7.02
    By contributor in forum New To Java
    Replies: 4
    Last Post: 09-04-2010, 02:27 PM
  3. setting cookies manually
    By dotanguy in forum Networking
    Replies: 0
    Last Post: 07-02-2010, 07:48 AM
  4. Manually adding a component
    By djc in forum NetBeans
    Replies: 3
    Last Post: 04-01-2009, 11:51 AM
  5. Handle exception manually
    By John_28 in forum New To Java
    Replies: 2
    Last Post: 06-05-2008, 11:26 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •