Guest User

Untitled

a guest
Oct 18th, 2023
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.27 KB | None | 0 0
  1. package org.example.type;
  2.  
  3. import com.googlecode.lanterna.*;
  4. import com.googlecode.lanterna.TextColor.RGB;
  5. import com.googlecode.lanterna.screen.*;
  6. import com.googlecode.lanterna.terminal.*;
  7.  
  8. import java.io.IOException;
  9. import java.util.*;
  10. import lombok.AllArgsConstructor;
  11. import lombok.Value;
  12.  
  13. public class QuasarSimulation {
  14.  
  15.   private Screen screen;
  16.   private final List<Point> quasarPoints = new ArrayList<>();
  17.   private double[][] depthBuffer;
  18.  
  19.   public static void main(String[] args) throws IOException, InterruptedException {
  20.     new QuasarSimulation().drawQuasar();
  21.   }
  22.  
  23.   public void drawQuasar() throws IOException, InterruptedException {
  24.     screen = new TerminalScreen(
  25.         new DefaultTerminalFactory().setInitialTerminalSize(new TerminalSize(80, 30))
  26.             .createTerminal());
  27.     screen.startScreen();
  28.     depthBuffer = new double[screen.getTerminalSize().getColumns()][screen.getTerminalSize()
  29.         .getRows()];
  30.  
  31.     initializeQuasarPoints();
  32.     int centerX = screen.getTerminalSize().getColumns() / 2;
  33.     int centerY = screen.getTerminalSize().getRows() / 2;
  34.     double rotationAngle = Math.toRadians(-0.1);
  35.  
  36.     while (true) {
  37.       for (double[] row : depthBuffer) {
  38.         Arrays.fill(row, Double.MAX_VALUE);
  39.       }
  40.       screen.clear();
  41.       quasarPoints.replaceAll(p -> rotate(p, rotationAngle, centerX, centerY));
  42.       drawDisk();
  43.       screen.refresh();
  44.       Thread.sleep(25);
  45.     }
  46.   }
  47.  
  48.   private void initializeQuasarPoints() {
  49.     int centerX = screen.getTerminalSize().getColumns() / 2;
  50.     int centerY = screen.getTerminalSize().getRows() / 2;
  51.     Random random = new Random();
  52.  
  53.     quasarPoints.add(new Point(centerX, centerY, 0));
  54.  
  55.     for (int arm = 0; arm < 4; arm++) {
  56.       for (double theta = 0; theta < 4 * Math.PI; theta += 0.01) {
  57.         double r = 0.1 * Math.exp(0.5 * theta);
  58.         double x = centerX + (r * Math.cos(theta + arm * Math.PI / 2));
  59.         double y = centerY + (r * Math.sin(theta + arm * Math.PI / 2));
  60.         int z = random.nextInt(6) - 3;
  61.         quasarPoints.add(new Point(x, y, z));
  62.         for (int i = 0; i < random.nextInt(2); i++) {
  63.           quasarPoints.add(new Point(x + random.nextInt(12) - 6, y + random.nextInt(12) - 6, z));
  64.         }
  65.       }
  66.     }
  67.  
  68.     for (int i = 1; i <= 200; i++) {
  69.       double r = i * 0.05;
  70.       int z = i / 2;
  71.       for (double angle = 0; angle < 2 * Math.PI; angle += 0.1) {
  72.         int x = centerX + (int) (r * Math.cos(angle));
  73.         int y = centerY + (int) (r * Math.sin(angle));
  74.         TextCharacter ch = new TextCharacter('*', TextColor.Factory.fromString("#FFFFFF"),
  75.             TextColor.ANSI.BLACK);
  76.         quasarPoints.addAll(Arrays.asList(new Point(x, y, z, Optional.of(ch)),
  77.             new Point(x, y, -z, Optional.of(ch))));
  78.       }
  79.     }
  80.   }
  81.  
  82.   double i = 0;
  83.  
  84.   private void drawDisk() {
  85.     int centerX = screen.getTerminalSize().getColumns() / 2;
  86.     int centerY = screen.getTerminalSize().getRows() / 2;
  87.     int depth = 100;
  88.  
  89.     double viewAngleX = Math.toRadians(-50 + (i += 0.3));
  90.     double viewAngleY = Math.toRadians(4);
  91.  
  92.     for (Point point : quasarPoints) {
  93.       Point adjustedPoint = applyViewingAngle(point, viewAngleX, viewAngleY, centerX, centerY);
  94.       double projectedX =
  95.           (depth * (adjustedPoint.getX() - centerX)) / (adjustedPoint.getZ() + depth) + centerX;
  96.       double projectedY =
  97.           (depth * (adjustedPoint.getY() - centerY)) / (adjustedPoint.getZ() + depth) + centerY;
  98.  
  99.       TextCharacter textCharacter = adjustedPoint.getCharacter()
  100.           .orElseGet(() -> getQuasarCharacter(point, centerX, centerY));
  101.       int intX = (int) projectedX;
  102.       int intY = (int) projectedY;
  103.  
  104.       if (intX >= 0 && intX < depthBuffer.length && intY >= 0 && intY < depthBuffer[intX].length
  105.           && point.getZ() < depthBuffer[intX][intY]) {
  106.         depthBuffer[intX][intY] = point.getZ();
  107.         screen.setCharacter(intX, intY, textCharacter);
  108.       }
  109.     }
  110.   }
  111.  
  112.  
  113.   private Point applyViewingAngle(Point point, double angleX, double angleY, int centerX,
  114.       int centerY) {
  115.     // Translate to the origin
  116.     double translatedX = point.getX() - centerX;
  117.     double translatedY = point.getY() - centerY;
  118.     double z = point.getZ();
  119.  
  120.     // Apply rotation around X-axis
  121.     double adjustedY = translatedY * Math.cos(angleX) - z * Math.sin(angleX);
  122.     double adjustedZ = translatedY * Math.sin(angleX) + z * Math.cos(angleX);
  123.  
  124.     // Apply rotation around Y-axis
  125.     double adjustedX = translatedX * Math.cos(angleY) + adjustedZ * Math.sin(angleY);
  126.     adjustedZ = -translatedX * Math.sin(angleY) + adjustedZ * Math.cos(angleY);
  127.  
  128.     // Translate back
  129.     adjustedX += centerX;
  130.     adjustedY += centerY;
  131.  
  132.     return new Point(adjustedX, adjustedY, adjustedZ, point.getCharacter());
  133.   }
  134.  
  135.   private Point rotate(Point point, double angle, int centerX, int centerY) {
  136.     double x =
  137.         (point.getX() - centerX) * Math.cos(angle) - (point.getY() - centerY) * Math.sin(angle)
  138.             + centerX;
  139.     double y =
  140.         (point.getX() - centerX) * Math.sin(angle) + (point.getY() - centerY) * Math.cos(angle)
  141.             + centerY;
  142.  
  143.     return new Point(x, y, point.getZ(), point.getCharacter());
  144.   }
  145.  
  146.   // Linear interpolation function
  147.   private TextColor lerpColor(String startColor, String endColor, double t) {
  148.     TextColor start = TextColor.Factory.fromString(startColor);
  149.     TextColor end = TextColor.Factory.fromString(endColor);
  150.  
  151.     int r = (int) (start.getRed() + t * (end.getRed() - start.getRed()));
  152.     int g = (int) (start.getGreen() + t * (end.getGreen() - start.getGreen()));
  153.     int b = (int) (start.getBlue() + t * (end.getBlue() - start.getBlue()));
  154.  
  155.     return new RGB(r, g, b);
  156.   }
  157.  
  158.   private TextCharacter getQuasarCharacter(Point point, int centerX, int centerY) {
  159.     int distance = (int) point.distance(centerX, centerY, 0);
  160.     TextColor color;
  161.  
  162.     if (distance < 5) {
  163.       color = lerpColor("#FFFFFF", "#87CEFA",
  164.           distance / 5.0);  // Interpolating between white and sky blue based on distance
  165.       return new TextCharacter('o', color,
  166.           TextColor.ANSI.BLACK); // Using '@' for denser core representation
  167.     } else if (distance < 10) {
  168.       color = lerpColor("#87CEFA", "#1E90FF",
  169.           (distance - 5) / 5.0);  // Interpolating between sky blue and deep blue
  170.       return new TextCharacter('*', color,
  171.           TextColor.ANSI.BLACK); // Using 'o' for intermediate representation
  172.     } else if (distance < 15) {
  173.       color = lerpColor("#1E90FF", "#00008B",
  174.           (distance - 10) / 5.0);  // Interpolating between deep blue and dark blue
  175.       return new TextCharacter('+', color,
  176.           TextColor.ANSI.BLACK); // Using '*' for outer representation
  177.     } else {
  178.       return new TextCharacter('.', TextColor.Factory.fromString("#00008B"),
  179.           TextColor.ANSI.BLACK);  // Dark blue for distant points
  180.     }
  181.   }
  182.  
  183.  
  184.   @Value
  185.   @AllArgsConstructor
  186.   public class Point {
  187.     double x;
  188.     double y;
  189.     double z;
  190.     Optional<TextCharacter> character;
  191.  
  192.     public Point(double x, double y, double z) {
  193.       this(x, y, z, Optional.empty());
  194.     }
  195.  
  196.     public double distance(int x, int y, int z) {
  197.       return Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.y - y, 2) + Math.pow(this.z - z, 2));
  198.     }
  199.   }
  200. }
  201.  
Advertisement
Add Comment
Please, Sign In to add comment