From 2b6f2932c748070c9df8c65e11cb458e95839bf4 Mon Sep 17 00:00:00 2001 From: James Ball Date: Wed, 5 Feb 2020 23:47:27 +0000 Subject: [PATCH] Added shape interface to clean up code and added ellipse class --- src/audio/AudioClient.java | 8 ++-- src/audio/AudioPlayer.java | 78 +++++++++++++++++++------------------- src/graphs/Graph.java | 4 +- src/shapes/Ellipse.java | 57 ++++++++++++++++++++++++++++ src/shapes/Line.java | 23 ++++++++++- src/shapes/Shape.java | 11 ++++++ src/shapes/Shapes.java | 18 ++++----- 7 files changed, 143 insertions(+), 56 deletions(-) create mode 100644 src/shapes/Ellipse.java create mode 100644 src/shapes/Shape.java diff --git a/src/audio/AudioClient.java b/src/audio/AudioClient.java index 4947ee4..bfe9930 100644 --- a/src/audio/AudioClient.java +++ b/src/audio/AudioClient.java @@ -1,5 +1,6 @@ package audio; +import shapes.Ellipse; import shapes.Shapes; import shapes.Vector; @@ -12,10 +13,11 @@ public class AudioClient { AudioPlayer player = new AudioPlayer(); AudioPlayer.FORMAT = AudioPlayer.defaultFormat(SAMPLE_RATE); - AudioPlayer.addLines(Shapes.generatePolygon(100, 0.5, 60)); - AudioPlayer.addLines(Shapes.generatePolygram(5, 3, 0.5, 60)); + AudioPlayer.addShapes(Shapes.generatePolygon(100, 0.5, 60)); + AudioPlayer.addShapes(Shapes.generatePolygram(5, 3, 0.5, 60)); + AudioPlayer.addShape(new Ellipse(0.5, 0.5)); - AudioPlayer.setRotateSpeed(0.8); + AudioPlayer.setRotateSpeed(-0.8); AudioPlayer.setTranslation(4, new Vector(1, 1)); AudioPlayer.setScale(0.5); diff --git a/src/audio/AudioPlayer.java b/src/audio/AudioPlayer.java index 026dd3c..29eb3cb 100644 --- a/src/audio/AudioPlayer.java +++ b/src/audio/AudioPlayer.java @@ -1,21 +1,23 @@ package audio; import com.xtaudio.xt.*; +import shapes.Ellipse; import shapes.Line; +import shapes.Shape; import shapes.Vector; import java.util.ArrayList; import java.util.List; public class AudioPlayer extends Thread { - public static XtFormat FORMAT; private static volatile boolean stopped = false; - private static List lines = new ArrayList<>(); - private static int currentLine = 0; + private static List shapes = new ArrayList<>(); + private static int currentShape = 0; private static int framesDrawn = 0; private static double[] phases = new double[2]; + public static XtFormat FORMAT; private static double TRANSLATE_SPEED = 0; private static Vector TRANSLATE_VECTOR; private static final int TRANSLATE_PHASE_INDEX = 0; @@ -28,81 +30,77 @@ public class AudioPlayer extends Thread { XtFormat format = stream.getFormat(); for (int f = 0; f < frames; f++) { - Line line = currentLine(); + Shape shape = currentShape(); - line = scale(line); - line = rotate(line, stream.getFormat().mix.rate); - line = translate(line, stream.getFormat().mix.rate); + shape = scale(shape); + shape = rotate(shape, stream.getFormat().mix.rate); + shape = translate(shape, stream.getFormat().mix.rate); - int framesToDraw = (int) (line.length * line.getWeight()); + double framesToDraw = shape.getLength() * shape.getWeight(); + double drawingProgress = framesDrawn / framesToDraw; for (int c = 0; c < format.outputs; c++) { - ((float[]) output)[f * format.outputs] = nextX(line, framesToDraw); - ((float[]) output)[f * format.outputs + 1] = nextY(line, framesToDraw); + ((float[]) output)[f * format.outputs] = shape.nextX(drawingProgress); + ((float[]) output)[f * format.outputs + 1] = shape.nextY(drawingProgress); } framesDrawn++; if (framesDrawn > framesToDraw) { framesDrawn = 0; - currentLine++; + currentShape++; } } } - static float nextTheta(double sampleRate, double frequency, int phaseIndex) { + static double nextTheta(double sampleRate, double frequency, int phaseIndex) { phases[phaseIndex] += frequency / sampleRate; - if (phases[phaseIndex] >= 1.0) + + if (phases[phaseIndex] >= 1.0) { phases[phaseIndex] = -1.0; - return (float) (phases[phaseIndex] * Math.PI); - } - - private static float nextX(Line line, double framesToDraw) { - return (float) (line.getX1() + (line.getX2() - line.getX1()) * framesDrawn / framesToDraw); - } - - private static float nextY(Line line, double framesToDraw) { - return (float) (line.getY1() + (line.getY2() - line.getY1()) * framesDrawn / framesToDraw); - } - - private static Line scale(Line line) { - if (SCALE != 1) { - return line.scale(SCALE); } - return line; + return phases[phaseIndex] * Math.PI; } - private static Line rotate(Line line, double sampleRate) { + private static Shape scale(Shape shape) { + if (SCALE != 1) { + return shape.scale(SCALE); + } + + return shape; + } + + private static Shape rotate(Shape shape, double sampleRate) { if (ROTATE_SPEED != 0) { - line = line.rotate( + shape = shape.rotate( nextTheta(sampleRate, ROTATE_SPEED, TRANSLATE_PHASE_INDEX) ); } - return line; + return shape; } - private static Line translate(Line line, double sampleRate) { + private static Shape translate(Shape shape, double sampleRate) { if (TRANSLATE_SPEED != 0 && !TRANSLATE_VECTOR.equals(new Vector())) { - return line.translate(TRANSLATE_VECTOR.scale( + return shape.translate(TRANSLATE_VECTOR.scale( Math.sin(nextTheta(sampleRate, TRANSLATE_SPEED, ROTATE_PHASE_INDEX)) )); } - return line; + return shape; } - public static void addLine(Line line) { - AudioPlayer.lines.add(line); + public static void addShape(Shape shape) { + AudioPlayer.shapes.add(shape); } - public static void addLines(List lines) { - AudioPlayer.lines.addAll(lines); + public static void addShapes(List shapes) { + AudioPlayer.shapes.addAll(shapes); } - private static Line currentLine() { - return lines.get(currentLine % lines.size()); + private static Shape currentShape() { + return shapes.get(currentShape % shapes.size()); } public static void setRotateSpeed(double speed) { diff --git a/src/graphs/Graph.java b/src/graphs/Graph.java index b375a57..49c2789 100644 --- a/src/graphs/Graph.java +++ b/src/graphs/Graph.java @@ -27,8 +27,8 @@ public class Graph { Node nodeA = nodes.get(line.getA()); Node nodeB = nodes.get(line.getB()); - nodeA.addAdjacent(nodeB, line.length); - nodeB.addAdjacent(nodeA, line.length); + nodeA.addAdjacent(nodeB, line.getLength()); + nodeB.addAdjacent(nodeA, line.getLength()); } } } diff --git a/src/shapes/Ellipse.java b/src/shapes/Ellipse.java new file mode 100644 index 0000000..05fa152 --- /dev/null +++ b/src/shapes/Ellipse.java @@ -0,0 +1,57 @@ +package shapes; + +public class Ellipse implements Shape { + private final double a; + private final double b; + private final double weight; + private final double length; + + public Ellipse(double a, double b, double weight) { + this.a = a; + this.b = b; + this.weight = weight; + // Approximation of length. + this.length = 2 * Math.PI * Math.sqrt((this.a * this.a + this.b * this.b) / 2); + } + + public Ellipse(double a, double b) { + this(a, b, 100); + } + + @Override + public float nextX(double drawingProgress) { + return (float) (a * Math.sin(2 * Math.PI * drawingProgress)); + } + + @Override + public float nextY(double drawingProgress) { + return (float) (b * Math.cos(2 * Math.PI * drawingProgress)); + } + + // TODO: Implement ellipse rotation. + @Override + public Shape rotate(double theta) { + return this; + } + + @Override + public Shape scale(double factor) { + return new Ellipse(a * factor, b * factor, weight); + } + + // TODO: Implement ellipse translation. + @Override + public Shape translate(Vector vector) { + return this; + } + + @Override + public double getWeight() { + return weight; + } + + @Override + public double getLength() { + return length; + } +} diff --git a/src/shapes/Line.java b/src/shapes/Line.java index ea75273..4d977b8 100644 --- a/src/shapes/Line.java +++ b/src/shapes/Line.java @@ -1,12 +1,12 @@ package shapes; -public class Line { +public class Line implements Shape { private final Vector a; private final Vector b; private final double weight; // Storing the length to save on repeat calculations. - public final double length; + private final double length; public static final double DEFAULT_WEIGHT = 100; @@ -33,14 +33,17 @@ public class Line { return Math.sqrt(Math.pow(getX1() - getX2(), 2) + Math.pow(getY1() - getY2(), 2)); } + @Override public Line rotate(double theta) { return new Line(getA().rotate(theta), getB().rotate(theta), getWeight()); } + @Override public Line translate(Vector vector) { return new Line(getA().add(vector), getB().add(vector)); } + @Override public Line scale(double factor) { return new Line(getA().scale(factor), getB().scale(factor)); } @@ -49,6 +52,16 @@ public class Line { return new Line(getA().copy(), getB().copy(), getWeight()); } + @Override + public float nextX(double drawingProgress) { + return (float) (getX1() + (getX2() - getX1()) * drawingProgress); + } + + @Override + public float nextY(double drawingProgress) { + return (float) (getY1() + (getY2() - getY1()) * drawingProgress); + } + public Vector getA() { return a; } @@ -89,10 +102,16 @@ public class Line { return new Line(getX1(), getY1(), getX2(), y2); } + @Override public double getWeight() { return weight; } + @Override + public double getLength() { + return length; + } + public Line setWeight(double weight) { return new Line(getX1(), getY1(), getX2(), getY2(), weight); } diff --git a/src/shapes/Shape.java b/src/shapes/Shape.java new file mode 100644 index 0000000..e73f352 --- /dev/null +++ b/src/shapes/Shape.java @@ -0,0 +1,11 @@ +package shapes; + +public interface Shape { + float nextX(double drawingProgress); + float nextY(double drawingProgress); + Shape rotate(double theta); + Shape scale(double factor); + Shape translate(Vector vector); + double getWeight(); + double getLength(); +} diff --git a/src/shapes/Shapes.java b/src/shapes/Shapes.java index 87917bf..2fa7ebf 100644 --- a/src/shapes/Shapes.java +++ b/src/shapes/Shapes.java @@ -4,8 +4,8 @@ import java.util.ArrayList; import java.util.List; public class Shapes { - public static List generatePolygram(int sides, int angleJump, Vector start, double weight) { - List polygon = new ArrayList<>(); + public static List generatePolygram(int sides, int angleJump, Vector start, double weight) { + List polygon = new ArrayList<>(); double theta = angleJump * 2 * Math.PI / sides; @@ -22,31 +22,31 @@ public class Shapes { return polygon; } - public static List generatePolygram(int sides, int angleJump, Vector start) { + public static List generatePolygram(int sides, int angleJump, Vector start) { return generatePolygram(sides, angleJump, start, Line.DEFAULT_WEIGHT); } - public static List generatePolygram(int sides, int angleJump, double scale, double weight) { + public static List generatePolygram(int sides, int angleJump, double scale, double weight) { return generatePolygram(sides, angleJump, new Vector(scale, scale), weight); } - public static List generatePolygram(int sides, int angleJump, double scale) { + public static List generatePolygram(int sides, int angleJump, double scale) { return generatePolygram(sides, angleJump, new Vector(scale, scale)); } - public static List generatePolygon(int sides, Vector start, double weight) { + public static List generatePolygon(int sides, Vector start, double weight) { return generatePolygram(sides, 1, start, weight); } - public static List generatePolygon(int sides, Vector start) { + public static List generatePolygon(int sides, Vector start) { return generatePolygram(sides, 1, start); } - public static List generatePolygon(int sides, double scale, double weight) { + public static List generatePolygon(int sides, double scale, double weight) { return generatePolygon(sides, new Vector(scale, scale), weight); } - public static List generatePolygon(int sides, double scale) { + public static List generatePolygon(int sides, double scale) { return generatePolygon(sides, new Vector(scale, scale)); }