import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class MainClass { public static void main(String[] args) { JFrame jf = new JFrame("Demo"); Container cp = jf.getContentPane(); MyCanvas tl = new MyCanvas(); cp.add(tl); jf.setSize(300, 300); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } class MyCanvas extends JComponent { Shape shape; public MyCanvas() { shape = create(); } protected Shape create() { float cm = 30f; return new Rectangle2D.Float(2*cm, 2*cm, cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setPaint(Color.black); g2.draw(shape); AffineTransform trans = new AffineTransform(); trans.scale(-1, 1); trans.translate(-120, 0); g2.transform(trans); g2.setPaint(Color.red); g2.draw(shape); } }
这种效果就是翻转之后再往后移120,但如果这样又为何会如此:
import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class MainClass { public static void main(String[] args) { JFrame jf = new JFrame("Demo"); Container cp = jf.getContentPane(); MyCanvas tl = new MyCanvas(); cp.add(tl); jf.setSize(300, 300); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } class MyCanvas extends JComponent { Shape shape; public MyCanvas() { shape = create(); } protected Shape create() { float cm = 30f; return new Rectangle2D.Float(2*cm, 2*cm, cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setPaint(Color.black); g2.draw(shape); AffineTransform trans = new AffineTransform(); trans.scale(-1, 1); g2.transform(trans); trans.translate(-30, 0); g2.transform(trans); g2.setPaint(Color.red); g2.draw(shape); } }
结果与上图一样,怎么会这样呢,按理往后移30应该是看不到,原因是这里多了句
g2.transform(trans);
这句是什么作用呢,看解释:
AffineTransform
object with the
Transform
in this
Graphics2D
according to the rule last-specified-first-applied. If the current
Transform
is Cx, the result of composition with Tx is a new
Transform
Cx'. Cx' becomes the current
Transform
for this
Graphics2D
. Transforming a point p by the updated
Transform
Cx' is equivalent to first transforming p by Tx and then transforming the result by the original
Transform
Cx. In other words, Cx'(p) = Cx(Tx(p)). A copy of the Tx is made, if necessary, so further modifications to Tx do not affect rendering.
Tx
- the
AffineTransform
object to be composed with the current
Transform
这里貌似是有问题的,Cx'怎么感觉就没翻转过呢,就感觉scale和transform两句没有发生作用一样,这是怎么回事呢?原因就是负负得正了,翻转两次,效果取消,看下文:
import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class MainClass { public static void main(String[] args) { JFrame jf = new JFrame("Demo"); Container cp = jf.getContentPane(); MyCanvas tl = new MyCanvas(); cp.add(tl); jf.setSize(300, 300); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } class MyCanvas extends JComponent { Shape shape; public MyCanvas() { shape = create(); } protected Shape create() { float cm = 30f; return new Rectangle2D.Float(2*cm, 2*cm, cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.translate(90, 0); g2.setPaint(Color.black); g2.draw(shape); g2.drawLine(0, 0, 0, 5); g2.drawLine(-30, 0, -30, 5); g2.drawLine(-60, 0, -60, 5); g2.drawLine(-90, 0, -90, 5); g2.drawLine(-120, 0, -120, 5); g2.drawLine(30, 0, 30, 5); g2.drawLine(60, 0, 60, 5); g2.drawLine(90, 0, 90, 5); g2.drawLine(120, 0, 120, 5); g2.drawLine(150, 0, 150, 5); g2.drawLine(180, 0, 180, 5); AffineTransform trans = new AffineTransform(); trans.scale(-1, 1); g2.transform(trans); g2.transform(trans); g2.setPaint(Color.red); g2.draw(shape); } }
这里有完备的教程:
http://www.glyphic.com/transform/applet/1intro.html
记住一点,这个对象AffineTransform是面向坐标系操作的,也就是说它的操作对象是坐标系。