# Thread: Rotating a Polygon (Manually)

1. Member Join Date
Apr 2012
Posts
25
Rep Power
0

## 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). Transforms into (after x rotations at 90 deg) , 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 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  Reply With Quote

2. Senior Member Join Date
Jan 2013
Location
Northern Virginia, United States
Posts
6,226
Rep Power
14

## Re: Rotating a Polygon (Manually)

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

Regards,
Jim  Reply With Quote

3. Member Join Date
Apr 2012
Posts
25
Rep Power
0

## 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) {
}

/* 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-23-2013 at 12:35 AM.  Reply With Quote

4. Senior Member Join Date
Jan 2013
Location
Northern Virginia, United States
Posts
6,226
Rep Power
14

## 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  Reply With Quote

5. Member Join Date
Apr 2012
Posts
25
Rep Power
0

## 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.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);

}

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) {
}

/* 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 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-23-2013 at 12:41 AM.  Reply With Quote

6. Senior Member Join Date
Jan 2013
Location
Northern Virginia, United States
Posts
6,226
Rep Power
14

## 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  Reply With Quote

7. Member Join Date
Apr 2012
Posts
25
Rep Power
0

## 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 01:23 AM.  Reply With Quote

8. Senior Member Join Date
Jan 2013
Location
Northern Virginia, United States
Posts
6,226
Rep Power
14

## 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  Reply With Quote

#### Posting Permissions

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