First commit, aggregated repos

This commit is contained in:
2025-10-05 22:53:40 -04:00
commit fd496edee5
14 changed files with 467800 additions and 0 deletions

158
Orbital-Bodies/Matrix.java Normal file
View File

@@ -0,0 +1,158 @@
/**
* A simple m x n matrix class.
*
* TODO All of the methods currently just return default values. You need to make them match the Javadoc comments.
*
* @author YOUR NAME HERE
* @version Sept. 2017
*/
public class Matrix {
private int m, n;
private double[][] M;
public Matrix(double[][] array) {
M = array;
m = array.length;
n = array[0].length;
}
/**
* @return The number of columns in the matrix.
*/
public int nCols() { return n; }
/**
* @return the number of rows.
*/
public int nRows() { return m; }
/**
* @param i
* @param j
* @return The entry at row i column j.
*/
public double entry(int i, int j) {
return M[i][j];
}
/**
* Computes the dot product of this matrix with the parameter that. (Return value is this . that)
* Recall that the dot product is the typical matrix multiplication.
* @param that The matrix to apply this matrix to.
* @throws BadDimensionException If this.nCols() != that.nRows() because the dot product is not defined
* @return The dot product of this matrix with that.
*/
public Matrix dot(Matrix that) throws UndefinedMatrixOpException {
if (this.nCols() != that.nRows()) {
throw new UndefinedMatrixOpException("Dot product not defined", this, that);
}
double[][] result = new double[this.nRows()][that.nCols()];
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
double entry = 0;
for (int k = 0; k < this.nCols(); k++) {
entry += this.entry(i, k) * that.entry(k, j);
}
result[i][j] = entry;
}
}
return new Matrix(result);
}
/**
* Add this matrix to that and returns the result. (Return value is this + that)
* @param that the matrix to add this matrix to.
* @throws BadDimensionException If the dimension of the two matrices are not identical.
* @return The sum of the this and that.
*/
public Matrix plus(Matrix that) throws UndefinedMatrixOpException {
if (this.nRows() != that.nRows() || this.nCols() != this.nRows()) {
throw new UndefinedMatrixOpException("Matrix dimensions are not identical", this, that);
}
double[][] result = new double[this.nRows()][this.nCols()];
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
result[i][j] = this.entry(i, j) + that.entry(i, j);
}
}
return new Matrix(result);
}
/**
* @param theta The rotation angle.
* @return The homogeneous rotation matrix for a given value for theta.
*/
public static Matrix rotationH2D(double theta) {
double[][] R = {{Math.cos(theta), -Math.sin(theta), 0}, {Math.sin(theta), Math.cos(theta), 0}, {0, 0, 1}};
return new Matrix(R);
}
/**
* @param tx The amount to translate in the x direction.
* @param ty The amount to translate in the y direction.
* @return The matrix representing a translation of tx, ty.
*/
public static Matrix translationH2D(double tx, double ty) {
double[][] T = {{1, 0, tx}, {0, 1, ty}, {0, 0, 1}};
return new Matrix(T);
}
/**
* @param x The x coordinate
* @param y The y coordinate
* @return The column matrix representing in homogeneous coordinates the point (x, y).
*/
public static Matrix vectorH2D(double x, double y) {
double[][] V = {{x}, {y}, {1}};
return new Matrix(V);
}
/**
* @param n The dimension of the matrix. Recall that the identity matrix has 1's for any entry that is in the same row index as its column index, 0's everywhere else.
* @return the nxn identity matrix
*/
public static Matrix identity(int n) {
return identity(n, n);
}
/**
* Computes the mxn identity matrix which has 1's for every entry at the same row and column index and
* 0 for all other entries.
* @param m
* @param n
* @return the mxn identity matrix.
*/
public static Matrix identity(int m, int n) {
double[][] result = new double[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
result[i][j] = (i == j) ? 1 : 0;
}
}
return new Matrix(result);
}
/**
* A little helpful toString() in case you want to print your matrix to System.out
*/
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
sb.append(M[i][j]);
sb.append('\t');
}
sb.append('\n');
}
return sb.toString();
}
}

