Add shape normalising function for correct rendering on oscilloscope

pull/35/head
James Ball 2020-11-05 21:03:48 +00:00
rodzic cd2d1925b1
commit ef63e47b94
3 zmienionych plików z 42 dodań i 17 usunięć

Wyświetl plik

@ -8,6 +8,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import parser.SvgParser;
import shapes.Shape;
import shapes.Shapes;
import shapes.Vector2;
@ -32,7 +35,8 @@ public class AudioClient {
//
// example:
// osci-render models/cube.obj 3
public static void main(String[] programArgs) throws IOException {
public static void main(String[] programArgs)
throws IOException, ParserConfigurationException, SAXException {
// TODO: Calculate weight of lines using depth.
// Reduce weight of lines drawn multiple times.
// Find intersections of lines to (possibly) improve line cleanup.
@ -53,7 +57,10 @@ public class AudioClient {
Vector3 rotation = new Vector3(0, OBJ_ROTATE_SPEED, OBJ_ROTATE_SPEED);
System.out.println("Begin pre-render...");
List<List<? extends Shape>> frames = preRender(object, rotation, camera);
//List<List<? extends Shape>> frames = preRender(object, rotation, camera);
List<List<? extends Shape>> frames = new ArrayList<>();
List<Shape> frame = Shapes.normalizeShapes(new SvgParser("test/images/sine-wave.svg").getShapes());
frames.add(frame);
System.out.println("Finish pre-render");
System.out.println("Connecting to audio player");
AudioPlayer player = new AudioPlayer(SAMPLE_RATE, frames, ROTATE_SPEED, TRANSLATION_SPEED,

Wyświetl plik

@ -210,22 +210,13 @@ public class SvgParser extends FileParser {
return shapes;
}
private Vector2 scaledArguments(float arg1, float arg2) {
return new Vector2(arg1, arg2);
// return new Vector2(arg1, arg2)
// .scale(new Vector2((width / viewBoxWidth) / viewBoxWidth,
// -(height / viewBoxHeight) / viewBoxHeight)
// ).translate(new Vector2(-0.5, 0.5))
// .scale(2);
}
// Parses moveto commands (M and m commands)
private List<? extends Shape> parseMoveTo(List<Float> args, boolean isAbsolute) {
if (args.size() % 2 != 0 || args.size() < 2) {
throw new IllegalArgumentException("SVG moveto command has incorrect number of arguments.");
}
Vector2 vec = scaledArguments(args.get(0), args.get(1));
Vector2 vec = new Vector2(args.get(0), args.get(1));
if (isAbsolute) {
currPoint = vec;
@ -273,9 +264,9 @@ public class SvgParser extends FileParser {
Vector2 newPoint;
if (expectedArgs == 1) {
newPoint = scaledArguments(args.get(i), args.get(i));
newPoint = new Vector2(args.get(i), args.get(i));
} else {
newPoint = scaledArguments(args.get(i), args.get(i + 1));
newPoint = new Vector2(args.get(i), args.get(i + 1));
}
if (isHorizontal && !isVertical) {
@ -326,14 +317,14 @@ public class SvgParser extends FileParser {
: prevQuadraticControlPoint.reflectRelativeToVector(currPoint);
}
} else {
controlPoint1 = scaledArguments(args.get(i), args.get(i + 1));
controlPoint1 = new Vector2(args.get(i), args.get(i + 1));
}
if (isCubic) {
controlPoint2 = scaledArguments(args.get(i + 2), args.get(i + 3));
controlPoint2 = new Vector2(args.get(i + 2), args.get(i + 3));
}
Vector2 newPoint = scaledArguments(args.get(i + expectedArgs - 2),
Vector2 newPoint = new Vector2(args.get(i + expectedArgs - 2),
args.get(i + expectedArgs - 1));
if (!isAbsolute) {

Wyświetl plik

@ -12,8 +12,35 @@ import org.jgrapht.graph.AsSubgraph;
import org.jgrapht.graph.DefaultUndirectedWeightedGraph;
import org.jgrapht.graph.DefaultWeightedEdge;
// Helper functions for the Shape interface.
public class Shapes {
// Normalises shapes between the coords -1 and 1 for proper scaling on an oscilloscope. May not
// work perfectly with curves that heavily deviate from their start and end points.
public static List<Shape> normalizeShapes(List<Shape> shapes) {
double maxVertex = 0;
for (Shape shape : shapes) {
Vector2 startVector = shape.nextVector(0);
Vector2 endVector = shape.nextVector(1);
double maxX = Math.max(Math.abs(startVector.getX()), Math.abs(endVector.getX()));
double maxY = Math.max(Math.abs(startVector.getY()), Math.abs(endVector.getY()));
maxVertex = Math.max(Math.max(maxX, maxY), maxVertex);
}
double factor = 2 / maxVertex;
for (int i = 0; i < shapes.size(); i++) {
shapes.set(i, shapes.get(i)
.scale(new Vector2(factor, -factor))
.translate(new Vector2(-1, 1)));
}
return shapes;
}
public static List<Shape> generatePolygram(int sides, int angleJump, Vector2 start,
double weight) {
List<Shape> polygon = new ArrayList<>();