我无法使我的JavaFX太阳系模拟工作。

huangapple go评论59阅读模式
英文:

I can't get my solar system simulation to work in JavaFX

问题

在编译和显示窗口之后,除了黑色背景和偶尔会出现一小部分太阳纹理外,我看到的唯一事物是,我不知道如何修复它,以便显示整个布局,我可以在上面看到地球和太阳。

import javafx.application.Application;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

public class MainApp extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        SolarSystem solarSystem = initSolarSystem();
        SolarSystemSimulation simulation = new SolarSystemSimulation(solarSystem);

        Scene scene = new Scene(simulation, 1200, 900);
        scene.setFill(javafx.scene.paint.Color.BLACK);

        PerspectiveCamera camera = new PerspectiveCamera();
        camera.setTranslateZ(-10000); // 沿Z轴平移相机
        camera.setFarClip(20000); // 渲染对象的距离
        scene.setCamera(camera);

        stage.setScene(scene);
        stage.show();

        simulation.start();

        // 为太阳设置更大的半径
        CelestialBody sun = solarSystem.getBodies().get(0);
        sun.setRadius(1000);
    }

    // 省略其他代码
}
// 其他类的内容不变

你应该至少能看到太阳和地球围绕太阳运动。

英文:

After compiling and displaying the window, the only thing I can see besides a black background and every now and then a piece of the sun texture, and I don't know how to fix it so that it displays the whole layout and I can see both the earth and the sun on it

import javafx.application.Application;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

public class MainApp extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        SolarSystem solarSystem = initSolarSystem();
        SolarSystemSimulation simulation = new SolarSystemSimulation(solarSystem);

        Scene scene = new Scene(simulation, 1200, 900);
        scene.setFill(javafx.scene.paint.Color.BLACK);

        PerspectiveCamera camera = new PerspectiveCamera();
        camera.setTranslateZ(-10000); // Przesunięcie kamery wzdłuż osi Z
        camera.setFarClip(20000); // Odległość renderowania obiektów
        scene.setCamera(camera);

        stage.setScene(scene);
        stage.show();

        simulation.start();

        // Ustawienie większego promienia dla słońca
        CelestialBody sun = solarSystem.getBodies().get(0);
        sun.setRadius(1000);
    }

    private SolarSystem initSolarSystem() {
        SolarSystem solarSystem = new SolarSystem();

        // Tutaj tworzymy ciała niebieskie i dodajemy je do układu słonecznego
        // Wszystkie tekstury powinny być zlokalizowane w folderze resources projektu
        CelestialBody sun = new CelestialBody("Sun", 1.989 * Math.pow(10, 30), 696340, new Vector3D(0, 0, 0), new Vector3D(0, 0, 0), "sun.jpg");
        solarSystem.addBody(sun);

        CelestialBody earth = new CelestialBody("Earth", 5.972 * Math.pow(10, 24), 6371, new Vector3D(147.1 * Math.pow(10, 6), 0, 0), new Vector3D(0, 0, 0), "earth.jpg");
        solarSystem.addBody(earth);

        // ... dodajemy resztę ciał niebieskich, dla których mamy tekstury

        return solarSystem;
    }

    public static void main(String[] args) {
        launch(args);
    }
}
public class CelestialBody {
    private String name;
    private double mass;
    private double radius;
    private Vector3D position;
    private Vector3D velocity;
    private String textureFilename;

    public CelestialBody(String name, double mass, double radius, Vector3D position, Vector3D velocity, String textureFilename) {
        this.name = name;
        this.mass = mass;
        this.radius = radius;
        this.position = position;
        this.velocity = velocity;
        this.textureFilename = textureFilename;
    }

    public String getName() {
        return name;
    }

    public double getMass() {
        return mass;
    }

    public double getRadius() {
        return radius;
    }

    public Vector3D getPosition() {
        return position;
    }

    public Vector3D getVelocity() {
        return velocity;
    }

    public void setVelocity(Vector3D velocity) {
        this.velocity = velocity;
    }

    public void setPosition(Vector3D position) {
        this.position = position;
    }
    public String getTextureFilename() {
        return textureFilename;
    }
    public void setRadius(double radius) {
        this.radius = radius;
    }
}
import java.util.ArrayList;
import java.util.List;

public class SolarSystem {
    private List<CelestialBody> bodies;

    public SolarSystem() {
        bodies = new ArrayList<>();
    }

    public void addBody(CelestialBody body) {
        bodies.add(body);
    }

    public List<CelestialBody> getBodies() {
        return bodies;
    }
}

import javafx.animation.AnimationTimer;
import javafx.scene.Group;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Sphere;
import java.io.InputStream;
import javafx.scene.image.Image;
import java.util.Map;
import java.util.HashMap;

public class SolarSystemSimulation extends Group {
    private SolarSystem solarSystem;
    private Map<CelestialBody, Sphere> spheres;

    public SolarSystemSimulation(SolarSystem solarSystem) {
        this.solarSystem = solarSystem;
        this.spheres = new HashMap<>();

        for (CelestialBody body : solarSystem.getBodies()) {
            Sphere sphere = new Sphere(body.getRadius());
            PhongMaterial material = new PhongMaterial();
            Image texture = loadImage(body.getTextureFilename());
            if (texture != null) {
                material.setDiffuseMap(texture);
            }
            sphere.setMaterial(material);
            spheres.put(body, sphere);
            getChildren().add(sphere);
        }

        // Wypisanie promieni sfer
        for (CelestialBody body : solarSystem.getBodies()) {
            Sphere sphere = spheres.get(body);
            System.out.println("Promień " + body.getName() + ": " + sphere.getRadius());
        }
    }

