Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import javafx.application.Application;
- import javafx.scene.Scene;
- import javafx.stage.Stage;
- import javafx.scene.layout.StackPane;
- import javafx.scene.canvas.*;
- import javafx.scene.paint.Color;
- import javafx.animation.*;
- import javafx.util.Duration;
- import javafx.geometry.Point2D;
- import javafx.scene.input.KeyCode;
- import java.util.*;
- public class SolarSystem extends Application{
- private static final int WIDTH = 1000;
- private static final int HEIGHT = 800;
- private static final double SCALE = 200 / 1.50e11;
- private static final double TIMESTEP = 3600*24; // 1 Day
- private static final double G = 6.6743e-11;
- private static class Planet{
- private double x, y;
- private double xVelocity, yVelocity;
- private double mass, radius;
- private Color color;
- private List<Point2D> orbit = new ArrayList<>();
- private boolean signChanged = false, renderOrbit = true;
- public Planet(Color color, double radius, double mass, double x, double y, double xVelocity, double yVelocity){
- this.color = color;
- this.radius = radius;
- this.mass = mass;
- this.x = x;
- this.y = y;
- this.xVelocity = xVelocity;
- this.yVelocity = yVelocity;
- }
- private Point2D getAttractionForce(Planet planet){
- double distanceX = planet.x-this.x;
- double distanceY = planet.y-this.y;
- double distance = Math.sqrt(Math.pow(distanceX, 2)+Math.pow(distanceY, 2));
- double force = SolarSystem.G*this.mass*planet.mass/Math.pow(distance, 2);
- double angle = Math.atan2(distanceY, distanceX);
- double forceX = force * Math.cos(angle);
- double forceY = force * Math.sin(angle);
- /*
- Distance moon-sun: 1.504E11
- Sun force for moon: 4.313523549126089E20
- Distance moon-earth: 4.0E8
- Earth force for moon: 1.831019119125E20
- */
- /*if (this == MOON && planet == SUN){
- System.out.println("Distance moon-sun: "+distance);
- System.out.println("Sun force for moon: "+force);
- } else if (this == MOON && planet == EARTH){
- System.out.println("Distance moon-earth: "+distance);
- System.out.println("Earth force for moon: "+force);
- }*/
- return new Point2D(forceX, forceY);
- }
- public void updatePosition(List<Planet> planets){
- double totalForceX = 0;
- double totalForceY = 0;
- for (Planet planet : planets){
- if (planet == this) continue;
- Point2D force = getAttractionForce(planet);
- totalForceX += force.getX();
- totalForceY += force.getY();
- }
- double temp = this.xVelocity;
- this.xVelocity += totalForceX/this.mass*TIMESTEP;
- this.yVelocity += totalForceY/this.mass*TIMESTEP;
- if (temp*this.xVelocity < 0){ // The sign changed
- this.signChanged = !this.signChanged;
- if (!this.signChanged){
- this.renderOrbit = false;
- }
- }
- this.x += this.xVelocity*TIMESTEP;
- this.y += this.yVelocity*TIMESTEP;
- }
- public void render(GraphicsContext gc){
- final double x = this.x*SolarSystem.SCALE+WIDTH/2;
- final double y = this.y*SolarSystem.SCALE+HEIGHT/2;
- if (this.renderOrbit){
- this.orbit.add(new Point2D(x, y));
- }
- gc.setFill(this.color);
- final double radius = this.radius; // TODO
- gc.fillOval(x-radius, y-radius, radius*2, radius*2);
- }
- public void renderOrbit(GraphicsContext gc){
- gc.setStroke(Color.WHITE);
- gc.setLineWidth(2);
- for (int i = 0; i < this.orbit.size()-1; i++){
- gc.strokeLine(this.orbit.get(i).getX(), this.orbit.get(i).getY(), this.orbit.get(i+1).getX(), this.orbit.get(i+1).getY());
- }
- }
- }
- private List<Planet> planets = new ArrayList<>();
- private Map<KeyCode, Boolean> keys = new HashMap<>();
- private static int WATCHING_PLANET = 0;
- private static Planet MOON, EARTH, SUN;
- @Override
- public void start(Stage stage){
- Canvas canvas = new Canvas(WIDTH, HEIGHT);
- GraphicsContext gc = canvas.getGraphicsContext2D();
- StackPane pane = new StackPane(canvas);
- canvas.setFocusTraversable(true);
- canvas.setOnKeyPressed(e -> this.keys.put(e.getCode(), true));
- canvas.setOnKeyReleased(e -> this.keys.put(e.getCode(), false));
- reset();
- Timeline loop = new Timeline(new KeyFrame(Duration.millis(1000.0/40), e -> {
- for (Planet planet : planets){
- planet.updatePosition(planets);
- }
- update(gc);
- }));
- loop.setCycleCount(Animation.INDEFINITE);
- loop.play();
- Scene scene = new Scene(pane, WIDTH, HEIGHT);
- stage.setScene(scene);
- stage.setTitle("Solar system");
- stage.setResizable(false);
- stage.show();
- }
- private void reset(){
- planets.clear();
- Planet sun = new Planet(Color.YELLOW, 16, 1.989e30, 0, 0, 0, 0);
- Planet earth = new Planet(Color.CYAN, 8, 5.972e24, -1.50e11, 0, 0, 2.97e4);
- Planet moon = new Planet(Color.GRAY, 4, 7.35e22, -(1.50e11+4e8), 0, 0, 1022);
- Planet mercury = new Planet(Color.ORANGE, 6, 3.30e23, -6.982e10, 0, 0, 4.736e4);
- Planet mars = new Planet(Color.RED, 5, 6.41e23, -2.49e11, 0, 0, 2.407e4);
- Planet venus = new Planet(Color.LIME, 4, 4.86e24, -1.08e11, 0, 0, 3.502e4);
- planets.add(sun);
- planets.add(earth);
- planets.add(moon);
- //planets.add(mercury);
- //planets.add(mars);
- //planets.add(venus);
- MOON = moon;
- EARTH = earth;
- SUN = sun;
- }
- private void update(GraphicsContext gc){
- gc.clearRect(0, 0, WIDTH, HEIGHT);
- gc.setFill(Color.BLACK);
- gc.fillRect(0, 0, WIDTH, HEIGHT);
- if (this.keys.getOrDefault(KeyCode.ESCAPE, false)){
- System.exit(0);
- } else if (this.keys.getOrDefault(KeyCode.R, false)){
- reset();
- this.keys.put(KeyCode.R, false);
- }
- // DEBUG
- if (this.keys.getOrDefault(KeyCode.DIGIT0, false)){
- WATCHING_PLANET = 0;
- this.keys.put(KeyCode.DIGIT0, false);
- } else if (this.keys.getOrDefault(KeyCode.DIGIT1, false)){
- WATCHING_PLANET = 1;
- this.keys.put(KeyCode.DIGIT1, false);
- } else if (this.keys.getOrDefault(KeyCode.DIGIT2, false)){
- WATCHING_PLANET = 2;
- this.keys.put(KeyCode.DIGIT2, false);
- } else if (this.keys.getOrDefault(KeyCode.DIGIT3, false)){
- WATCHING_PLANET = 3;
- this.keys.put(KeyCode.DIGIT3, false);
- } else if (this.keys.getOrDefault(KeyCode.DIGIT4, false)){
- WATCHING_PLANET = 4;
- this.keys.put(KeyCode.DIGIT4, false);
- } else if (this.keys.getOrDefault(KeyCode.DIGIT5, false)){
- WATCHING_PLANET = 5;
- this.keys.put(KeyCode.DIGIT5, false);
- }
- for (Planet planet : planets){
- planet.renderOrbit(gc);
- planet.render(gc);
- }
- gc.setFill(Color.WHITE);
- gc.fillText(String.format("x: %.3f y: %.3f\nxVel: %.3f\nyVel: %.3f\nTarget: %d", planets.get(WATCHING_PLANET).x, planets.get(WATCHING_PLANET).y, planets.get(WATCHING_PLANET).xVelocity, planets.get(WATCHING_PLANET).yVelocity, WATCHING_PLANET), 50, 50);
- }
- public static void main(String[] args){
- launch(args);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement