From 939ee8732debd8e0556158514bcc4a0947deb32f Mon Sep 17 00:00:00 2001 From: hneemann Date: Fri, 2 Nov 2018 11:17:13 +0100 Subject: [PATCH] added new matrix transforms and closes #146 --- .../de/neemann/digital/core/element/Keys.java | 9 + .../java/de/neemann/digital/core/io/Out.java | 6 +- .../digital/draw/graphics/Polygon.java | 119 +---------- .../digital/draw/graphics/PolygonParser.java | 186 ++++++++++++++++++ .../digital/draw/graphics/Transform.java | 46 +++++ .../draw/graphics/TransformMatrix.java | 85 ++++++++ .../draw/graphics/TransformRotate.java | 5 + .../draw/graphics/TransformTranslate.java | 15 ++ .../neemann/digital/draw/graphics/Vector.java | 5 + .../digital/draw/graphics/VectorFloat.java | 6 + .../draw/graphics/VectorInterface.java | 7 + .../digital/draw/shapes/SevenShape.java | 26 ++- .../digital/draw/shapes/SixteenShape.java | 13 +- src/main/resources/lang/lang_de.xml | 4 +- src/main/resources/lang/lang_en.xml | 4 +- .../draw/graphics/PolygonParserTest.java | 42 ++++ 16 files changed, 450 insertions(+), 128 deletions(-) create mode 100644 src/main/java/de/neemann/digital/draw/graphics/PolygonParser.java create mode 100644 src/main/java/de/neemann/digital/draw/graphics/TransformMatrix.java create mode 100644 src/test/java/de/neemann/digital/draw/graphics/PolygonParserTest.java diff --git a/src/main/java/de/neemann/digital/core/element/Keys.java b/src/main/java/de/neemann/digital/core/element/Keys.java index a59967171..7af8959c7 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -159,6 +159,15 @@ public final class Keys { .allowGroupEdit() .setSecondary(); + /** + * The size of a seven seg display + */ + public static final Key SEVEN_SEG_SIZE + = new Key.KeyInteger("Size", 2) + .setComboBoxValues(0, 1, 2, 3, 4, 5) + .setMin(0) + .allowGroupEdit(); + /** * The value of constants */ diff --git a/src/main/java/de/neemann/digital/core/io/Out.java b/src/main/java/de/neemann/digital/core/io/Out.java index 2ab2ca8be..f10414d01 100644 --- a/src/main/java/de/neemann/digital/core/io/Out.java +++ b/src/main/java/de/neemann/digital/core/io/Out.java @@ -68,7 +68,8 @@ public class Out implements Element { public static final ElementTypeDescription SEVENHEXDESCRIPTION = new ElementTypeDescription("Seven-Seg-Hex", attributes -> new Out(4, 1), input("d"), input("dp")) - .addAttribute(Keys.COLOR); + .addAttribute(Keys.COLOR) + .addAttribute(Keys.SEVEN_SEG_SIZE); /** * Sixteen Segment Display @@ -76,7 +77,8 @@ public class Out implements Element { public static final ElementTypeDescription SIXTEENDESCRIPTION = new ElementTypeDescription("SixteenSeg", attributes -> new Out(16, 1), input("led"), input("dp")) - .addAttribute(Keys.COLOR); + .addAttribute(Keys.COLOR) + .addAttribute(Keys.SEVEN_SEG_SIZE); private final int[] bits; private final String label; diff --git a/src/main/java/de/neemann/digital/draw/graphics/Polygon.java b/src/main/java/de/neemann/digital/draw/graphics/Polygon.java index 5dfc6350c..9bcbd5a41 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/Polygon.java +++ b/src/main/java/de/neemann/digital/draw/graphics/Polygon.java @@ -8,7 +8,6 @@ package de.neemann.digital.draw.graphics; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; -import java.util.StringTokenizer; /** * A polygon representation used by the {@link Graphic} interface. @@ -198,6 +197,9 @@ public class Polygon implements Iterable { * @return the transformed polygon */ public Polygon transform(Transform transform) { + if (transform == Transform.IDENTITY) + return this; + Polygon p = new Polygon(closed); for (VectorInterface v : points) p.add(v.transform(transform)); @@ -237,115 +239,14 @@ public class Polygon implements Iterable { * @return the polygon or null if there was an error */ public static Polygon createFromPath(String path) { - StringTokenizer tok = new StringTokenizer(path, " ,"); - float x = 0; - float y = 0; - Polygon p = new Polygon(); - String lastTok = ""; - while (tok.hasMoreTokens()) { - final String t = tok.nextToken(); - switch (t) { - case "M": - x = Float.parseFloat(tok.nextToken()); - y = Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - lastTok = t; - break; - case "m": - x += Float.parseFloat(tok.nextToken()); - y += Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - lastTok = t; - break; - case "V": - y = Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - lastTok = t; - break; - case "v": - y += Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - lastTok = t; - break; - case "H": - x = Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - lastTok = t; - break; - case "h": - x += Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - lastTok = t; - break; - case "l": - x += Float.parseFloat(tok.nextToken()); - y += Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - lastTok = t; - break; - case "L": - x = Float.parseFloat(tok.nextToken()); - y = Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - lastTok = t; - break; - case "c": - float x1 = x + Float.parseFloat(tok.nextToken()); - float y1 = y + Float.parseFloat(tok.nextToken()); - float x2 = x1 + Float.parseFloat(tok.nextToken()); - float y2 = y1 + Float.parseFloat(tok.nextToken()); - x = x2 + Float.parseFloat(tok.nextToken()); - y = y2 + Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x1, y1), new VectorFloat(x2, y2), new VectorFloat(x, y)); - break; - case "C": - x1 = Float.parseFloat(tok.nextToken()); - y1 = Float.parseFloat(tok.nextToken()); - x2 = Float.parseFloat(tok.nextToken()); - y2 = Float.parseFloat(tok.nextToken()); - x = Float.parseFloat(tok.nextToken()); - y = Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x1, y1), new VectorFloat(x2, y2), new VectorFloat(x, y)); - break; - case "Z": - case "z": - p.closed = true; - break; - default: - switch (lastTok) { - case "V": - y = Float.parseFloat(t); - p.add(new VectorFloat(x, y)); - break; - case "v": - y += Float.parseFloat(t); - p.add(new VectorFloat(x, y)); - break; - case "H": - x = Float.parseFloat(t); - p.add(new VectorFloat(x, y)); - break; - case "h": - x += Float.parseFloat(t); - p.add(new VectorFloat(x, y)); - break; - case "l": - x += Float.parseFloat(t); - y += Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - break; - case "L": - x = Float.parseFloat(t); - y = Float.parseFloat(tok.nextToken()); - p.add(new VectorFloat(x, y)); - break; - default: - return null; - } - break; - } + try { + return new PolygonParser(path).create(); + } catch (PolygonParser.ParserException e) { + return null; } - return p; } + void setClosed(boolean closed) { + this.closed = closed; + } } diff --git a/src/main/java/de/neemann/digital/draw/graphics/PolygonParser.java b/src/main/java/de/neemann/digital/draw/graphics/PolygonParser.java new file mode 100644 index 000000000..6e4282b54 --- /dev/null +++ b/src/main/java/de/neemann/digital/draw/graphics/PolygonParser.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2018 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.draw.graphics; + +/** + * Creates a polygon from a path + */ +public class PolygonParser { + enum Token {EOF, COMMAND, NUMBER} + + private final String path; + private int lastTokenPos; + private int pos; + private char command; + private float value; + private float x; + private float y; + + /** + * Creates a new instance + * + * @param path the path to parse + */ + PolygonParser(String path) { + this.path = path; + pos = 0; + } + + Token next() { + lastTokenPos = pos; + while (pos < path.length() && (path.charAt(pos) == ' ' || path.charAt(pos) == ',')) + pos++; + if (pos == path.length()) + return Token.EOF; + + char c = path.charAt(pos); + if (Character.isAlphabetic(c)) { + pos++; + command = c; + return Token.COMMAND; + } else { + value = parseNumber(); + return Token.NUMBER; + } + } + + private char peekChar() { + return path.charAt(pos); + } + + private float parseNumber() { + int p0 = pos; + if (peekChar() == '+' || peekChar() == '-') + pos++; + + while (pos < path.length() && (Character.isDigit(peekChar()) || peekChar() == '.')) + pos++; + + if (pos < path.length() && (peekChar() == 'e' || peekChar() == 'E')) { + pos++; + if (peekChar() == '+' || peekChar() == '-') + pos++; + + while (pos < path.length() && (Character.isDigit(peekChar()) || peekChar() == '.')) + pos++; + } + + return Float.parseFloat(path.substring(p0, pos)); + } + + + private void unreadToken() { + pos = lastTokenPos; + } + + char getCommand() { + return command; + } + + double getValue() { + return value; + } + + private float nextValue() throws ParserException { + if (next() != Token.NUMBER) + throw new ParserException("expected a number at pos " + pos + " in '" + path + "'"); + return value; + } + + private VectorFloat nextVector() throws ParserException { + x = nextValue(); + y = nextValue(); + return new VectorFloat(x, y); + } + + private VectorFloat nextVectorInc() throws ParserException { + x += nextValue(); + y += nextValue(); + return new VectorFloat(x, y); + } + + /** + * Creates a polygon from the given path. + * + * @return the polygon + * @throws ParserException ParserException + */ + public Polygon create() throws ParserException { + Polygon p = new Polygon(false); + Token tok; + while ((tok = next()) != Token.EOF) { + if (tok == Token.NUMBER) { + unreadToken(); + if (command == 'm') + command = 'l'; + else if (command == 'M') + command = 'L'; + } + switch (command) { + case 'M': + p.add(nextVector()); + break; + case 'm': + p.add(nextVectorInc()); + break; + case 'V': + y = nextValue(); + p.add(new VectorFloat(x, y)); + break; + case 'v': + y += nextValue(); + p.add(new VectorFloat(x, y)); + break; + case 'H': + x = nextValue(); + p.add(new VectorFloat(x, y)); + break; + case 'h': + x += nextValue(); + p.add(new VectorFloat(x, y)); + break; + case 'l': + p.add(nextVectorInc()); + break; + case 'L': + p.add(nextVector()); + break; + case 'c': + p.add(nextVectorInc(), nextVectorInc(), nextVectorInc()); + break; + case 'C': + p.add(nextVector(), nextVector(), nextVector()); + break; + case 'a': + addArc(p, nextVectorInc(), nextValue(), nextValue() != 0, nextValue() != 0, nextVectorInc()); + break; + case 'A': + addArc(p, nextVector(), nextValue(), nextValue() != 0, nextValue() != 0, nextVector()); + break; + case 'Z': + case 'z': + p.setClosed(true); + break; + default: + throw new ParserException("unsupported path command " + command); + } + } + return p; + } + + private void addArc(Polygon p, VectorFloat rad, float rot, boolean large, boolean sweep, VectorFloat pos) { + p.add(pos); + } + + /** + * The parser exception + */ + public static final class ParserException extends Exception { + private ParserException(String message) { + super(message); + } + } +} diff --git a/src/main/java/de/neemann/digital/draw/graphics/Transform.java b/src/main/java/de/neemann/digital/draw/graphics/Transform.java index 80ebf2990..7f39d323f 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/Transform.java +++ b/src/main/java/de/neemann/digital/draw/graphics/Transform.java @@ -10,6 +10,46 @@ package de.neemann.digital.draw.graphics; */ public interface Transform { + /** + * The identity transform + */ + Transform IDENTITY = new Transform() { + @Override + public Vector transform(Vector v) { + return v; + } + + @Override + public VectorFloat transform(VectorFloat v) { + return v; + } + + @Override + public TransformMatrix getMatrix() { + return new TransformMatrix(1, 0, 0, 1, 0, 0); + } + }; + + /** + * Combines the two given transformations to a common transformation + * + * @param t1 first transformation + * @param t2 second transformation + * @return the resulting transformation + */ + static Transform mul(Transform t1, Transform t2) { + TransformMatrix m1 = t1.getMatrix(); + TransformMatrix m2 = t2.getMatrix(); + return new TransformMatrix( + m1.a * m2.a + m1.b * m2.c, + m1.c * m2.a + m1.d * m2.c, + m1.a * m2.b + m1.b * m2.d, + m1.c * m2.b + m1.d * m2.d, + m1.a * m2.x + m1.b * m2.y + m1.x, + m1.c * m2.x + m1.d * m2.y + m1.y); + } + + /** * Transforms an integer vector * @@ -26,4 +66,10 @@ public interface Transform { */ VectorFloat transform(VectorFloat v); + /** + * Returns a matrix representation of this transformation + * + * @return the transformed Transform + */ + TransformMatrix getMatrix(); } diff --git a/src/main/java/de/neemann/digital/draw/graphics/TransformMatrix.java b/src/main/java/de/neemann/digital/draw/graphics/TransformMatrix.java new file mode 100644 index 000000000..246714513 --- /dev/null +++ b/src/main/java/de/neemann/digital/draw/graphics/TransformMatrix.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2018 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.draw.graphics; + +/** + * A Matrix transformation + */ +public class TransformMatrix implements Transform { + + + /** + * Creates a rotation. + * + * @param w the angle in 360 grad + * @return the transformation + */ + public static TransformMatrix rotate(float w) { + final double phi = w / 180 * Math.PI; + float cos = (float) Math.cos(phi); + float sin = (float) Math.sin(phi); + return new TransformMatrix(cos, sin, -sin, cos, 0, 0); + } + + final float a; + final float b; + final float c; + final float d; + final float x; + final float y; + + /** + * Creates a new instance + * + * @param a A_00 + * @param b A_10 + * @param c A_01 + * @param d A_11 + * @param x x offset + * @param y y offset + */ + public TransformMatrix(float a, float b, float c, float d, float x, float y) { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.x = x; + this.y = y; + } + + @Override + public Vector transform(Vector v) { + return new Vector( + (int) (v.getXFloat() * a + v.getYFloat() * b + x), + (int) (v.getXFloat() * c + v.getYFloat() * d + y)); + } + + @Override + public VectorFloat transform(VectorFloat v) { + return new VectorFloat( + v.getXFloat() * a + v.getYFloat() * b + x, + v.getXFloat() * c + v.getYFloat() * d + y); + } + + + /** + * Transforms a direction vector + * + * @param v the vector to transform + * @return the transformed vector + */ + public VectorFloat transformDirection(VectorInterface v) { + return new VectorFloat( + v.getXFloat() * a + v.getYFloat() * b, + v.getXFloat() * c + v.getYFloat() * d); + } + + @Override + public TransformMatrix getMatrix() { + return this; + } + +} diff --git a/src/main/java/de/neemann/digital/draw/graphics/TransformRotate.java b/src/main/java/de/neemann/digital/draw/graphics/TransformRotate.java index 0a43cbf41..60bb5d77c 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/TransformRotate.java +++ b/src/main/java/de/neemann/digital/draw/graphics/TransformRotate.java @@ -53,4 +53,9 @@ public class TransformRotate implements Transform { return new VectorFloat(v.getXFloat() * cos + v.getYFloat() * sin + translation.getXFloat(), -v.getXFloat() * sin + v.getYFloat() * cos + translation.getYFloat()); } + + @Override + public TransformMatrix getMatrix() { + return new TransformMatrix(cos, sin, -sin, cos, translation.getXFloat(), translation.getYFloat()); + } } diff --git a/src/main/java/de/neemann/digital/draw/graphics/TransformTranslate.java b/src/main/java/de/neemann/digital/draw/graphics/TransformTranslate.java index 68b4f3953..1fc47a214 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/TransformTranslate.java +++ b/src/main/java/de/neemann/digital/draw/graphics/TransformTranslate.java @@ -20,6 +20,16 @@ public class TransformTranslate implements Transform { this.trans = trans; } + /** + * Creates a new instance + * + * @param x the x translation + * @param y the y translation + */ + public TransformTranslate(float x, float y) { + this(new VectorFloat(x, y)); + } + @Override public Vector transform(Vector v) { return v.add(trans.getX(), trans.getY()); @@ -29,4 +39,9 @@ public class TransformTranslate implements Transform { public VectorFloat transform(VectorFloat v) { return new VectorFloat(v.getXFloat() + trans.getXFloat(), v.getYFloat() + trans.getYFloat()); } + + @Override + public TransformMatrix getMatrix() { + return new TransformMatrix(1, 0, 0, 1, trans.getXFloat(), trans.getYFloat()); + } } diff --git a/src/main/java/de/neemann/digital/draw/graphics/Vector.java b/src/main/java/de/neemann/digital/draw/graphics/Vector.java index 4c5234829..46899535d 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/Vector.java +++ b/src/main/java/de/neemann/digital/draw/graphics/Vector.java @@ -231,4 +231,9 @@ public class Vector implements VectorInterface { public VectorInterface transform(Transform tr) { return tr.transform(this); } + + @Override + public Vector round() { + return this; + } } diff --git a/src/main/java/de/neemann/digital/draw/graphics/VectorFloat.java b/src/main/java/de/neemann/digital/draw/graphics/VectorFloat.java index 22c1337fd..4009a9dc6 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/VectorFloat.java +++ b/src/main/java/de/neemann/digital/draw/graphics/VectorFloat.java @@ -120,4 +120,10 @@ public class VectorFloat implements VectorInterface { public int hashCode() { return Objects.hash(x, y); } + + + @Override + public Vector round() { + return new Vector(getX(), getY()); + } } diff --git a/src/main/java/de/neemann/digital/draw/graphics/VectorInterface.java b/src/main/java/de/neemann/digital/draw/graphics/VectorInterface.java index 6c6b06653..348afe0ce 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/VectorInterface.java +++ b/src/main/java/de/neemann/digital/draw/graphics/VectorInterface.java @@ -66,4 +66,11 @@ public interface VectorInterface { * @return the norm of this vector */ VectorFloat norm(); + + /** + * Rounds the vector to an int vector + * + * @return a int vector + */ + Vector round(); } diff --git a/src/main/java/de/neemann/digital/draw/shapes/SevenShape.java b/src/main/java/de/neemann/digital/draw/shapes/SevenShape.java index 14b21fd4f..a545fc437 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/SevenShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/SevenShape.java @@ -7,10 +7,8 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.Keys; -import de.neemann.digital.draw.graphics.Graphic; +import de.neemann.digital.draw.graphics.*; import de.neemann.digital.draw.graphics.Polygon; -import de.neemann.digital.draw.graphics.Style; -import de.neemann.digital.draw.graphics.Vector; import java.awt.*; @@ -39,6 +37,7 @@ public abstract class SevenShape implements Shape { private final Style onStyle; private final Style offStyle; + private final int size; /** * Creates a new instance @@ -48,16 +47,29 @@ public abstract class SevenShape implements Shape { public SevenShape(ElementAttributes attr) { onStyle = Style.NORMAL.deriveFillStyle(attr.get(Keys.COLOR)); offStyle = Style.NORMAL.deriveFillStyle(new Color(230, 230, 230)); + size = attr.get(Keys.SEVEN_SEG_SIZE); } @Override public void drawTo(Graphic graphic, Style highLight) { - graphic.drawPolygon(FRAME, Style.NORMAL); - + Transform tr = createTransform(size); + graphic.drawPolygon(FRAME.transform(tr), Style.NORMAL); for (int i = 0; i < 7; i++) - graphic.drawPolygon(POLYGONS[i], getStyleInt(i)); + graphic.drawPolygon(POLYGONS[i].transform(tr), getStyleInt(i)); - graphic.drawCircle(DOT, DOT.add(8, 8), getStyleInt(7)); + graphic.drawCircle(DOT.transform(tr), DOT.add(8, 8).transform(tr), getStyleInt(7)); + } + + static Transform createTransform(int size) { + if (size == 2) + return Transform.IDENTITY; + else { + final TransformTranslate tr1 = new TransformTranslate(-70, -139); + final TransformTranslate tr2 = new TransformTranslate(70, 139); + float s = (2 + size) / 4f; + final TransformMatrix trm = new TransformMatrix(s, 0, 0, s, 0, 0); + return Transform.mul(Transform.mul(tr2, trm), tr1); + } } private Style getStyleInt(int i) { diff --git a/src/main/java/de/neemann/digital/draw/shapes/SixteenShape.java b/src/main/java/de/neemann/digital/draw/shapes/SixteenShape.java index 3c1e7cd05..ff4103935 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/SixteenShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/SixteenShape.java @@ -14,10 +14,8 @@ import de.neemann.digital.core.element.PinDescriptions; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; -import de.neemann.digital.draw.graphics.Graphic; +import de.neemann.digital.draw.graphics.*; import de.neemann.digital.draw.graphics.Polygon; -import de.neemann.digital.draw.graphics.Style; -import de.neemann.digital.draw.graphics.Vector; import java.awt.*; @@ -54,6 +52,7 @@ public class SixteenShape implements Shape { private final Style onStyle; private final Style offStyle; private final PinDescriptions pins; + private final int size; private ObservableValue input; private ObservableValue dp; private Value inValue; @@ -70,6 +69,7 @@ public class SixteenShape implements Shape { pins = inputs; onStyle = Style.NORMAL.deriveFillStyle(attr.get(Keys.COLOR)); offStyle = Style.NORMAL.deriveFillStyle(new Color(230, 230, 230)); + size = attr.get(Keys.SEVEN_SEG_SIZE); } @Override @@ -96,7 +96,8 @@ public class SixteenShape implements Shape { @Override public void drawTo(Graphic graphic, Style highLight) { - graphic.drawPolygon(SevenShape.FRAME, Style.NORMAL); + Transform tr = SevenShape.createTransform(size); + graphic.drawPolygon(SevenShape.FRAME.transform(tr), Style.NORMAL); int bits = -1; if (inValue != null) @@ -106,13 +107,13 @@ public class SixteenShape implements Shape { for (Polygon p : POLYGONS) { Style s = onStyle; if ((bits & mask) == 0) s = offStyle; - graphic.drawPolygon(p, s); + graphic.drawPolygon(p.transform(tr), s); mask <<= 1; } Style s = onStyle; if (dpValue != null && !dpValue.getBool()) s = offStyle; - graphic.drawCircle(DOT, DOT.add(8, 8), s); + graphic.drawCircle(DOT.transform(tr), DOT.add(8, 8).transform(tr), s); } } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 4f9f482f4..8248d7284 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -986,8 +986,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Legt die Anzahl der Eingänge fest. Alle Eingänge müssen beschaltet werden. Bezeichnung Die Bezeichnung dieses Elementes. - Größe - Die Größe der LED in der Schaltung. + Größe + Die Größe der Darstellung in der Schaltung. Sprache Sprache der Oberfläche. Wird erst nach einem Neustart wirksam. Netzname diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 5804e4f11..9b6704ea6 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -981,8 +981,8 @@ The Number of Inputs used. Every input needs to be connected. Label The name of this element. - Size - The size of the LED in the circuit. + Size + The size of the shape in the circuit. Language Language of the GUI. Will only take effect after a restart. Net name diff --git a/src/test/java/de/neemann/digital/draw/graphics/PolygonParserTest.java b/src/test/java/de/neemann/digital/draw/graphics/PolygonParserTest.java new file mode 100644 index 000000000..0b25cb637 --- /dev/null +++ b/src/test/java/de/neemann/digital/draw/graphics/PolygonParserTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016 Helmut Neemann + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.draw.graphics; + +import junit.framework.TestCase; + +public class PolygonParserTest extends TestCase { + + public void testSimple() { + PolygonParser pp = new PolygonParser("m 1,2"); + + assertEquals(PolygonParser.Token.COMMAND, pp.next()); + assertEquals('m', pp.getCommand()); + + assertEquals(PolygonParser.Token.NUMBER, pp.next()); + assertEquals(1.0, pp.getValue(), 1e-6); + + assertEquals(PolygonParser.Token.NUMBER, pp.next()); + assertEquals(2.0, pp.getValue(), 1e-6); + + assertEquals(PolygonParser.Token.EOF, pp.next()); + assertEquals(PolygonParser.Token.EOF, pp.next()); + } + + public void testSimpleExp() { + PolygonParser pp = new PolygonParser("1e1"); + assertEquals(PolygonParser.Token.NUMBER, pp.next()); + assertEquals(10, pp.getValue(), 1e-6); + assertEquals(PolygonParser.Token.EOF, pp.next()); + } + + public void testSimpleExpSign() { + PolygonParser pp = new PolygonParser("1e-1"); + assertEquals(PolygonParser.Token.NUMBER, pp.next()); + assertEquals(0.1, pp.getValue(), 1e-6); + assertEquals(PolygonParser.Token.EOF, pp.next()); + } + +} \ No newline at end of file