    public void setRadius(CelestialBody body, double radius) {
        Sphere sphere = spheres.get(body);
        if (sphere != null) {
            sphere.setRadius(radius);
        }
    }

    private Image loadImage(String filename) {
        InputStream inputStream = getClass().getResourceAsStream("/" + filename);
        return new Image(inputStream);
    }

    public void updatePositions(double deltaTime) {
        for (CelestialBody body : solarSystem.getBodies()) {
            Vector3D currentPosition = body.getPosition();
            Vector3D velocity = body.getVelocity();
            Vector3D newPosition = currentPosition.add(velocity.scale(deltaTime));
            body.setPosition(newPosition);
        }
    }

    public void start() {
        new AnimationTimer() {
            private long previousTime = 0;

            @Override
            public void handle(long now) {
                if (previousTime == 0) {
                    previousTime = now;
                    return;
                }

                // Obliczamy różnicę czasu w sekundach
                double deltaTime = (now - previousTime) / 1_000_000_000.0;
                previousTime = now;

                // Wyliczamy nowe pozycje dla ciał niebieskich
                for (CelestialBody body : solarSystem.getBodies()) {
                    // Obliczamy nową prędkość na podstawie sił grawitacyjnych
                    Vector3D acceleration = calculateGravitationalAcceleration(body);
                    body.setVelocity(body.getVelocity().add(acceleration.scale(deltaTime)));

                    // Aktualizujemy pozycję na podstawie prędkości
                    Vector3D newPosition = body.getPosition().add(body.getVelocity().scale(deltaTime));
                    body.setPosition(newPosition);

                    // Aktualizujemy pozycję sfery na scenie
                    Sphere sphere = spheres.get(body);
                    sphere.setTranslateX(body.getPosition().getX());
                    sphere.setTranslateY(body.getPosition().getY());
                    sphere.setTranslateZ(body.getPosition().getZ());
                }
                // Oddalanie kamery
                getChildren().forEach(child -> {
                    if (child instanceof Sphere) {
                        Sphere sphere = (Sphere) child;
                        sphere.setTranslateZ(sphere.getTranslateZ() - 0.5);
                    }
                });
            }
        }.start();
    }

    private Vector3D calculateGravitationalAcceleration(CelestialBody body) {
        Vector3D acceleration = new Vector3D(0, 0, 0);
        for (CelestialBody otherBody : solarSystem.getBodies()) {
            if (body != otherBody) {
                // Obliczamy wektor odległości między ciałami
                Vector3D distance = otherBody.getPosition().subtract(body.getPosition());

                // Obliczamy siłę grawitacyjną między ciałami
                double gravitationalForce = calculateGravitationalForce(body, otherBody, distance.magnitude());

                // Obliczamy wektor przyspieszenia na podstawie siły i odległości
                Vector3D bodyAcceleration = distance.scale(gravitationalForce / body.getMass());

                // Dodajemy przyspieszenie od innego ciała do ogólnego przyspieszenia
                acceleration = acceleration.add(bodyAcceleration);
            }
        }
        return acceleration;
    }

    private double calculateGravitationalForce(CelestialBody body1, CelestialBody body2, double distance) {
        final double gravitationalConstant = 6.67430e-11;
        return gravitationalConstant * (body1.getMass() * body2.getMass()) / (distance * distance);
    }
}

public class Vector3D {
    private double x;
    private double y;
    private double z;

    public Vector3D(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    public double getZ() {
        return z;
    }

    // Dodaje wektor do obecnego wektora
    public Vector3D add(Vector3D other) {
        return new Vector3D(this.x + other.x, this.y + other.y, this.z + other.z);
    }

    // Odejmuje wektor od obecnego wektora
    public Vector3D subtract(Vector3D other) {
        return new Vector3D(this.x - other.x, this.y - other.y, this.z - other.z);
    }

    // Mnoży wektor przez skalar
    public Vector3D scale(double factor) {
        return new Vector3D(this.x * factor, this.y * factor, this.z * factor);
    }

    // Oblicza długość (magnitude) wektora
    public double magnitude() {
        return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
    }
}

I should at least see sun and earth orbiting around sun

答案1

得分: 2

scene 对象没有深度缓冲:

Scene scene = new Scene(simulation, 1200, 900);

为了启用深度缓冲,您可以使用以下构造函数之一:

Scene(Parent root, double width, double height, boolean depthBuffer, SceneAntialiasing antiAliasing)

或者:

Scene(Parent root, double width, double height, boolean depthBuffer)

例如:

Scene scene = new Scene(simulation, 1200, 900, true, SceneAntialiasing.BALANCED);
英文:

your scene object does not have depthBuffer :

Scene scene = new Scene(simulation, 1200, 900);

in order to eneble depthBuffer you can use either this constructor

Scene(Parent root, double width, double height, boolean depthBuffer, SceneAntialiasing antiAliasing)

or this

Scene(Parent root, double width, double height, boolean depthBuffer)

E.g :

Scene scene = new Scene(simulation, 1200, 900,true,SceneAntialiasing.BALANCED);

huangapple
  • 本文由 发表于 2023年6月30日 04:12:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76584334.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定