简体   繁体   English

如何用像素绘制3D对象?

[英]How to paint 3D object from pixels?

I have problem with my program. 我的程序有问题。 I have ascii file with columns "theta y radius" ~ 180 000 lines. 我有ascii文件,其列为“ theta y radius”〜180 000行。 I can calculate from that: x,y,z records. 我可以从中计算出:x,y,z记录。 I try to paint it in 3D space, next I want to combine the pixels and result should be project which I can rotate with my mouse. 我尝试在3D空间中对其进行绘制,接下来我要合并像素,结果应该是可以用鼠标旋转的项目。 I should use only java.awt. 我应该只使用java.awt。

I have something like that: 我有这样的事情:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;

class Point3D {
   public int x, y, z;
   public Point3D( int X, int Y, int Z ) {
      x = X;  y = Y;  z = Z;
   }
}

class Edge {
   public int a, b;
   public Edge( int A, int B ) {
      a = A;  b = B;
   }
}

public class WireframeViewer extends Applet
   implements MouseListener, MouseMotionListener {

   int width, height;
   int mx, my;  // the most recently recorded mouse coordinates

   Image backbuffer;
   Graphics backg;

   int azimuth = 35, elevation = 30;

   Point3D[] vertices;
   Edge[] edges;

   public void init() {
      width = getSize().width;
      height = getSize().height;

      vertices = new Point3D[ 8 ];
      vertices[0] = new Point3D( -1, -1, -1 );
      vertices[1] = new Point3D( -1, -1,  1 );
      vertices[2] = new Point3D( -1,  1, -1 );
      vertices[3] = new Point3D( -1,  1,  1 );
      vertices[4] = new Point3D(  1, -1, -1 );
      vertices[5] = new Point3D(  1, -1,  1 );
      vertices[6] = new Point3D(  1,  1, -1 );
      vertices[7] = new Point3D(  1,  1,  1 );

      edges = new Edge[ 12 ];
      edges[ 0] = new Edge( 0, 1 );
      edges[ 1] = new Edge( 0, 2 );
      edges[ 2] = new Edge( 0, 4 );
      edges[ 3] = new Edge( 1, 3 );
      edges[ 4] = new Edge( 1, 5 );
      edges[ 5] = new Edge( 2, 3 );
      edges[ 6] = new Edge( 2, 6 );
      edges[ 7] = new Edge( 3, 7 );
      edges[ 8] = new Edge( 4, 5 );
      edges[ 9] = new Edge( 4, 6 );
      edges[10] = new Edge( 5, 7 );
      edges[11] = new Edge( 6, 7 );

      backbuffer = createImage( width, height );
      backg = backbuffer.getGraphics();
      drawWireframe( backg );

      addMouseListener( this );
      addMouseMotionListener( this );
   }

   void drawWireframe( Graphics g ) {

      // compute coefficients for the projection
      double theta = Math.PI * azimuth / 180.0;
      double phi = Math.PI * elevation / 180.0;
      float cosT = (float)Math.cos( theta ), sinT = (float)Math.sin( theta );
      float cosP = (float)Math.cos( phi ), sinP = (float)Math.sin( phi );
      float cosTcosP = cosT*cosP, cosTsinP = cosT*sinP,
             sinTcosP = sinT*cosP, sinTsinP = sinT*sinP;

      // project vertices onto the 2D viewport
      Point[] points;
      points = new Point[ vertices.length ];
      int j;
      int scaleFactor = width/4;
      float near = 3;  // distance from eye to near plane
      float nearToObj = 1.5f;  // distance from near plane to center of object
      for ( j = 0; j < vertices.length; ++j ) {
         int x0 = vertices[j].x;
         int y0 = vertices[j].y;
         int z0 = vertices[j].z;

         // compute an orthographic projection
         float x1 = cosT*x0 + sinT*z0;
         float y1 = -sinTsinP*x0 + cosP*y0 + cosTsinP*z0;

         // now adjust things to get a perspective projection
         float z1 = cosTcosP*z0 - sinTcosP*x0 - sinP*y0;
         x1 = x1*near/(z1+near+nearToObj);
         y1 = y1*near/(z1+near+nearToObj);

         // the 0.5 is to round off when converting to int
         points[j] = new Point(
            (int)(width/2 + scaleFactor*x1 + 0.5),
            (int)(height/2 - scaleFactor*y1 + 0.5)
         );
      }

      // draw the wireframe
      g.setColor( Color.black );
      g.fillRect( 0, 0, width, height );
      g.setColor( Color.white );
      for ( j = 0; j < edges.length; ++j ) {
         g.drawLine(
            points[ edges[j].a ].x, points[ edges[j].a ].y,
            points[ edges[j].b ].x, points[ edges[j].b ].y
         );
      }
   }

   public void mouseEntered( MouseEvent e ) { }
   public void mouseExited( MouseEvent e ) { }
   public void mouseClicked( MouseEvent e ) { }
   public void mousePressed( MouseEvent e ) {
      mx = e.getX();
      my = e.getY();
      e.consume();
   }
   public void mouseReleased( MouseEvent e ) { }
   public void mouseMoved( MouseEvent e ) { }
   public void mouseDragged( MouseEvent e ) {
      // get the latest mouse position
      int new_mx = e.getX();
      int new_my = e.getY();

      // adjust angles according to the distance travelled by the mouse
      // since the last event
      azimuth -= new_mx - mx;
      elevation += new_my - my;

      // update the backbuffer
      drawWireframe( backg );

      // update our data
      mx = new_mx;
      my = new_my;

      repaint();
      e.consume();
   }

   public void update( Graphics g ) {
      g.drawImage( backbuffer, 0, 0, this );
      showStatus("Elev: "+elevation+" deg, Azim: "+azimuth+" deg");
   }

   public void paint( Graphics g ) {
      update( g );
   }
}

