Step By Step(Java 2D图形篇<二>) (一)

2014-11-24 03:21:37 · 作者: · 浏览: 18

本篇将继续介绍Java 2D 图形部分的内容。

5. 坐标变换:

坐标变换是图形编程中非常重要的一项技术,该技术在基于3D的开发中应用更为普遍,我们这里将介绍Java 2D中四种基本的变换:

1) 比例缩放(scale):放大和缩小从一个固定点出发的所有距离;

2) 旋转(rotate):环绕着一个固定中心旋转所有点;

3) 平移(translate):将所有的点移动一个固定量;

4) 切变(shear):使一个线条固定不变,再按照与该固定线条之间的距离,成比例地将与该线条平行的各个线条"滑动"一个距离量。

这里提及的四种变换规则可以组合在一起使用,然而需要注意的是,在组合时,Graphics2D是按照相反的顺序执行变换的,如:

1 public void paint(Graphics g) {

2 Graphics2D g2 = (Graphics2D)g;

3 g2.rotate(angle);

4 g2.scale(2,2);

5 g2.translate(x,y);

6 }

对于上面代码中的组合变换,translate将会被最先执行,其次是scale,最后才是rotate。

在Java 2D的API中提供了AffineTransform类用于描述各种变换,该类提供了一组静态工厂方法用于获取不同的AffineTransform子类,如:getRotateInstance、getScaleInstance、getTranslateInstance和getShearInstance。之后我们再通过Graphics2D.setTransform()方法设置当前Graphics的坐标变换对象。然而在实际的应用中,我们经常需要调用的却是Graphics2D.transform()方法以组合当前的变换和新设置的变换,而setTransform()域方法则是完全替换当前Graphics的变换为新设置的变换。

1 public class MyTest extends JPanel {

2 public static void main(String[] args) {

3 JFrame frame = new JFrame();

4 frame.setTitle("AffineTransform");

5 frame.setSize(1000, 600);

6 frame.addWindowListener(new WindowAdapter() {

7 public void windowClosing(WindowEvent e) {

8 System.exit(0);

9 }

10 });

11 Container contentPane = frame.getContentPane();

12 contentPane.add(new MyTest());

13 frame.show();

14 }

15 public void paintComponent(Graphics g) {

16 super.paintComponent(g);

17 g.setColor(Color.orange);

18 g.drawLine(0, getHeight()/4, getWidth(), getHeight()/4);

19 g.drawLine(0, getHeight()/2, getWidth(), getHeight()/2);

20 g.drawLine(0, getHeight()*3/4, getWidth(), getHeight()*3/4);

21 paintWithGraphicsMethod(g);

22 paintWithTransform(g);

23 paintWithSetTransform(g);

24 paintWithStaticTransformInstance(g);

25 }

26 //通过Graphics自身提供的变换方法进行变换

27 private void paintWithGraphicsMethod(Graphics g) {

28 //Graphics中的变换都是组合变换方式,

29 Graphics2D g2d = (Graphics2D) g;

30 AffineTransform oldTrans = g2d.getTransform();

31 g2d.setColor(Color.yellow);

32 g2d.fillRect(20, 20, 60, 60);

33 //1. 基于原点进行平移变换

34 g2d.translate(160, 0);

35 g2d.fillRect(20, 20, 60, 60);

36 //2. 基于1)平移变换后继续平移变换

37 g2d.translate(160, 0);

38 //3. 在2)平移的基础上进行旋转变换

39 g2d.rotate(Math.PI / 4);

40 g2d.fillRect(20, 20, 60, 60);

41 //4. 这里需要特别注意,由于3)中组合了旋转变换,因此这里再直接进行

42 //平移变换x时,因为坐标系的角度发生了变化,所以不能得到期望的平移

43 //效果,在平移前需要将3)中的旋转再反向旋转回来。

44 g2d.rotate(-Math.PI / 4);

45 g2d.translate(160, 0);

46 //5. 在4)的基础上做放大变换

47 g2d.scale(1.5, 1.5);

48 g2d.fillRect(20, 20, 60, 60);

49 //6. 做切变变化,可以通过调整shear()方法的两个参数,进一步掌握切变变换

50 g2d.translate(160, 0);

51