代码如此的短,被我优化过,所以不很容易看懂。有这个想法源于看图形学时看到的直线的画法,当时我想,用这个方法用来画空间投射线也应该很容易。于是就做了这个基于空间投射线的3D模型成像。 代码里面基本是算法,但是终归要有一个3D模型才能成像,于是我建立了一个3维数组,用来储存空间的点信息。也就是byte[][][] data;然后随便画了几个矩形、几个点,看起来效果还是不错的。(其实class Mod里面基本上都在画这些点和矩形) 【原理】从视点透出201×201的空间投射线,如果和空间中的3D模型相碰撞则返回并记录下点的颜色信息。最后产生一张201×201的2D图形,然后放大到603×603,并显示。 用(E)(D)(S)(F)来控制视点的上下左右移动,用(J)(K)(L)来控制视点的前进后退和复原。 【Model.java】 import java.awt.*;import java.awt.event.*;import java.awt.image.*;import javax.swing.*; public class Model{ public static void main(String [] args){ MFrame f = new MFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(608,628); f.setVisible(true); }} class MFrame extends JFrame{ MFrame(){ Container pane = getContentPane(); MPanel p = new MPanel(); pane.add(p); }} class MPanel extends JPanel implements KeyListener{ MPanel(){ addKeyListener(this); } public boolean isFocusTraversable(){ return true; } public void keyPressed(KeyEvent e){ if(e.getKeyCode() == KeyEvent.VK_S){ cam.subX(); } if(e.getKeyCode() == KeyEvent.VK_F){ cam.addX(); } if(e.getKeyCode() == KeyEvent.VK_E){ cam.subY(); } if(e.getKeyCode() == KeyEvent.VK_D){ cam.addY(); } if(e.getKeyCode() == KeyEvent.VK_J){ cam.addZ(); } if(e.getKeyCode() == KeyEvent.VK_K){ cam.subZ(); } if(e.getKeyCode() == KeyEvent.VK_L){ cam.resume(); } image = getImage(); repaint();// System.out.println(cam.getX() +" "+cam.getY()+" "+cam.getZ()); } public void keyReleased(KeyEvent e){} public void keyTyped(KeyEvent e){} public BufferedImage getImage(){ BufferedImage img = new BufferedImage(603,603,BufferedImage.TYPE_INT_RGB); WritableRaster raster = img.getRaster(); byte color; int [] rgb = {0,0,0}; for(int i = 0;i < 201;i ++){ for(int j = 0;j < 201;j ++){ geted[i][j] = false; } } cam.reset(); int z = cam.getZ(); int x = cam.getX(); int y = cam.getY(); while(z < 200){ cam.stepZ(); z++; for(int i = 0;i < 201;i ++){ for(int j = 0;j < 201;j ++){ if(!geted[i][j]){ color = mod.getData(x + cam.getTXY(i), y + cam.getTXY(j), z); if (color != 0) { rgb[0] = (color % 4) * 85; rgb[1] = ((color % 16) / 4) * 85; rgb[2] = (color / 16) * 85; for (int ii = 0; ii < 3; ii++) { for (int jj = 0; jj < 3; jj++) { raster.setPixel(i * 3 + ii,j * 3 + jj, rgb); } } geted[i][j] = true; } } } } } return img; } public void paintComponent(Graphics g){ super.paintComponent(g); g.drawImage(image,0,0,null); } private BufferedImage image = new BufferedImage(603,603,BufferedImage.TYPE_INT_RGB); private Mod mod = new Mod(); private Camera cam = new Camera(); private boolean[][] geted = new boolean[201][201];} class Camera{ Camera(){ for(int i = 0;i < 100;i ++){ stepX[i] = -1; int k = 2*i; pX[i] = 100 - k; tdx[i] = 200 - k; tdxdz[i] = -k; } for(int i = 100;i < 201;i ++){ stepX[i] = 1; int k = 2*i; pX[i] = k - 300; tdx[i] = k - 200; tdxdz[i] = k - 400; } resume(); } public int getTXY(int i){ return tX[i]; } public void stepZ(){ for(int i = 0;i < 201;i ++){ if(pX[i] < 0){ pX[i] += tdx[i]; } else{ tX[i] += stepX[i]; pX[i] += tdxdz[i]; } } } public void reset(){ for(int i = 0;i < 100;i ++){ pX[i] = 100 - 2*i; } for(int i = 100;i < 201;i ++){ pX[i] = 2*i - 300; } for(int i = 0;i < 201;i ++){ tX[i] = 0; } } public void resume(){ x = 50;y = 50;z = 50; } public void addX(){x++;} public void subX(){x--;} public void addY(){y++;} public void subY(){y--;} public void addZ(){z++;} public void subZ(){z--;} public int getX(){return this.x;} public int getY(){return this.y;} public int getZ(){return this.z;} private int x,y,z; private int[] stepX = new int[201]; private int[] tX = new int [201]; private int[] pX = new int [201]; private int[] tdx = new int [201]; private int[] tdxdz = new int[201];} class Mod{ Mod(){ data = new byte[100][100][100]; for(int i = 0;i < 100;i ++){ for(int j = 0;j < 100;j ++){ data[i][j][99] = 1; data[i][0][j] = 4; data[i][99][j] = 4; data[0][i][j] = 48; data[99][i][j] = 48; data[i][49][j] = 15; data[49][i][j] = 60; } } for(int i = 1;i < 11;i ++){ for(int j = 0;j < 50;j ++){ data[i][j][5] = 2; data[i][j][25] = 3; data[i+38][j][10] = 13; data[i+38][j][30] = 7; } } for(int i = 0;i < 3;i ++){ for(int j = 0;j < 3;j ++){ data[10+i*3][25+j*3][15] = 63; data[40+i*3][35+j*3][25] = 15; } } for(int i = 0;i < 10;i ++){ for(int j = 0;j < 100;j ++){ data[i+20][49][j] = 3; } } for(int i = 0;i < 9;i ++){ for(int j = 1;j < 99;j ++){ for(int k = 0;k < 7;k ++){ data[j][49][i*10+k+10] = 0; } } } for(int i = 20;i < 50;i ++){ for(int j = 0;j < 2;j ++){ for(int k = 0;k < 8;k ++){ data[j + 10][i][k*10+5] = 53; data[12][i][k*10+5+j] = 58; } } } } public byte getData(int x,int y,int z){ if(x >= 0 && x < 100 && y >= 0 && y < 100 && z >= 100 && z < 200){ return data[x][y][z-100]; } else return (byte)0; } private byte[][][] data;} //////////////////// End //////////////////

评论