You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Java中不使用OpenGL绘制立方体的问题求助

Hey there! Let's walk through fixing your Java cube drawing code step by step. The main issues stem from Java's strict type system, differences in how data structures work compared to Lua, and some syntax/typo errors. Here's how to get it working:

Key Issues & Fixes

  1. Use Proper Point Classes Instead of Arrays
    In Lua, you can use tables with named fields like x, y, z, but Java arrays don't support that. Create simple Point3D and Point2D classes to hold coordinates—this will eliminate the "can't find x/y/z" errors.

  2. Fix Math Function Typos
    Math.coz is a typo; it should be Math.cos. Also, use double for angle calculations since Math.sin/Math.cos return doubles, avoiding integer precision issues.

  3. Correct List/Array Usage
    Your parameter types (like ArrayList points[]) are incorrect. Use generic lists (List<Point3D>) to store points, and iterate over them properly with for loops instead of while loops with index decrements.

  4. Pass Graphics Context to Cube's Paint Method
    Your Cube.paint() method needs access to the Graphics object from the JPanel to draw lines. Pass it as a parameter when calling the method.

  5. Fix Point Initialization
    You were calling Make3dPoint but not adding the returned points to your pointsArray. Initialize the list properly and add each cube vertex to it.

  6. Adjust Rotation Math & Coordinate Transformation
    Correct the rotation logic to use proper 3D rotation formulas, and ensure the perspective scaling uses floating-point division to avoid distorted results.

Corrected Code

Main Class

package Main;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
import javax.swing.JFrame;

public class Main extends JPanel {
    public static void main(String[] args) {
        int width = 800;
        int height = 600;
        String title = "3D Cube";
        
        JFrame display = new JFrame(title);
        display.setSize(width, height);
        display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        display.setContentPane(new Main());
        display.setVisible(true);
    }

    public Main() {
        setBackground(Color.black);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // Always call this first to clear the panel
        Cube cube = new Cube();
        cube.paint(g); // Pass the Graphics object to the cube's paint method
    }
}

Cube Class

package Main;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;

public class Cube {
    private static class Point3D {
        double x, y, z;
        Point3D(double x, double y, double z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    }

    private static class Point2D {
        int x, y;
        Point2D(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    private final int focalLength = 300;
    private final List<Point3D> pointsArray;
    private Point3D cubeAxisRotation;
    private final double userX = -0.01;
    private final double userY = 0.01;

    public Cube() {
        // Initialize cube vertices (8 points in 3D space)
        pointsArray = new ArrayList<>();
        pointsArray.add(new Point3D(-50, -50, -50));
        pointsArray.add(new Point3D(50, -50, -50));
        pointsArray.add(new Point3D(50, -50, 50));
        pointsArray.add(new Point3D(-50, -50, 50));
        pointsArray.add(new Point3D(-50, 50, -50));
        pointsArray.add(new Point3D(50, 50, -50));
        pointsArray.add(new Point3D(50, 50, 50));
        pointsArray.add(new Point3D(-50, 50, 50));

        cubeAxisRotation = new Point3D(0, 0, 0);
    }

    private Point2D make2dPoint(double x, double y) {
        // Offset to center the cube in the window
        return new Point2D((int) x + 400, (int) y + 300);
    }

    private List<Point2D> trans3dTo2d(List<Point3D> points, Point3D rotations) {
        List<Point2D> transformedPoints = new ArrayList<>();
        
        double cx = Math.cos(rotations.x);
        double sx = Math.sin(rotations.x);
        double cy = Math.cos(rotations.y);
        double sy = Math.sin(rotations.y);
        double cz = Math.cos(rotations.z);
        double sz = Math.sin(rotations.z);

        for (Point3D p : points) {
            double x = p.x;
            double y = p.y;
            double z = p.z;

            // Rotate around X axis
            double rotatedY = cx * y - sx * z;
            double rotatedZ = sx * y + cx * z;

            // Rotate around Y axis
            double rotatedX = cy * x + sy * rotatedZ;
            rotatedZ = -sy * x + cy * rotatedZ;

            // Rotate around Z axis
            double finalX = cz * rotatedX - sz * rotatedY;
            double finalY = sz * rotatedX + cz * rotatedY;

            // Apply perspective projection
            double scaleRatio = focalLength / (focalLength + rotatedZ);
            int screenX = (int) (finalX * scaleRatio);
            int screenY = (int) (finalY * scaleRatio);

            transformedPoints.add(make2dPoint(screenX, screenY));
        }

        return transformedPoints;
    }

    public void paint(Graphics g) {
        // Update rotation angles
        cubeAxisRotation.x += userX;
        cubeAxisRotation.y += userY;

        List<Point2D> sp = trans3dTo2d(pointsArray, cubeAxisRotation);

        // Draw bottom face (green)
        g.setColor(Color.green);
        drawLine(g, sp.get(0), sp.get(1));
        drawLine(g, sp.get(1), sp.get(2));
        drawLine(g, sp.get(2), sp.get(3));
        drawLine(g, sp.get(3), sp.get(0));

        // Draw top face (red)
        g.setColor(Color.red);
        drawLine(g, sp.get(4), sp.get(5));
        drawLine(g, sp.get(5), sp.get(6));
        drawLine(g, sp.get(6), sp.get(7));
        drawLine(g, sp.get(7), sp.get(4));

        // Draw front/back vertical lines (white)
        g.setColor(Color.white);
        drawLine(g, sp.get(0), sp.get(4));
        drawLine(g, sp.get(1), sp.get(5));

        // Draw left/right vertical lines (blue)
        g.setColor(Color.blue);
        drawLine(g, sp.get(2), sp.get(6));
        drawLine(g, sp.get(3), sp.get(7));
    }

    private void drawLine(Graphics g, Point2D p1, Point2D p2) {
        g.drawLine(p1.x, p1.y, p2.x, p2.y);
    }
}

Explanation of Changes

  • Point Classes: Point3D and Point2D make it easy to access coordinates with .x, .y, .z.
  • Rotation Math: Corrected the rotation order and formulas to properly apply X, Y, Z rotations.
  • Perspective Scaling: Used double for calculations to avoid integer division errors.
  • List Initialization: Properly added all 8 cube vertices to pointsArray.
  • Graphics Context: Passed the Graphics object from the JPanel to the Cube's paint method so it can draw lines.
  • 0-Indexing: Java lists are 0-indexed, so adjusted all line drawing to use get(0) instead of sp[1].

This code should display a rotating 3D cube in a black window. Run the Main class, and you'll see the cube spinning smoothly!

内容的提问来源于stack exchange,提问作者Benzaboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:58:25