Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Help with transforms

Reply
Thread Tools

Help with transforms

 
 
Ian Stanley
Guest
Posts: n/a
 
      07-30-2003
Hi,
I have a simple program below where the user can draw rectangles on a panel.
The choice to either rotate or scale any single rectangle should result in
the appropriate action.(after selecting a shape).
However, the selected rectangle is transformed(rotated or scaled) but it
appears to be drawn translated as well.
I am guessing that it has somethig to do with transforming the coordinate
system for that shape.
Is there a way to fix it so that the selected shape is rotated or scaled at
its current location?
Thanking you in advance
Ian.

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class SwingDraw
{
public static void main(String[] args)
{
Draw D = new Draw() ;
}
}

interface Constants {
final int RECTANGLE = 1, ROTATE = 2, SCALE = 3;
}

class Draw extends JFrame
implements Constants, ActionListener{
JPanel bp = new JPanel() ;
DrawJPanel djp ;
Container content = getContentPane() ;
JButton rectButton, rotateButton, quitButton, scaleButton ;

Draw() {
super() ;
content.setLayout(new BorderLayout()) ;
djp = new DrawJPanel() ;
bp.add(rectButton = new JButton("Rectangle")) ;
bp.add(rotateButton = new JButton("rotate")) ;
bp.add(scaleButton = new JButton("scale")) ;
bp.add(quitButton = new JButton("Quit")) ;
quitButton.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent
e) {
System.exit(0) ;
}
}) ;
rectButton.addActionListener(this) ;
rotateButton.addActionListener(this) ;
scaleButton.addActionListener(this) ;
content.add(bp, BorderLayout.NORTH) ;
content.add(djp, BorderLayout.CENTER) ;
setSize(750, 500) ;
setVisible(true) ;
}


public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand() ;
switch (cmd.charAt(0)) {
case 'R':
djp.setMode(RECTANGLE) ;
break ;
case 'r':
djp.setMode(ROTATE) ;
break ;
case 's':
djp.setMode(SCALE) ;
break ;
}
}

}
class DrawJPanel extends JPanel
implements Constants
{
Vector v = new Vector();
Shape current_shape = null;
int drawingMode;
public DrawJPanel()
{
addMouseListener(
new MouseAdapter() {
public void mousePressed(MouseEvent evt)
{
int x = evt.getX();
int y = evt.getY();
// check if we hit an existing shape
current_shape = locateRect(x,y);
// if ( current_shape==null)
// {
if (drawingMode == RECTANGLE){
Rectangle2D.Float e = new
Rectangle2D.Float(x, y, 80, 50);
v.add(e);
repaint();
}
else if (drawingMode == ROTATE &&
current_shape != null ){
rotateShape(x,y);
repaint();
}
else if (drawingMode == SCALE &&
current_shape != null ){
scaleShape(x,y);
repaint();
}
}
}
);
}
void setMode(int mode) {
drawingMode = mode ;
}

public Shape locateRect(int x, int y)
{
for (int i = 0; i < v.size(); i++){
Shape s = (Shape)v.elementAt(i);
if (s.contains(x,y) )
return s;
}
return null;
}

public Shape rotateShape(int x, int y)
{
for (int i = 0; i < v.size(); i++){
Shape s = (Shape)v.elementAt(i);
if (s.contains(x,y) ){
AffineTransform tr =
AffineTransform.getRotateInstance(Math.toRadians(4 5));
Shape ts = tr.createTransformedShape(current_shape);
v.addElement(ts);
v.removeElement(s);
repaint();
}
}
return null;
}

public Shape scaleShape(int x, int y)

{
for (int i = 0; i < v.size(); i++){
Shape s = (Shape)v.elementAt(i);
if (s.contains(x,y) ){
AffineTransform tr =
AffineTransform.getScaleInstance(0.7,0.7);
Shape ts = tr.createTransformedShape(current_shape);
v.addElement(ts);
v.removeElement(s);
repaint();
}
}
return null;
}

public void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
for(int i=0; i<v.size(); i++)
g.draw((Shape)v.elementAt(i));
}
}


 
Reply With Quote
 
 
 
 
Larry A Barowski
Guest
Posts: n/a
 
      07-30-2003
