From 9453cc239571b4a247a626acb1434ee18a225ef2 Mon Sep 17 00:00:00 2001 From: James Ball Date: Mon, 16 Nov 2020 20:47:43 +0000 Subject: [PATCH] Implement rendering of lines of text and improve normalize function --- src/parser/TextParser.java | 26 +++++++-- src/shapes/Shape.java | 107 +++++++++++++++++++++++++++++-------- text/hello.txt | 2 +- 3 files changed, 110 insertions(+), 25 deletions(-) diff --git a/src/parser/TextParser.java b/src/parser/TextParser.java index 24eec5b5..2232512b 100644 --- a/src/parser/TextParser.java +++ b/src/parser/TextParser.java @@ -4,22 +4,29 @@ import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; import shapes.Shape; +import shapes.Vector2; public class TextParser extends FileParser{ - private final Map> charToShape; + private static final char WIDE_CHAR = '_'; + private static final double LENGTH_SCALAR = 1.2; + private final Map> charToShape; private final List text; + private List shapes; + public TextParser(String path, String font) throws IOException, SAXException, ParserConfigurationException { this.charToShape = new HashMap<>(); + this.shapes = new ArrayList<>(); this.text = Files.readAllLines(Paths.get(path), Charset.defaultCharset()); parseFile(font); } @@ -34,18 +41,31 @@ public class TextParser extends FileParser{ throws ParserConfigurationException, IOException, SAXException, IllegalArgumentException { SvgParser parser = new SvgParser(path); + charToShape.put(WIDE_CHAR, parser.parseGlyphsWithUnicode(WIDE_CHAR)); + for (String line : text) { for (char c : line.toCharArray()) { if (!charToShape.containsKey(c)) { List glyph = parser.parseGlyphsWithUnicode(c); - charToShape.put(c, Shape.flipShapes(Shape.normalize(glyph))); + charToShape.put(c, glyph); } } } + + double length = LENGTH_SCALAR * Shape.width(charToShape.get(WIDE_CHAR)); + + for (String line : text) { + char[] lineChars = line.toCharArray(); + for (int i = 0; i < lineChars.length; i++) { + shapes.addAll(Shape.translate(charToShape.get(lineChars[i]), new Vector2(i * length, 0))); + } + } + + shapes = Shape.flip(Shape.normalize(shapes)); } @Override public List nextFrame() { - return charToShape.get(text.get(0).charAt(0)); + return shapes; } } diff --git a/src/shapes/Shape.java b/src/shapes/Shape.java index 57f3c7c8..84283446 100644 --- a/src/shapes/Shape.java +++ b/src/shapes/Shape.java @@ -35,44 +35,109 @@ public abstract class Shape { // 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 normalize(List shapes) { - double maxVertex = 0; + double maxAbsVertex = maxAbsVector(shapes).getX(); + List normalizedShapes = new ArrayList<>(); + + for (Shape shape : shapes) { + normalizedShapes.add(shape.scale(new Vector2(2 / maxAbsVertex, -2 / maxAbsVertex))); + } + + return center(normalizedShapes); + } + + public static List center(List shapes) { + Vector2 maxVector = maxVector(shapes); + double height = height(shapes); + + return translate(shapes, new Vector2(-1, -maxVector.getY() + height / 2)); + } + + public static Vector2 maxAbsVector(List shapes) { + double maxX = 0; + double maxY = 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())); + double x = Math.max(Math.abs(startVector.getX()), Math.abs(endVector.getX())); + double y = Math.max(Math.abs(startVector.getY()), Math.abs(endVector.getY())); - maxVertex = Math.max(Math.max(maxX, maxY), maxVertex); + maxX = Math.max(x, maxX); + maxY = Math.max(y, maxY); } - double factor = 2 / maxVertex; - - List normalizedShapes = new ArrayList<>(); - - for (Shape shape : shapes) { - normalizedShapes.add(shape - .scale(new Vector2(factor, -factor)) - .translate(new Vector2(-1, 1)) - ); - } - - return normalizedShapes; + return new Vector2(maxX, maxY); } - public static List flipShapes(List inputShapes) { + public static Vector2 maxVector(List shapes) { + double maxX = Double.NEGATIVE_INFINITY; + double maxY = Double.NEGATIVE_INFINITY; + + for (Shape shape : shapes) { + Vector2 startVector = shape.nextVector(0); + Vector2 endVector = shape.nextVector(1); + + double x = Math.max(startVector.getX(), endVector.getX()); + double y = Math.max(startVector.getY(), endVector.getY()); + + maxX = Math.max(x, maxX); + maxY = Math.max(y, maxY); + } + + return new Vector2(maxX, maxY); + } + + public static List flip(List shapes) { List flippedShapes = new ArrayList<>(); - for (Shape shape : inputShapes) { - flippedShapes.add(shape - .scale(new Vector2(1, -1)) - ); + for (Shape shape : shapes) { + flippedShapes.add(shape.scale(new Vector2(1, -1))); } return flippedShapes; } + public static double height(List shapes) { + double maxY = Double.NEGATIVE_INFINITY; + double minY = Double.POSITIVE_INFINITY; + + for (Shape shape : shapes) { + Vector2 startVector = shape.nextVector(0); + Vector2 endVector = shape.nextVector(1); + + maxY = Math.max(maxY, Math.max(startVector.getY(), endVector.getY())); + minY = Math.min(minY, Math.min(startVector.getY(), endVector.getY())); + } + + return Math.abs(maxY - minY); + } + + public static double width(List shapes) { + double maxX = Double.NEGATIVE_INFINITY; + double minX = Double.POSITIVE_INFINITY; + + for (Shape shape : shapes) { + Vector2 startVector = shape.nextVector(0); + Vector2 endVector = shape.nextVector(1); + + maxX = Math.max(maxX, Math.max(startVector.getX(), endVector.getX())); + minX = Math.min(minX, Math.min(startVector.getX(), endVector.getX())); + } + + return Math.abs(maxX - minX); + } + + public static List translate(List shapes, Vector2 translation) { + List translatedShapes = new ArrayList<>(); + + for (Shape shape : shapes) { + translatedShapes.add(shape.translate(translation)); + } + + return translatedShapes; + } + public static List generatePolygram(int sides, int angleJump, Vector2 start, double weight) { List polygon = new ArrayList<>(); diff --git a/text/hello.txt b/text/hello.txt index bc7774a7..6769dd60 100644 --- a/text/hello.txt +++ b/text/hello.txt @@ -1 +1 @@ -hello world! \ No newline at end of file +Hello world! \ No newline at end of file