Shape rotation using mouse

Hi,

I抦 interested in rotating a shape by dragging the mouse.

For example, visualise a rectangle, now imagine pressing the mouse on the top left-hand corner, then dragging that corner down, with the mouse, to rotate the shape. That抯 what I want to do.

Has anyone got any thoughts on this?

Thanks,

Luke

[337 byte] By [dfgstga] at [2007-11-27 0:08:02]
# 1

import java.awt.*;

import java.awt.event.*;

import java.awt.geom.*;

import javax.swing.*;

import javax.swing.event.MouseInputAdapter;

public class DragRotation extends JPanel {

Rectangle2D.Double rect = new Rectangle2D.Double(100,75,200,160);

AffineTransform at = new AffineTransform();

protected void paintComponent(Graphics g) {

super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2.setPaint(Color.blue);

g2.draw(rect);

g2.setPaint(Color.red);

g2.draw(at.createTransformedShape(rect));

}

public static void main(String[] args) {

DragRotation test = new DragRotation();

test.addMouseListener(test.rotator);

test.addMouseMotionListener(test.rotator);

JFrame f = new JFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.getContentPane().add(test);

f.setSize(400,400);

f.setLocation(200,200);

f.setVisible(true);

}

private MouseInputAdapter rotator = new MouseInputAdapter() {

Point2D.Double center = new Point2D.Double();

double thetaStart = 0;

double thetaEnd = 0;

boolean rotating = false;

public void mousePressed(MouseEvent e) {

Point p = e.getPoint();

Shape shape = at.createTransformedShape(rect);

if(shape.contains(p)) {

Rectangle r = shape.getBounds();

center.x = r.getCenterX();

center.y = r.getCenterY();

double dy = p.y - center.y;

double dx = p.x - center.x;

thetaStart = Math.atan2(dy, dx) - thetaEnd;

//System.out.printf("press thetaStart = %.1f%n",

//Math.toDegrees(thetaStart));

rotating = true;

}

}

public void mouseReleased(MouseEvent e) {

rotating = false;

double dy = e.getY() - center.y;

double dx = e.getX() - center.x;

thetaEnd = Math.atan2(dy, dx) - thetaStart;

//System.out.printf("release thetaEnd = %.1f%n",

//Math.toDegrees(thetaEnd));

}

public void mouseDragged(MouseEvent e) {

if(rotating) {

double dy = e.getY() - center.y;

double dx = e.getX() - center.x;

double theta = Math.atan2(dy, dx);

at.setToRotation(theta - thetaStart, center.x, center.y);

repaint();

}

}

};

}

crwooda at 2007-7-11 16:06:46 > top of Java-index,Security,Cryptography...
# 2

thanks :)

tell me something tho, if I deffine a shape that is the same as rect:

...

// The shape to draw

Shape toDraw=rect;

And then each drag I trandform it:

public void mouseDragged(MouseEvent e

{

...

...

at.setToRotation(theta - thetaStart, center.x, center.y);

toDraw=at.createTransformedShape(toDraw);

repaint();

}

}

And draw that shape, it seems to rotate too much or some thing.

Why is this? As it seems to be more or less the same code as yours?

Thanks for the code tho :)

Luke

dfgstga at 2007-7-11 16:06:46 > top of Java-index,Security,Cryptography...
# 3

it seems to rotate too much or some thing

In the DragRotation class each rotation event is referenced to the original, non–rotated rect. When you redefine the shape each time then each rotation will have to be referenced to/from the last/current shape angular position. If it is already rotated and you rotate it with the current_rotated_angle plus the angle referenced to the original non–rotated rect you will get too much rotation. We have to change the way we reference the rotation.

If I start walking from Los Angeles to Chicago and measure my distance from LA each time I arrive at a new town, okay. If I measure the distance from town to town it is a different way to reference the distance walked. If I leave Denver, at a distance of 1000 miles from LA, and walk to Omaha, a distance of 550 miles, I would have walked a total of 1000 + 550 miles. But if I get confused about the counting and add the total from LA to Omaha to the miles walked on the last leg (from Denver) it would appear that I walked 1000 + 550 + 550 miles. So we need to be clear about how we are measuring the distance traveled.

import java.awt.*;

import java.awt.event.*;

import java.awt.geom.*;

import javax.swing.*;

import javax.swing.event.MouseInputAdapter;

public class DragRotation extends JPanel {

Rectangle2D.Double rect = new Rectangle2D.Double(100,75,200,160);

Shape shape = rect;

protected void paintComponent(Graphics g) {

super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2.setPaint(Color.blue);

g2.draw(rect);

g2.setPaint(Color.red);

g2.draw(shape);

}

public static void main(String[] args) {

DragRotation test = new DragRotation();

test.addMouseListener(test.rotator);

test.addMouseMotionListener(test.rotator);

JFrame f = new JFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.getContentPane().add(test);

f.setSize(400,400);

f.setLocation(200,200);

f.setVisible(true);

}

private MouseInputAdapter rotator = new MouseInputAdapter() {

AffineTransform at = new AffineTransform();

Point2D.Double center = new Point2D.Double();

double thetaStart = 0;

boolean rotating = false;

public void mousePressed(MouseEvent e) {

Point p = e.getPoint();

if(shape.contains(p)) {

Rectangle r = shape.getBounds();

center.x = r.getCenterX();

center.y = r.getCenterY();

double dy = p.y - center.y;

double dx = p.x - center.x;

thetaStart = Math.atan2(dy, dx);

rotating = true;

}

}

public void mouseReleased(MouseEvent e) {

rotating = false;

}

public void mouseDragged(MouseEvent e) {

if(rotating) {

double dy = e.getY() - center.y;

double dx = e.getX() - center.x;

double theta = Math.atan2(dy, dx);

at.setToRotation(theta - thetaStart, center.x, center.y);

shape = at.createTransformedShape(shape);

repaint();

// Counting in increments now.

thetaStart = theta;

}

}

};

}

crwooda at 2007-7-11 16:06:46 > top of Java-index,Security,Cryptography...
# 4
Ahh, yes I see, that makes sence now.Thanks for your help. I now have an app were the user can draw a shape, then scale, translate, and now drag, using the shift and control keys and the mouse.Thanks again.Luke
dfgstga at 2007-7-11 16:06:46 > top of Java-index,Security,Cryptography...