"Ian Stanley" <> wrote in message news:<>...
> Hi,
> I have a simple program below where the user can draw rectangles on a panel.
> The choice to either rotate or scale any single rectangle should result in
> the appropriate action.(after selecting a shape).
> However, the selected rectangle is transformed(rotated or scaled) but it
> appears to be drawn translated as well.
> I am guessing that it has somethig to do with transforming the coordinate
> system for that shape.
> Is there a way to fix it so that the selected shape is rotated or scaled at
> its current location?


You want AffineTransform.getRotateInstance(double theta, double x,
double y), but the definition of center point is up to you. You should
probably store the original center rather than computing it from
Shape bounds, to avoid drift. Actually, you should probably store the
original Shape, current rotation, and current scale. Whenever the
the rotation or scale changes, rebuild the transformed object. This
will avoid roundoff errors due to repeated transforming. So v would
contain objects with: original shape, center point, current rotation,
current scale, and transformed shape.


-Larry


> Thanking you in advance
> Ian.
>
> import java.awt.*;
> import java.awt.event.*;
> import java.awt.geom.*;
> import java.util.*;
> import javax.swing.*;
> public class SwingDraw
> {
> public static void main(String[] args)
> {
> Draw D = new Draw() ;
> }
> }
>
> interface Constants {
> final int RECTANGLE = 1, ROTATE = 2, SCALE = 3;
> }
>
> class Draw extends JFrame
> implements Constants, ActionListener{
> JPanel bp = new JPanel() ;
> DrawJPanel djp ;
> Container content = getContentPane() ;
> JButton rectButton, rotateButton, quitButton, scaleButton ;
>
> Draw() {
> super() ;
> content.setLayout(new BorderLayout()) ;
> djp = new DrawJPanel() ;
> bp.add(rectButton = new JButton("Rectangle")) ;
> bp.add(rotateButton = new JButton("rotate")) ;
> bp.add(scaleButton = new JButton("scale")) ;
> bp.add(quitButton = new JButton("Quit")) ;
> quitButton.addActionListener(
> new ActionListener(){
> public void actionPerformed(ActionEvent
> e) {
> System.exit(0) ;
> }
> }) ;
> rectButton.addActionListener(this) ;
> rotateButton.addActionListener(this) ;
> scaleButton.addActionListener(this) ;
> content.add(bp, BorderLayout.NORTH) ;
> content.add(djp, BorderLayout.CENTER) ;
> setSize(750, 500) ;
> setVisible(true) ;
> }
>
>
> public void actionPerformed(ActionEvent e) {
> String cmd = e.getActionCommand() ;
> switch (cmd.charAt(0)) {
> case 'R':
> djp.setMode(RECTANGLE) ;
> break ;
> case 'r':
> djp.setMode(ROTATE) ;
> break ;
> case 's':
> djp.setMode(SCALE) ;
> break ;
> }
> }
>
> }
> class DrawJPanel extends JPanel
> implements Constants
> {
> Vector v = new Vector();
> Shape current_shape = null;
> int drawingMode;
> public DrawJPanel()
> {
> addMouseListener(
> new MouseAdapter() {
> public void mousePressed(MouseEvent evt)
> {
> int x = evt.getX();
> int y = evt.getY();
> // check if we hit an existing shape
> current_shape = locateRect(x,y);
> // if ( current_shape==null)
> // {
> if (drawingMode == RECTANGLE){
> Rectangle2D.Float e = new
> Rectangle2D.Float(x, y, 80, 50);
> v.add(e);
> repaint();
> }
> else if (drawingMode == ROTATE &&
> current_shape != null ){
> rotateShape(x,y);
> repaint();
> }
> else if (drawingMode == SCALE &&
> current_shape != null ){
> scaleShape(x,y);
> repaint();
> }
> }
> }
> );
> }
> void setMode(int mode) {
> drawingMode = mode ;
> }
>
> public Shape locateRect(int x, int y)
> {
> for (int i = 0; i < v.size(); i++){
> Shape s = (Shape)v.elementAt(i);
> if (s.contains(x,y) )
> return s;
> }
> return null;
> }
>
> public Shape rotateShape(int x, int y)
> {
> for (int i = 0; i < v.size(); i++){
> Shape s = (Shape)v.elementAt(i);
> if (s.contains(x,y) ){
> AffineTransform tr =
> AffineTransform.getRotateInstance(Math.toRadians(4 5));
> Shape ts = tr.createTransformedShape(current_shape);
> v.addElement(ts);
> v.removeElement(s);
> repaint();
> }
> }
> return null;
> }
>
> public Shape scaleShape(int x, int y)
>
> {
> for (int i = 0; i < v.size(); i++){
> Shape s = (Shape)v.elementAt(i);
> if (s.contains(x,y) ){
> AffineTransform tr =
> AffineTransform.getScaleInstance(0.7,0.7);
> Shape ts = tr.createTransformedShape(current_shape);
> v.addElement(ts);
> v.removeElement(s);
> repaint();
> }
> }
> return null;
> }
>
> public void paintComponent(Graphics gr)
> {
> super.paintComponent(gr);
> Graphics2D g = (Graphics2D)gr;
> for(int i=0; i<v.size(); i++)
> g.draw((Shape)v.elementAt(i));
> }
> }

 
Reply With Quote
 
 
 
 
Roedy Green
Guest
Posts: n/a
 
      07-30-2003
On Wed, 30 Jul 2003 22:00:29 +0930, "Ian Stanley"
<> wrote or quoted :

>I am guessing that it has somethig to do with transforming the coordinate
>system for that shape.


the tool you probably want is AffineTransform.rotate(double
thetaInRadians, double x, double y) Concatenates this transform with a
transform that rotates coordinates around an anchor point.

see http://mindprod.com/jgloss/affinetransform.html
and http://mindprod.com/jgloss/coordinates.html

--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
 
Reply With Quote
 
Ian Stanley
Guest
Posts: n/a
 
      07-31-2003
Thanks.
But is there a "hack" or a simple way where I can first work out where the
centre of the shape is and apply a translation relative to these coords
and(0,0) . And then apply the rotation which will rotate the shape about it
centre.
I have lookded at the Sun 2d Transform example which rotates/translates
shapes and they always appear centered. I would like try try something like
this(for my level of understanding) and then try to understand/utilise the
api in more detail:--
Calculate the centre of the panel, working out where the center of the shape
is and applying a tranformation involving this "offset".
The Sun tranform example uses the following to center the shape. I have
tried to do similar in my program but without success.
AffineTransform toCenterAt = new AffineTransform();
toCenterAt.concatenate(at);
toCenterAt.translate(-(r.width/2), -(r.height/2));
any further help appreciated.
Ian
ps the link to the complete transform example:
http://java.sun.com/docs/books/tutor...nsforming.html


"Ian Stanley" <> wrote in message
news:...
> Hi,
> I have a simple program below where the user can draw rectangles on a

panel.
> The choice to either rotate or scale any single rectangle should result in
> the appropriate action.(after selecting a shape).
> However, the selected rectangle is transformed(rotated or scaled) but it
> appears to be drawn translated as well.
> I am guessing that it has somethig to do with transforming the coordinate
> system for that shape.
> Is there a way to fix it so that the selected shape is rotated or scaled

