正文

用Java实现3D模型成像2005-12-16 11:55:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/jywzzz/8340.html

分享到:

        代码如此的短,被我优化过,所以不很容易看懂。有这个想法源于看图形学时看到的直线的画法,当时我想,用这个方法用来画空间投射线也应该很容易。于是就做了这个基于空间投射线的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 //////////////////

阅读(4374) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册