141
Orbital-Bodies/Orbit.pde Normal file
View File

@@ -0,0 +1,141 @@
import java.util.*;
import java.awt.*;
Orbiter sun; // The root orbiter
int lastMillis;
double[][] originM = {{0},{0},{1}};
Matrix origin = new Matrix(originM);
// A few fun parameters
boolean clearBackground = true;
double speedModifier = 1.0; // Set in some of the scenes to change the speed.
// One default scene (selected in the setup() function
void setupScene1() {
sun = new Orbiter(null, 0, 0, 0, Orbiter.Type.CIRCLE, Color.yellow);
Orbiter earth = new Orbiter(sun, 50, 0, 1, Orbiter.Type.CIRCLE, Color.blue);
Orbiter moon = new Orbiter(earth, 30, 0, 1, Orbiter.Type.CIRCLE, Color.gray);
Orbiter moonSatellite = new Orbiter(moon, 20, 0, 1, Orbiter.Type.CIRCLE, Color.gray);
Orbiter jupiter = new Orbiter(sun, 200, 0, 0.5, Orbiter.Type.CIRCLE, Color.red);
Orbiter jupiterMoon = new Orbiter(jupiter, 75, 0, 2, Orbiter.Type.CIRCLE, Color.green);
Orbiter jupiterExplorer = new Orbiter(jupiterMoon, 40, 0, -1, Orbiter.Type.SQUARE, Color.orange);
Orbiter jupiterExplorerRobot = new Orbiter(jupiterExplorer, 20, 0, -3, Orbiter.Type.TRIANGLE, Color.magenta);
}
// A second default scene
void setupScene2() {
speedModifier = 0.25;
sun = new Orbiter(null, 0, 0, 0, Orbiter.Type.TRIANGLE, Color.yellow);
Orbiter earth = new Orbiter(sun, 50, 0, 10, Orbiter.Type.TRIANGLE, Color.blue);
Orbiter moon = new Orbiter(earth, 30, 0, 20, Orbiter.Type.TRIANGLE, Color.gray);
Orbiter moonSatellite = new Orbiter(moon, 20, 0, 30, Orbiter.Type.TRIANGLE, Color.gray);
Orbiter jupiter = new Orbiter(sun, 200, 0, 5, Orbiter.Type.TRIANGLE, Color.red);
Orbiter jupiterMoon = new Orbiter(jupiter, 75, 0, 2, Orbiter.Type.TRIANGLE, Color.green);
Orbiter jupiterExplorer = new Orbiter(jupiterMoon, 40, 0, 8, Orbiter.Type.TRIANGLE, Color.orange);
Orbiter jupiterExplorerRobot = new Orbiter(jupiterExplorer, 20, 0, -6, Orbiter.Type.TRIANGLE, Color.magenta);
}
// The setup. You don't need to edit this other than to switch scenes by commenting out
// the setupScene1() and uncommenting setupScene2().
void setup() {
size(800, 800);
background(0);
setupScene1();
//setupScene2(); // Run this one with clearBackground set to false
lastMillis = millis();
}
// The draw function
// DO NOT EDIT
void draw() {
if (clearBackground) background(0); // Make the background black.
int currentMillis = millis(); // Get the current number of milliseconds
int elapsedMillis = currentMillis - lastMillis; // Get the number of milliseconds elapsed since last call
double timeDelta = elapsedMillis / 1000.0;
updateOrbiters(timeDelta * speedModifier);
pushMatrix();
scale(1, -1);
translate(width / 2, - height / 2);
drawOrbiters();
popMatrix();
lastMillis = currentMillis;
}
void updateOrbiters(double timeDelta) {
Queue<Orbiter> queue = new LinkedList<Orbiter>();
queue.add(sun);
while (!queue.isEmpty()) {
Orbiter node = queue.remove();
node.updateRotation(timeDelta);
queue.addAll(node.getChildren());
}
// TODO
// This code should traverse the orbiters (in BFS or DFS, but I used BFS)
// order using a stack or a queue (your choice), and call updateRotation
// on each one using the timeDelta parameter.
//
// Recall that Java has a Queue<T> data type and a Stack<T> interface
}
void drawOrbiters() {
Queue<Orbiter> queue = new LinkedList<Orbiter>();
queue.add(sun);
while (!queue.isEmpty()) {
Orbiter node = queue.remove();
drawOrbiter(node);
queue.addAll(node.getChildren());
}
// TODO
// This code should traverse the orbiters (in BFS or DFS order, i used BFS)
// and call drawOrbiter on each orbiter.
}
// The code for drawing an orbiter. This is called from your drawOrbiters() method
// but you should not have to edit it.
void drawOrbiter(Orbiter orbiter) {
try {
Matrix position = orbiter.getMatrix().dot(origin);
int px = (int) Math.round(position.entry(0,0) / position.entry(2,0));
int py = (int) Math.round(position.entry(1,0) / position.entry(2,0));
// Draw the orbiter
noStroke();
fill(orbiter.getFillColor().getRed(), orbiter.getFillColor().getGreen(), orbiter.getFillColor().getBlue());
switch (orbiter.getType()) {
case CIRCLE:
ellipse(px, py, 16, 16);
break;
case SQUARE:
rect(px-4, py-4, 8, 8);
break;
case TRIANGLE:
triangle(px, py+3, px-2, py-1, px+2, py-1);
break;
}
noFill();
// Draw the orbit path
if (clearBackground) {
stroke(60);
for (Orbiter child : orbiter.getChildren()) {
int radius = (int) (2*child.getOrbitRadius());
ellipse(px, py, radius, radius);
}
}
} catch (UndefinedMatrixOpException umoe) {
}
}

