Как нарисовать изображения на трехмерном вращающемся кубе в 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);
}
}