2017-01-17 3 views
0

Я пытаюсь создать программу, которая может рисовать 3D-изображения. Я получил свою программу для работы, когда изображения были предварительно установлены в программе, но когда я пытаюсь добавить способ перемещения объекта, изображение не отображается. Я включил главное окно, холст и класс, который на самом деле рисует объекты.Java Canvas Графика, не показывающая

Главное окно:

package Graphics; 

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.WindowConstants; 
import javax.swing.border.EmptyBorder; 

public class Window extends JFrame 
{ 

    public static JPanel contentPane; 
    public static MyCanvas c; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       try 
       { 
        Window frame = new Window(); 
        frame.setVisible(true); 
        frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH); 
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
       } catch (Exception e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    * 
    * @throws Exception 
    */ 
    public Window() throws Exception { 
     setResizable(false); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 450, 300); 
     contentPane = new JPanel(); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     contentPane.setLayout(new BorderLayout(0, 0)); 
     setContentPane(contentPane); 

     c = new MyCanvas(); 

     contentPane.add(c); 

    } 

} 

MyCanvas:

package Graphics; 

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.util.ArrayList; 
import java.util.Arrays; 

import GraphicsEngine.Image3D; 
import GraphicsEngine.Point3D; 
import GraphicsEngine.PolygonC; 
import GraphicsEngine.Transformation3D; 

public class MyCanvas extends Canvas 
{ 

    public void paint(Graphics g) 
    { 

     Image3D cube; 

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

     @SuppressWarnings("unchecked") 
     ArrayList<Integer>[] al = new ArrayList[6]; 

     al[0] = new ArrayList<Integer>(Arrays.asList(0, 2, 6, 4));// "Back" 
                    // blue 
     al[1] = new ArrayList<Integer>(Arrays.asList(0, 1, 5, 4));// "Bottom" 
                    // green 
     al[2] = new ArrayList<Integer>(Arrays.asList(0, 1, 3, 2));// "RS" 
                    // yellow 
     al[3] = new ArrayList<Integer>(Arrays.asList(1, 3, 7, 5));// "Front" 
                    // Grey 
     al[4] = new ArrayList<Integer>(Arrays.asList(2, 3, 7, 6));// "Top" 
                    // red 
     al[5] = new ArrayList<Integer>(Arrays.asList(4, 5, 7, 6));// "LS" 
                    // Pink 

     Color[][] c = new Color[6][2]; 
     c[0][0] = Color.BLUE; 
     c[0][1] = Color.BLUE; 
     c[1][0] = Color.GREEN; 
     c[1][1] = Color.GREEN; 
     c[2][0] = Color.YELLOW; 
     c[2][1] = Color.YELLOW; 
     c[3][0] = Color.GRAY; 
     c[3][1] = Color.GRAY; 
     c[4][0] = Color.RED; 
     c[4][1] = Color.RED; 
     c[5][0] = Color.PINK; 
     c[5][1] = Color.PINK; 

     PolygonC[] poly = new PolygonC[6]; 
     poly[0] = new PolygonC(al[0], c[0]); 
     poly[1] = new PolygonC(al[1], c[1]); 
     poly[2] = new PolygonC(al[2], c[2]); 
     poly[3] = new PolygonC(al[3], c[3]); 
     poly[4] = new PolygonC(al[4], c[4]); 
     poly[5] = new PolygonC(al[5], c[5]); 

     try 
     { 

      cube = new Image3D(cubeArray, poly); 

      Window.c.addKeyListener(new KeyAdapter() 
      { 
       @Override 
       public void keyPressed(KeyEvent e) 
       { 
        try 
        { 
         switch (e.getKeyChar()) 
         { 
         case 'w': 
          Thread t = new Thread(new change(g, Window.c.getWidth(), Window.c.getHeight(), cube, 10d, 0d, 0d, 0d, 0d, 0d)); 
          t.start(); 
         case 's': 

         case 'a': 

         case 'd': 

         case 'q': 

         case 'e': 

         } 
        } catch (Exception e1) 
        { 
         e1.printStackTrace(); 
        } 

       } 
      }); 

     } catch (Exception e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      return; 
     } 
    } 
} 

class change implements Runnable 
{ 

    Image3D  i; 
    int   w; 
    int   h; 
    Graphics g; 

    public change(Graphics g, int w, int h, Image3D i, double x, double y, double z, double dx, double dy, double dz) throws Exception { 
     // TODO Auto-generated method stub 
     this.i = i; 
     this.w = w; 
     this.h = h; 
     this.g = g; 

     Double[][] translateArray = 
     { 
       { 1d, 0d, 0d, dx }, 
       { 0d, 1d, 0d, dy }, 
       { 0d, 0d, 1d, dz }, 
       { 0d, 0d, 0d, 1d } }; 

     Double[][] yRotateArray = 
     { 
       { Math.cos(Math.toRadians(y)), 0d, Math.sin(Math.toRadians(y)), 0d }, 
       { 0d, 1d, 0d, 0d }, 
       { -Math.sin(Math.toRadians(y)), 0d, Math.cos(Math.toRadians(y)), 0d }, 
       { 0d, 0d, 0d, 1d } }; 

     Double[][] xRotateArray = 
     { 
       { 1d, 0d, 0d, 0d }, 
       { 0d, Math.cos(Math.toRadians(x)), -Math.sin(Math.toRadians(x)), 0d }, 
       { 0d, Math.sin(Math.toRadians(x)), Math.cos(Math.toRadians(x)), 0d }, 
       { 0d, 0d, 0d, 1d } }; 

     Double[][] zRotateArray = 
     { 
       { Math.cos(Math.toRadians(z)), Math.sin(Math.toRadians(z)), 0d, 0d }, 
       { -Math.sin(Math.toRadians(z)), Math.cos(Math.toRadians(z)), 0d, 0d }, 
       { 0d, 0d, 1d, 0d }, 
       { 0d, 0d, 0d, 1d } }; 

     Transformation3D translate = new Transformation3D(translateArray); 
     Transformation3D yRotate = new Transformation3D(yRotateArray); 
     Transformation3D xRotate = new Transformation3D(xRotateArray); 
     Transformation3D zRotate = new Transformation3D(zRotateArray); 

     this.i.setTransformation(translate); 
     this.i.addTransformation(xRotate); 
     this.i.addTransformation(yRotate); 
     this.i.addTransformation(zRotate); 

     ; 
    } 