View File

@@ -0,0 +1,69 @@
import java.awt.Color;
import java.util.*;
/**
* An Orbiter is an object that orbits some other object, called its parent.
* The center of an orbital system is an Orbiter with no parent.
* Each Orbiter may have child Oribters that orbit it.
*
* An Orbiter stores its orbital radius and current orbit angle.
*/
public class Orbiter {
public enum Type {
CIRCLE, SQUARE, TRIANGLE
}
private final double orbitRadius;
private final Type type;
private final Color fillColor;
private double orbitAngle;
private double orbitSpeed;
private final List<Orbiter> children = new LinkedList<Orbiter>();
private final Orbiter parent;
public Orbiter(Orbiter parent, double orbitRadius, double orbitAngle, double orbitSpeed, Type type, Color fillColor) {
this.orbitRadius = orbitRadius;
this.orbitAngle = orbitAngle;
this.type = type;
this.fillColor = fillColor;
this.parent = parent;
this.orbitSpeed = orbitSpeed;
if (parent != null) parent.children.add(this);
}
public double getOrbitRadius() { return orbitRadius; }
public double getOrbitAngle() { return orbitAngle; }
public Color getFillColor() { return fillColor; }
public Type getType() { return type; }
public Orbiter getParent() { return parent; }
public List<Orbiter> getChildren() { return children; }
/**
* Updates the rotation of this orbiter by the amount specified in the deltaAngle parameter.
* @param deltaAngle The amount of rotation angle to add the to the current rotation.
*/
public void updateRotation(double timeDelta) {
orbitAngle += (timeDelta * orbitSpeed);
}
public Matrix getMatrix() throws UndefinedMatrixOpException {
if (parent == null) {
return Matrix.identity(3);
}
Matrix local = Matrix.rotationH2D(orbitAngle).dot(Matrix.translationH2D(orbitRadius, 0));
return this.parent.getMatrix().dot(local);
// TODO
// If this is the root node, then return the 3x3 identity matrix
// If this is not the root node, should return the transformation
// matrix for this orbiter (see the writeup for an idea of how to
// do this). Make sure you've coded the Matrix class first.
}
}

View File

@@ -0,0 +1,14 @@
/**
* Thrown when a matrix oepration is applied to matrices of the wrong size.
*
* You don't need to edit this.
*/
public class UndefinedMatrixOpException extends Exception {
public UndefinedMatrixOpException(String message, Matrix m1, Matrix m2) {
super(message + "\nMatrix 1: " + m1 + "\n\nMatrix 2: " + m2);
}
}