Как нарисовать изображения на трехмерном вращающемся кубе в java swing

Я пытаюсь создать программу, которая рисует 3d-куб с изображениями, нарисованными поверх него. Используя другие посты здесь, я создал вращающийся 3d куб. Часть, с которой у меня возникают проблемы, - это изгибание и деформация изображения, чтобы оно соответствовало поверхности куба. Я попытался перерисовать пиксели одного изображения на другое изображение с различными порядками и уравнениями, но я не могу понять, как это сделать. По сути, я спрашиваю, как деформировать изображение, чтобы оно выглядело как трехмерный куб в Java swing, без чего-либо похожего на Java 3D API.

Спасибо.

Вот что у меня уже есть.

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.io.*;

import javax.imageio.*;
import javax.swing.*;

public class Component extends Applet implements Runnable {
    private static final long serialVersionUID = 1L;

    public static boolean isRunning = false;

    public static int pixelSize = 1;

    public static Dimension size = new Dimension(800, 600);
    public static Dimension pixel = new Dimension((int) size.getWidth() / pixelSize, (int) size.getHeight() / pixelSize);

    //setting screen
    public static Image screen;

    //setting cube
    public static Cube cube;

    public static BufferedImage img;

    public Component() {
        setPreferredSize(size);
    }

    public void init() {
        screen = createVolatileImage((int) pixel.getWidth(), (int) pixel.getHeight());

        //setting img
        try {
            img = ImageIO.read(new File("img.png"));
        } catch(Exception e) { }
    }

    public void start() {
        isRunning = true;

        new Thread(this).start();
    }

    public void stop() {
        isRunning = false;
    }

    //doubles used to rotate cube
    double a = 0, b = 0;;
    public void tick() {

        a+=0.01;
        b-=0.02;
        //initalizing and rotating cube
        cube = new Cube(150, Component.pixel.width / 2, Component.pixel.height / 2, (double)a/5, (double)b/5, (double)a/5);
    }

    public void render() {
        Graphics g = screen.getGraphics();

        g.setColor(Color.white);
        g.fillRect(0, 0, (int) size.getWidth(), (int) size.getHeight());

        cube.render(g);

        g.dispose();
        g = getGraphics();

        g.drawImage(screen, 0, 0, (int) size.getWidth(), (int) size.getHeight(), null);

        g.dispose();
    }

    public void run() {
        while(isRunning) {
            tick();
            render();

            try {
                Thread.sleep(5);
            } catch(Exception e) { }
        }
    }

    public static void main(String args[]) {
        Component component = new Component();

        JFrame frame = new JFrame();
        frame.add(component);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("3D Game");
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        component.init();
        component.start();
    }


}

Тогда класс куба:

 import java.awt.*;

public class Cube {

    private double vertex[][][][] =
        {
            {
                {
                    { -1, -1, -1 },
                    {  1, -1, -1 }
                },
                {
                    { -1,  1, -1 },
                    {  1,  1, -1 }
                }
            },
            {
                {
                    { -1, -1, 1 },
                    {  1, -1, 1 }
                },
                {
                    { -1,  1,  1 },
                    {  1,  1,  1 }
                }
            }
        };

    //rotations
    double xyR = 0.005, xzR = 0.005, yzR = 0.005; 
    int scale, offsetX, offsetY;

    public Cube(int size, int offX, int offY, double xyR, double xzR, double yzR) {
        this.scale = size;
        this.offsetX = offX;
        this.offsetY = offY;
        this.xyR = xyR;
        this.xzR = xzR;
        this.yzR = yzR;

        //rotating cube
        for(int x = 0; x < 2; x++) {
            for(int y = 0; y < 2; y++) {
                for(int z = 0; z < 2; z++) {
                    xyRotate(vertex[x][y][z], Math.sin(xyR), Math.cos(xyR));
                    xzRotate(vertex[x][y][z], Math.sin(xzR), Math.cos(xzR));
                    yzRotate(vertex[x][y][z], Math.sin(yzR), Math.cos(yzR));
                }
            }
        }
    }

    public void tick() {

    }

    public void render(Graphics g) {
        //draw cube edges
        for(int x = 0; x < 2; x++) {
            for(int y = 0; y < 2; y++) {
                //rotating cube
                g.setColor(Color.red);
                drawEdge(vertex[x][y][0][0], vertex[x][y][0][1], vertex[x][y][1][0], vertex[x][y][1][1], g);
                g.setColor(Color.blue);
                drawEdge(vertex[x][0][y][0], vertex[x][0][y][1], vertex[x][1][y][0], vertex[x][1][y][1], g);
                g.setColor(Color.green);
                drawEdge(vertex[0][x][y][0], vertex[0][x][y][1], vertex[1][x][y][0], vertex[1][x][y][1], g);
            }
        }
    }

    //apply plane rotation to 3D point, only 2 coordinates are affected
    public void xyRotate(double p[], double sin, double cos) {
        double temp;
        temp =  cos*p[0] + sin*p[1];
        p[1] = -sin*p[0] + cos*p[1];
        p[0] = temp;
    }

    public void xzRotate(double p[], double sin, double cos) {
        double temp;
        temp =  cos*p[0] + sin*p[2];
        p[2] = -sin*p[0] + cos*p[2];
        p[0] = temp;
    }

    public void yzRotate(double p[], double sin, double cos) {
        double temp;
        temp =  cos*p[1] + sin*p[2];
        p[2] = -sin*p[1] + cos*p[2];
        p[1] = temp;
    }

    //drawing lines
    public void drawEdge(double x1, double y1, double x2, double y2, Graphics g) {
        g.drawLine((int) (x1 * scale) + offsetX, (int) (-y1 * scale) + offsetY, (int) (x2 * scale) + offsetX, (int) (-y2 * scale) + offsetY);
    }
}

0 ответов

Другие вопросы по тегам