    @Override 
    public void run() 
    { 
     g.clearRect(0, 0, w, h); 
     try 
     { 
      i.draw(g); 
     } catch (Exception e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

FlatImage3D:

package GraphicsEngine; 

import java.awt.Graphics; 
import java.awt.Polygon; 
import java.util.Arrays; 

public class FlatImage3D 
{ 
    public FlatPoint3D[] p; 
    public PolygonC[]  poly; 

    public FlatImage3D(FlatPoint3D[] p, PolygonC[] poly) throws Exception { 
     this.p = p; 
     this.poly = poly; 
    } 

    public void draw(Graphics g) throws Exception 
    { 
     poly = sort(poly); 
     for (int i = 0; i < poly.length; i++) 
     { 
      int[] xCord = new int[poly[i].al.size()]; 
      int[] yCord = new int[poly[i].al.size()]; 
      for (int h = 0; h < poly[i].al.size(); h++) 
      { 
       xCord[h] = p[poly[i].al.get(h)].x; 
       yCord[h] = p[poly[i].al.get(h)].y; 
      } 
      Polygon p = new Polygon(xCord, yCord, poly[i].al.size()); 
      g.setColor(poly[i].c[0]); 
      g.fillPolygon(p); 
      g.setColor(poly[i].c[1]); 
      g.drawPolygon(p); 
     } 
    } 

    private PolygonC[] sort(PolygonC[] poly) 
    { 
     if (poly.length == 1) 
     { 
      return poly; 
     } 

     int fs; 

     if (poly.length % 2 == 0) 
     { 
      fs = poly.length/2; 
     } else 
     { 
      fs = poly.length/2 + 1; 
     } 

     PolygonC[] f = Arrays.copyOfRange(poly, 0, fs); 
     PolygonC[] s = Arrays.copyOfRange(poly, fs, poly.length); 

     f = sort(f); 
     s = sort(s); 

     int fc = 0; 
     int sc = 0; 

     PolygonC[] r = new PolygonC[poly.length]; 
     for (int i = 0; i < poly.length; i++) 
     { 
      if (fc >= f.length) 
      { 
       r[i] = s[sc]; 
       sc++; 
      } else if (sc >= s.length) 
      { 
       r[i] = f[fc]; 
       fc++; 
      } else if (compare(lowestElement(f[fc]), lowestElement(s[sc])) == -1) 
      { 
       r[i] = f[fc]; 
       fc++; 
      } else 
      { 
       r[i] = s[sc]; 
       sc++; 
      } 
     } 
     return r; 
    } 

    private Integer[] lowestElement(PolygonC pc) 
    { 
     Integer[] low = new Integer[pc.al.size()]; 
     for (int i = 0; i < pc.al.size(); i++) 
     { 
      low[i] = p[pc.al.get(i)].z; 
     } 
     Arrays.sort(low); 
     return low; 
    } 

    private static int compare(Integer[] a, Integer[] b) 
    { 
     for (int i = 0; i < Integer.MAX_VALUE; i++) 
     { 
      if (i >= a.length) 
      { 
       return -1; 
      } else if (i >= b.length) 
      { 
       return 1; 
      } else if (a[i] < b[i]) 
      { 
       return -1; 
      } else if (a[i] > b[i]) 
      { 
       return 1; 
      } 
     } 
     return 0; 
    } 
} 
+2

Картина однопоточная. Объект Graphics действителен только для метода paint (или paintComponent), которому он передается. Вы не можете передать объект Graphics в новый поток и ожидать его использования. Также обратите внимание, что вы добавляете дополнительный KeyListener * каждый раз, когда вы нарисовываете Canvas; слушатели должны быть настроены вне любых методов рисования. – VGR

+0

Спасибо за помощь – WIR3D

+0

Если вы используете 'Canvas', то вы должны использовать' BufferedStrategy', мало пользы от использования 'Canvas' в противном случае (' JPanel' по умолчанию буферизуется по умолчанию, где как ' Canvas' is not) – MadProgrammer

ответ

0

Ваша программа должна быть структурирована следующим образом:

public class MyCanvas extends Canvas { 

public MyCanvas() { 

    // all the stuff you have inside paint now, except you dont create a new class 
// everytime you press a button just create once and direct it by some method 

change ch=new change(Window.c.getWidth(), Window.c.getHeight(), cube, 10d, 0d, 0d, 0d, 0d, 0d)); 

// then 
        case 'w': 
         ch.adjustParameters(x, y.......) 
} 

public void paint(Graphics g) 
{ 

    change.draw(g); 

} 

изменения должны быть

class change { 

Image3D  i; 
int   w; 
int   h; 
Graphics g; 

public change(int w, int h, Image3D i, double x, double y, double z, double dx, double dy, double dz) throws Exception { 

что не Runnable.

каждый раз, когда вы что-то меняете ключом, необходимо передать (например, координаты x, y) каким-либо способом, но на данный момент вы можете предположить x = y = 0 и просто выполнить этот прогон.