kopia lustrzana https://github.com/jameshball/osci-render
Implement rendering of lines of text and improve normalize function
rodzic
ff371316de
commit
9453cc2395
|
@ -4,22 +4,29 @@ import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import shapes.Shape;
|
import shapes.Shape;
|
||||||
|
import shapes.Vector2;
|
||||||
|
|
||||||
public class TextParser extends FileParser{
|
public class TextParser extends FileParser{
|
||||||
|
|
||||||
private final Map<Character, List<Shape>> charToShape;
|
private static final char WIDE_CHAR = '_';
|
||||||
|
private static final double LENGTH_SCALAR = 1.2;
|
||||||
|
|
||||||
|
private final Map<Character, List<Shape>> charToShape;
|
||||||
private final List<String> text;
|
private final List<String> text;
|
||||||
|
|
||||||
|
private List<Shape> shapes;
|
||||||
|
|
||||||
public TextParser(String path, String font)
|
public TextParser(String path, String font)
|
||||||
throws IOException, SAXException, ParserConfigurationException {
|
throws IOException, SAXException, ParserConfigurationException {
|
||||||
this.charToShape = new HashMap<>();
|
this.charToShape = new HashMap<>();
|
||||||
|
this.shapes = new ArrayList<>();
|
||||||
this.text = Files.readAllLines(Paths.get(path), Charset.defaultCharset());
|
this.text = Files.readAllLines(Paths.get(path), Charset.defaultCharset());
|
||||||
parseFile(font);
|
parseFile(font);
|
||||||
}
|
}
|
||||||
|
@ -34,18 +41,31 @@ public class TextParser extends FileParser{
|
||||||
throws ParserConfigurationException, IOException, SAXException, IllegalArgumentException {
|
throws ParserConfigurationException, IOException, SAXException, IllegalArgumentException {
|
||||||
SvgParser parser = new SvgParser(path);
|
SvgParser parser = new SvgParser(path);
|
||||||
|
|
||||||
|
charToShape.put(WIDE_CHAR, parser.parseGlyphsWithUnicode(WIDE_CHAR));
|
||||||
|
|
||||||
for (String line : text) {
|
for (String line : text) {
|
||||||
for (char c : line.toCharArray()) {
|
for (char c : line.toCharArray()) {
|
||||||
if (!charToShape.containsKey(c)) {
|
if (!charToShape.containsKey(c)) {
|
||||||
List<Shape> glyph = parser.parseGlyphsWithUnicode(c);
|
List<Shape> 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
|
@Override
|
||||||
public List<Shape> nextFrame() {
|
public List<Shape> nextFrame() {
|
||||||
return charToShape.get(text.get(0).charAt(0));
|
return shapes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,44 +35,109 @@ public abstract class Shape {
|
||||||
// Normalises shapes between the coords -1 and 1 for proper scaling on an oscilloscope. May not
|
// 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.
|
// work perfectly with curves that heavily deviate from their start and end points.
|
||||||
public static List<Shape> normalize(List<Shape> shapes) {
|
public static List<Shape> normalize(List<Shape> shapes) {
|
||||||
double maxVertex = 0;
|
double maxAbsVertex = maxAbsVector(shapes).getX();
|
||||||
|
List<Shape> normalizedShapes = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Shape shape : shapes) {
|
||||||
|
normalizedShapes.add(shape.scale(new Vector2(2 / maxAbsVertex, -2 / maxAbsVertex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return center(normalizedShapes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Shape> center(List<Shape> shapes) {
|
||||||
|
Vector2 maxVector = maxVector(shapes);
|
||||||
|
double height = height(shapes);
|
||||||
|
|
||||||
|
return translate(shapes, new Vector2(-1, -maxVector.getY() + height / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 maxAbsVector(List<Shape> shapes) {
|
||||||
|
double maxX = 0;
|
||||||
|
double maxY = 0;
|
||||||
|
|
||||||
for (Shape shape : shapes) {
|
for (Shape shape : shapes) {
|
||||||
Vector2 startVector = shape.nextVector(0);
|
Vector2 startVector = shape.nextVector(0);
|
||||||
Vector2 endVector = shape.nextVector(1);
|
Vector2 endVector = shape.nextVector(1);
|
||||||
|
|
||||||
double maxX = Math.max(Math.abs(startVector.getX()), Math.abs(endVector.getX()));
|
double x = Math.max(Math.abs(startVector.getX()), Math.abs(endVector.getX()));
|
||||||
double maxY = Math.max(Math.abs(startVector.getY()), Math.abs(endVector.getY()));
|
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;
|
return new Vector2(maxX, maxY);
|
||||||
|
}
|
||||||
|
|
||||||
List<Shape> normalizedShapes = new ArrayList<>();
|
public static Vector2 maxVector(List<Shape> shapes) {
|
||||||
|
double maxX = Double.NEGATIVE_INFINITY;
|
||||||
|
double maxY = Double.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
for (Shape shape : shapes) {
|
for (Shape shape : shapes) {
|
||||||
normalizedShapes.add(shape
|
Vector2 startVector = shape.nextVector(0);
|
||||||
.scale(new Vector2(factor, -factor))
|
Vector2 endVector = shape.nextVector(1);
|
||||||
.translate(new Vector2(-1, 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 normalizedShapes;
|
return new Vector2(maxX, maxY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Shape> flipShapes(List<Shape> inputShapes) {
|
public static List<Shape> flip(List<Shape> shapes) {
|
||||||
List<Shape> flippedShapes = new ArrayList<>();
|
List<Shape> flippedShapes = new ArrayList<>();
|
||||||
|
|
||||||
for (Shape shape : inputShapes) {
|
for (Shape shape : shapes) {
|
||||||
flippedShapes.add(shape
|
flippedShapes.add(shape.scale(new Vector2(1, -1)));
|
||||||
.scale(new Vector2(1, -1))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return flippedShapes;
|
return flippedShapes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double height(List<Shape> 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<Shape> 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<Shape> translate(List<Shape> shapes, Vector2 translation) {
|
||||||
|
List<Shape> translatedShapes = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Shape shape : shapes) {
|
||||||
|
translatedShapes.add(shape.translate(translation));
|
||||||
|
}
|
||||||
|
|
||||||
|
return translatedShapes;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<Shape> generatePolygram(int sides, int angleJump, Vector2 start,
|
public static List<Shape> generatePolygram(int sides, int angleJump, Vector2 start,
|
||||||
double weight) {
|
double weight) {
|
||||||
List<Shape> polygon = new ArrayList<>();
|
List<Shape> polygon = new ArrayList<>();
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
hello world!
|
Hello world!
|
Ładowanie…
Reference in New Issue