at
> its current location?
> Thanking you in advance
> Ian.
>
> import java.awt.*;
> import java.awt.event.*;
> import java.awt.geom.*;
> import java.util.*;
> import javax.swing.*;
> public class SwingDraw
> {
> public static void main(String[] args)
> {
> Draw D = new Draw() ;
> }
> }
>
> interface Constants {
> final int RECTANGLE = 1, ROTATE = 2, SCALE = 3;
> }
>
> class Draw extends JFrame
> implements Constants, ActionListener{
> JPanel bp = new JPanel() ;
> DrawJPanel djp ;
> Container content = getContentPane() ;
> JButton rectButton, rotateButton, quitButton, scaleButton ;
>
> Draw() {
> super() ;
> content.setLayout(new BorderLayout()) ;
> djp = new DrawJPanel() ;
> bp.add(rectButton = new JButton("Rectangle")) ;
> bp.add(rotateButton = new JButton("rotate")) ;
> bp.add(scaleButton = new JButton("scale")) ;
> bp.add(quitButton = new JButton("Quit")) ;
> quitButton.addActionListener(
> new ActionListener(){
> public void

actionPerformed(ActionEvent
> e) {
> System.exit(0) ;
> }
> }) ;
> rectButton.addActionListener(this) ;
> rotateButton.addActionListener(this) ;
> scaleButton.addActionListener(this) ;
> content.add(bp, BorderLayout.NORTH) ;
> content.add(djp, BorderLayout.CENTER) ;
> setSize(750, 500) ;
> setVisible(true) ;
> }
>
>
> public void actionPerformed(ActionEvent e) {
> String cmd = e.getActionCommand() ;
> switch (cmd.charAt(0)) {
> case 'R':
> djp.setMode(RECTANGLE) ;
> break ;
> case 'r':
> djp.setMode(ROTATE) ;
> break ;
> case 's':
> djp.setMode(SCALE) ;
> break ;
> }
> }
>
> }
> class DrawJPanel extends JPanel
> implements Constants
> {
> Vector v = new Vector();
> Shape current_shape = null;
> int drawingMode;
> public DrawJPanel()
> {
> addMouseListener(
> new MouseAdapter() {
> public void mousePressed(MouseEvent evt)
> {
> int x = evt.getX();
> int y = evt.getY();
> // check if we hit an existing shape
> current_shape = locateRect(x,y);
> // if ( current_shape==null)
> // {
> if (drawingMode == RECTANGLE){
> Rectangle2D.Float e = new
> Rectangle2D.Float(x, y, 80, 50);
> v.add(e);
> repaint();
> }
> else if (drawingMode == ROTATE &&
> current_shape != null ){
> rotateShape(x,y);
> repaint();
> }
> else if (drawingMode == SCALE &&
> current_shape != null ){
> scaleShape(x,y);
> repaint();
> }
> }
> }
> );
> }
> void setMode(int mode) {
> drawingMode = mode ;
> }
>
> public Shape locateRect(int x, int y)
> {
> for (int i = 0; i < v.size(); i++){
> Shape s = (Shape)v.elementAt(i);
> if (s.contains(x,y) )
> return s;
> }
> return null;
> }
>
> public Shape rotateShape(int x, int y)
> {
> for (int i = 0; i < v.size(); i++){
> Shape s = (Shape)v.elementAt(i);
> if (s.contains(x,y) ){
> AffineTransform tr =
> AffineTransform.getRotateInstance(Math.toRadians(4 5));
> Shape ts = tr.createTransformedShape(current_shape);
> v.addElement(ts);
> v.removeElement(s);
> repaint();
> }
> }
> return null;
> }
>
> public Shape scaleShape(int x, int y)
>
> {
> for (int i = 0; i < v.size(); i++){
> Shape s = (Shape)v.elementAt(i);
> if (s.contains(x,y) ){
> AffineTransform tr =
> AffineTransform.getScaleInstance(0.7,0.7);
> Shape ts = tr.createTransformedShape(current_shape);
> v.addElement(ts);
> v.removeElement(s);
> repaint();
> }
> }
> return null;
> }
>
> public void paintComponent(Graphics gr)
> {
> super.paintComponent(gr);
> Graphics2D g = (Graphics2D)gr;
> for(int i=0; i<v.size(); i++)
> g.draw((Shape)v.elementAt(i));
> }
> }
>
>



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Multiple XSLT Transforms using a Controller XSLT sneill@mxlogic.com XML 2 10-19-2005 11:00 AM
Multiple XSLt Transforms? rush XML 3 03-30-2005 09:39 PM
xslt, multiple transforms Random ASP .Net 3 02-28-2005 10:38 PM
Different transforms for different children of same type Ravi XML 4 11-10-2003 08:22 PM
Fourier transforms (coefficient calculation)... Matthew C++ 2 10-03-2003 01:01 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57