That aplet is okay but it's showing square - I want that there should be object from my pixels. 那个aplet还可以,但显示为正方形-我希望像素中应该有物体。

I can calculate > 160 00 vertices and when I'm painting it in 2D I can see a man head. 我可以计算> 160 00个顶点,当我用2D绘制它时,我可以看到一个人头。 The problem is, what I can do with edges? 问题是,边缘该怎么办?

Any suggestions? 有什么建议么?

Change... 更改...

public void update( Graphics g ) {
   g.drawImage( backbuffer, 0, 0, this );
   showStatus("Elev: "+elevation+" deg, Azim: "+azimuth+" deg");
}

public void paint( Graphics g ) {
   update( g );
}

to... 至...

@Override
public void paint(Graphics g) {
    super.paint(g);
    g.drawImage(backbuffer, 0, 0, this);
    showStatus("Elev: " + elevation + " deg, Azim: " + azimuth + " deg");
}

And it produces... 它产生...

Cude

update actually calls paint , so you're kind of screwing with the way painting works. update实际上称为paint ,因此您有点迷恋绘画的工作方式。

This is not something you will want to do solely in java.awt . 这不是您将只想在java.awt完成的事情。 There is a lot involved with rendering 3D using only pixels. 仅使用像素渲染3D涉及很多工作。

You'll have to compute all of the mathematics for converting 3D space to 2D, account for rotation/translation/scaling and account for shading (if required). 您必须计算所有将3D空间转换为2D的数学运算,旋转/平移/缩放和阴影处理(如果需要)。

Are you able to use OpenGL to solve your issue? 您可以使用OpenGL解决问题吗?

Java even has bindings for OpenGL (see Java OpenGL) that allow you to render 3D graphics on an AWT window. Java甚至具有OpenGL绑定(请参阅Java OpenGL) ,使您可以在AWT窗口上渲染3D图形。

If you absolutely must implement your own software rendering pipeline, you'll need to start by learning about projection matrices and modelview matrices. 如果您绝对必须实现自己的软件渲染管道,则需要从了解投影矩阵和Modelview矩阵开始。 Then you will need to implement your own version of a vertex shader and fragment shader (or something of the sort). 然后,您将需要实现自己的顶点着色器和片段着色器(或类似类型)的版本。

I found this article which may be helpful in the mathematics: http://www.songho.ca/opengl/gl_projectionmatrix.html 我发现这篇文章可能对数学有帮助: http : //www.songho.ca/opengl/gl_projectionmatrix.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM