allows the usage of polygons with fractional coordinates

This commit is contained in:
hneemann 2018-03-18 16:45:42 +01:00
parent 7917e6df43
commit 87f8ae6138
16 changed files with 311 additions and 106 deletions

View File

@ -208,7 +208,7 @@ public class VisualElement implements Drawable, Movable, AttributeListener {
if (transform == null) { if (transform == null) {
int rotate = getRotate(); int rotate = getRotate();
if (rotate == 0) if (rotate == 0)
transform = v -> v.add(pos); transform = new TransformTranslate(pos);
else else
transform = new TransformRotate(pos, rotate); transform = new TransformRotate(pos, rotate);
} }

View File

@ -57,7 +57,7 @@ public class GraphicMinMax implements Graphic {
@Override @Override
public void drawPolygon(Polygon p, Style style) { public void drawPolygon(Polygon p, Style style) {
for (Vector v : p) for (VectorInterface v : p)
check(v); check(v);
} }
@ -72,10 +72,10 @@ public class GraphicMinMax implements Graphic {
* *
* @param p the point to check * @param p the point to check
*/ */
public void check(Vector p) { public void check(VectorInterface p) {
if (min == null || max == null) { if (min == null || max == null) {
min = new Vector(p.x, p.y); min = new Vector(p.getX(), p.getY());
max = new Vector(p.x, p.y); max = new Vector(p.getX(), p.getY());
} else { } else {
min = Vector.min(min, p); min = Vector.min(min, p);
max = Vector.max(max, p); max = Vector.max(max, p);

View File

@ -296,8 +296,8 @@ public class GraphicSVG implements Graphic {
} }
} }
private String str(Vector p) { private String str(VectorInterface p) {
return p.x + "," + p.y; return p.getXFloat() + "," + p.getYFloat();
} }
} }

View File

@ -68,13 +68,15 @@ public class GraphicSwing implements Graphic {
//CHECKSTYLE.OFF: ModifiedControlVariable //CHECKSTYLE.OFF: ModifiedControlVariable
for (int i = 0; i < p.size(); i++) { for (int i = 0; i < p.size(); i++) {
if (i == 0) { if (i == 0) {
path.moveTo(p.get(i).x, p.get(i).y); path.moveTo(p.get(i).getXFloat(), p.get(i).getYFloat());
} else { } else {
if (p.isBezierStart(i)) { if (p.isBezierStart(i)) {
path.curveTo(p.get(i).x, p.get(i).y, p.get(i + 1).x, p.get(i + 1).y, p.get(i + 2).x, p.get(i + 2).y); path.curveTo(p.get(i).getXFloat(), p.get(i).getYFloat(),
p.get(i + 1).getXFloat(), p.get(i + 1).getYFloat(),
p.get(i + 2).getXFloat(), p.get(i + 2).getYFloat());
i += 2; i += 2;
} else } else
path.lineTo(p.get(i).x, p.get(i).y); path.lineTo(p.get(i).getXFloat(), p.get(i).getYFloat());
} }
} }
//CHECKSTYLE.ON: ModifiedControlVariable //CHECKSTYLE.ON: ModifiedControlVariable

View File

@ -13,9 +13,9 @@ import java.util.StringTokenizer;
/** /**
* A polygon representation used by the {@link Graphic} interface. * A polygon representation used by the {@link Graphic} interface.
*/ */
public class Polygon implements Iterable<Vector> { public class Polygon implements Iterable<VectorInterface> {
private final ArrayList<Vector> points; private final ArrayList<VectorInterface> points;
private final HashSet<Integer> isBezierStart; private final HashSet<Integer> isBezierStart;
private final boolean closed; private final boolean closed;
@ -41,7 +41,7 @@ public class Polygon implements Iterable<Vector> {
* @param points the polygons points * @param points the polygons points
* @param closed true if polygon is closed * @param closed true if polygon is closed
*/ */
public Polygon(ArrayList<Vector> points, boolean closed) { public Polygon(ArrayList<VectorInterface> points, boolean closed) {
this.points = points; this.points = points;
this.closed = closed; this.closed = closed;
isBezierStart = new HashSet<>(); isBezierStart = new HashSet<>();
@ -71,7 +71,7 @@ public class Polygon implements Iterable<Vector> {
* @param p the point to add * @param p the point to add
* @return this for chained calls * @return this for chained calls
*/ */
public Polygon add(Vector p) { public Polygon add(VectorInterface p) {
points.add(p); points.add(p);
return this; return this;
} }
@ -115,12 +115,12 @@ public class Polygon implements Iterable<Vector> {
* @param i the index * @param i the index
* @return the i'th point * @return the i'th point
*/ */
public Vector get(int i) { public VectorInterface get(int i) {
return points.get(i); return points.get(i);
} }
@Override @Override
public Iterator<Vector> iterator() { public Iterator<VectorInterface> iterator() {
return points.iterator(); return points.iterator();
} }
@ -152,14 +152,14 @@ public class Polygon implements Iterable<Vector> {
/** /**
* @return the first point of the polygon * @return the first point of the polygon
*/ */
public Vector getFirst() { public VectorInterface getFirst() {
return points.get(0); return points.get(0);
} }
/** /**
* @return the last point of the polygon * @return the last point of the polygon
*/ */
public Vector getLast() { public VectorInterface getLast() {
return points.get(points.size() - 1); return points.get(points.size() - 1);
} }
@ -199,7 +199,7 @@ public class Polygon implements Iterable<Vector> {
*/ */
public Polygon transform(Transform transform) { public Polygon transform(Transform transform) {
Polygon p = new Polygon(closed); Polygon p = new Polygon(closed);
for (Vector v : points) for (VectorInterface v : points)
p.add(transform.transform(v)); p.add(transform.transform(v));
p.isBezierStart.addAll(isBezierStart); p.isBezierStart.addAll(isBezierStart);
return p; return p;
@ -213,56 +213,56 @@ public class Polygon implements Iterable<Vector> {
*/ */
public static Polygon createFromPath(String path) { public static Polygon createFromPath(String path) {
StringTokenizer tok = new StringTokenizer(path, " ,"); StringTokenizer tok = new StringTokenizer(path, " ,");
int x = 0; float x = 0;
int y = 0; float y = 0;
boolean closed = false; boolean closed = false;
ArrayList<Vector> list = new ArrayList<>(); ArrayList<VectorInterface> list = new ArrayList<>();
String lastTok = null; String lastTok = null;
while (tok.hasMoreTokens()) { while (tok.hasMoreTokens()) {
final String t = tok.nextToken(); final String t = tok.nextToken();
switch (t) { switch (t) {
case "M": case "M":
x = Integer.parseInt(tok.nextToken()); x = Float.parseFloat(tok.nextToken());
y = Integer.parseInt(tok.nextToken()); y = Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
lastTok = t; lastTok = t;
break; break;
case "m": case "m":
x += Integer.parseInt(tok.nextToken()); x += Float.parseFloat(tok.nextToken());
y += Integer.parseInt(tok.nextToken()); y += Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
lastTok = t; lastTok = t;
break; break;
case "V": case "V":
y = Integer.parseInt(tok.nextToken()); y = Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
lastTok = t; lastTok = t;
break; break;
case "v": case "v":
y += Integer.parseInt(tok.nextToken()); y += Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
lastTok = t; lastTok = t;
break; break;
case "H": case "H":
x = Integer.parseInt(tok.nextToken()); x = Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
lastTok = t; lastTok = t;
break; break;
case "h": case "h":
x += Integer.parseInt(tok.nextToken()); x += Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
lastTok = t; lastTok = t;
break; break;
case "l": case "l":
x += Integer.parseInt(tok.nextToken()); x += Float.parseFloat(tok.nextToken());
y += Integer.parseInt(tok.nextToken()); y += Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
lastTok = t; lastTok = t;
break; break;
case "L": case "L":
x = Integer.parseInt(tok.nextToken()); x = Float.parseFloat(tok.nextToken());
y = Integer.parseInt(tok.nextToken()); y = Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
lastTok = t; lastTok = t;
break; break;
case "Z": case "Z":
@ -272,30 +272,30 @@ public class Polygon implements Iterable<Vector> {
default: default:
switch (lastTok) { switch (lastTok) {
case "V": case "V":
y = Integer.parseInt(t); y = Float.parseFloat(t);
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
break; break;
case "v": case "v":
y += Integer.parseInt(t); y += Float.parseFloat(t);
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
break; break;
case "H": case "H":
x = Integer.parseInt(t); x = Float.parseFloat(t);
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
break; break;
case "h": case "h":
x += Integer.parseInt(t); x += Float.parseFloat(t);
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
break; break;
case "l": case "l":
x += Integer.parseInt(t); x += Float.parseFloat(t);
y += Integer.parseInt(tok.nextToken()); y += Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
break; break;
case "L": case "L":
x = Integer.parseInt(t); x = Float.parseFloat(t);
y = Integer.parseInt(tok.nextToken()); y = Float.parseFloat(tok.nextToken());
list.add(new Vector(x, y)); list.add(new VectorFloat(x, y));
break; break;
default: default:
return null; return null;

View File

@ -8,12 +8,35 @@ package de.neemann.digital.draw.graphics;
/** /**
* A simple transformation to a given vector * A simple transformation to a given vector
*/ */
public interface Transform { public abstract class Transform {
/** /**
* Transforms a vector * Transforms an integer vector
* *
* @param v the vector to transform * @param v the vector to transform
* @return the transformed vector * @return the transformed vector
*/ */
Vector transform(Vector v); public abstract Vector transform(Vector v);
/**
* Transforms an float vector
*
* @param v the vector to transform
* @return the transformed vector
*/
public abstract VectorFloat transform(VectorFloat v);
/**
* Transforms an vector interface
*
* @param v the vector to transform
* @return the transformed vector
*/
public VectorInterface transform(VectorInterface v) {
if (v instanceof Vector)
return transform((Vector) v);
else
return transform(v.getVectorFloat());
}
} }

View File

@ -8,11 +8,11 @@ package de.neemann.digital.draw.graphics;
/** /**
* Implements a rotation and translation. * Implements a rotation and translation.
*/ */
public class TransformRotate implements Transform { public class TransformRotate extends Transform {
private final int sin; private final int sin;
private final int cos; private final int cos;
private final Vector translation; private final VectorInterface translation;
/** /**
* Creates a new instance * Creates a new instance
@ -20,7 +20,7 @@ public class TransformRotate implements Transform {
* @param translation the translation * @param translation the translation
* @param rot the rotation * @param rot the rotation
*/ */
public TransformRotate(Vector translation, int rot) { public TransformRotate(VectorInterface translation, int rot) {
this.translation = translation; this.translation = translation;
switch (rot) { switch (rot) {
case 1: case 1:
@ -44,6 +44,13 @@ public class TransformRotate implements Transform {
@Override @Override
public Vector transform(Vector v) { public Vector transform(Vector v) {
return new Vector(v.x * cos + v.y * sin, -v.x * sin + v.y * cos).add(translation); return new Vector(v.getX() * cos + v.getY() * sin + translation.getX(),
-v.getX() * sin + v.getY() * cos + translation.getY());
}
@Override
public VectorFloat transform(VectorFloat v) {
return new VectorFloat(v.getXFloat() * cos + v.getYFloat() * sin + translation.getXFloat(),
-v.getXFloat() * sin + v.getYFloat() * cos + translation.getYFloat());
} }
} }

View File

@ -0,0 +1,32 @@
/*
* 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 translation
*/
public class TransformTranslate extends Transform {
private final VectorInterface trans;
/**
* Creates a new instance
*
* @param trans the translation
*/
public TransformTranslate(VectorInterface trans) {
this.trans = trans;
}
@Override
public Vector transform(Vector v) {
return v.add(trans.getX(), trans.getY());
}
@Override
public VectorFloat transform(VectorFloat v) {
return new VectorFloat(v.getXFloat() + trans.getXFloat(), v.getYFloat() + trans.getYFloat());
}
}

View File

@ -11,7 +11,7 @@ import java.util.List;
/** /**
* Represents a 2D Vector * Represents a 2D Vector
*/ */
public class Vector { public class Vector implements VectorInterface {
/** /**
* the x coordinate * the x coordinate
@ -62,12 +62,12 @@ public class Vector {
* @param p the vectors to evaluate * @param p the vectors to evaluate
* @return the minimum * @return the minimum
*/ */
public static Vector min(Vector... p) { public static Vector min(VectorInterface... p) {
int x = p[0].x; int x = p[0].getX();
int y = p[0].y; int y = p[0].getY();
for (int i = 1; i < p.length; i++) { for (int i = 1; i < p.length; i++) {
if (p[i].x < x) x = p[i].x; if (p[i].getX() < x) x = p[i].getX();
if (p[i].y < y) y = p[i].y; if (p[i].getY() < y) y = p[i].getY();
} }
return new Vector(x, y); return new Vector(x, y);
} }
@ -78,12 +78,12 @@ public class Vector {
* @param p the vectors to evaluate * @param p the vectors to evaluate
* @return the maximum * @return the maximum
*/ */
public static Vector max(Vector... p) { public static Vector max(VectorInterface... p) {
int x = p[0].x; int x = p[0].getX();
int y = p[0].y; int y = p[0].getY();
for (int i = 1; i < p.length; i++) { for (int i = 1; i < p.length; i++) {
if (p[i].x > x) x = p[i].x; if (p[i].getX() > x) x = p[i].getX();
if (p[i].y > y) y = p[i].y; if (p[i].getY() > y) y = p[i].getY();
} }
return new Vector(x, y); return new Vector(x, y);
} }
@ -225,4 +225,28 @@ public class Vector {
return new Vector(Math.round(x * 128 / l), Math.round(y * 128 / l)); return new Vector(Math.round(x * 128 / l), Math.round(y * 128 / l));
} }
@Override
public int getX() {
return x;
}
@Override
public int getY() {
return y;
}
@Override
public float getXFloat() {
return x;
}
@Override
public float getYFloat() {
return y;
}
@Override
public VectorFloat getVectorFloat() {
return new VectorFloat(x, y);
}
} }

View File

@ -0,0 +1,77 @@
/*
* 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;
import java.util.Objects;
/**
* A vector with float coordinates
*/
public class VectorFloat implements VectorInterface {
private final float x;
private final float y;
/**
* Creates a new vector
*
* @param x the x coordinate
* @param y the x coordinate
*/
public VectorFloat(float x, float y) {
this.x = x;
this.y = y;
}
@Override
public int getX() {
return (int) x;
}
@Override
public int getY() {
return (int) y;
}
@Override
public float getXFloat() {
return x;
}
@Override
public float getYFloat() {
return y;
}
@Override
public VectorFloat getVectorFloat() {
return this;
}
/**
* Subtracts the given vector
*
* @param sub the vector zo subtract
* @return the new vector
*/
public VectorFloat sub(VectorInterface sub) {
return new VectorFloat(x - sub.getXFloat(), y - sub.getYFloat());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
VectorFloat that = (VectorFloat) o;
return Float.compare(that.x, x) == 0
&& Float.compare(that.y, y) == 0;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}

View File

@ -0,0 +1,37 @@
/*
* 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;
/**
* The bas class of all vectors
*/
public interface VectorInterface {
/**
* @return the integer x coordinate
*/
int getX();
/**
* @return the integer y coordinate
*/
int getY();
/**
* @return the float x coordinate
*/
float getXFloat();
/**
* @return the float y coordinate
*/
float getYFloat();
/**
* @return this vactor as a {@link VectorFloat} instance
*/
VectorFloat getVectorFloat();
}

View File

@ -27,13 +27,13 @@ public abstract class SevenShape implements Shape {
*/ */
public static final Polygon FRAME = Polygon.createFromPath("m -10,1 L 70,1 70,139 -10,139 z"); public static final Polygon FRAME = Polygon.createFromPath("m -10,1 L 70,1 70,139 -10,139 z");
private static final Polygon[] POLYGONS = new Polygon[]{ private static final Polygon[] POLYGONS = new Polygon[]{
Polygon.createFromPath("m 57,14 L 62,10 57,5 10,5 5,10 9,14 z"), // 0, Polygon.createFromPath("m 12.04,5.0 L 52.8,5.0 58.15,10.61 52.28,16.22 11.52,16.22 6.17,10.61 z"), // 0,
Polygon.createFromPath("m 53,65 L 57,14 62,10 66,14 63,65 57,70 z"), // 1, Polygon.createFromPath("m 59.49,12.01 L 64.84,17.62 62.74,62.99 56.87,68.6 51.52,62.99 53.62,17.62 z"), // 1,
Polygon.createFromPath("m 49,126 L 52,75 57,70 62,75 58,126 53,130 z"), // 2, Polygon.createFromPath("m 56.74,71.4 L 62.09,77.01 60.0,122.38 54.13,127.99 48.78,122.38 50.88,77.01 z"), // 2,
Polygon.createFromPath("m 48,135 L 53,130 49,126 1,126 -3,130 1,135 z"), // 3, Polygon.createFromPath("m 6.55,123.78 L 47.32,123.78 52.67,129.39 46.8,135.0 6.04,135.0 0.69,129.39 z"), // 3,
Polygon.createFromPath("m -7,126 L -4,75 1,70 5,75 1,126 -3,130 z"), // 4, Polygon.createFromPath("m 1.96,71.4 L 7.31,77.01 5.22,122.38 -0.64,127.99 -5.99,122.38 -3.9,77.01 z"), // 4,
Polygon.createFromPath("m -3,65 L 0,14 5,10 9,14 6,65 1,70 z"), // 5, Polygon.createFromPath("m 4.7,12.01 L 10.05,17.62 7.96,62.99 2.09,68.6 -3.25,62.99 -1.15,17.62 z"), // 5,
Polygon.createFromPath("m 52,75 L 57,70 53,65 6,65 1,70 5,75 z"), // 6, Polygon.createFromPath("m 9.3,64.39 L 50.06,64.39 55.41,70.0 49.54,75.61 8.78,75.61 3.43,70.0 z"), // 6,
}; };
private static final Vector DOT = new Vector(58, 127); private static final Vector DOT = new Vector(58, 127);

View File

@ -29,22 +29,22 @@ import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
public class SixteenShape implements Shape { public class SixteenShape implements Shape {
private static final Polygon[] POLYGONS = new Polygon[]{ private static final Polygon[] POLYGONS = new Polygon[]{
Polygon.createFromPath("m 10,5 L 29,5 33,10 28,14 9,14 5,10 z"), // 0, Polygon.createFromPath("m 12.04,5.0 L 25.41,5.0 30.76,10.61 24.89,16.22 11.52,16.22 6.17,10.61 z"), // 0,
Polygon.createFromPath("m 38,5 L 57,5 62,10 57,14 38,14 33,10 z"), // 1, Polygon.createFromPath("m 39.43,5.0 L 52.8,5.0 58.15,10.61 52.28,16.22 38.91,16.22 33.56,10.61 z"), // 1,
Polygon.createFromPath("m 53,65 L 57,14 62,10 66,14 63,65 57,70 z"), // 2, Polygon.createFromPath("m 59.49,12.01 L 64.84,17.62 62.74,62.99 56.87,68.6 51.52,62.99 53.62,17.62 z"), // 2,
Polygon.createFromPath("m 49,126 L 52,75 57,70 62,75 58,126 53,130 z"), // 3, Polygon.createFromPath("m 56.74,71.4 L 62.09,77.01 60.0,122.38 54.13,127.99 48.78,122.38 50.88,77.01 z"), // 3,
Polygon.createFromPath("m 30,126 L 49,126 53,130 48,135 29,135 25,130 z"), // 4, Polygon.createFromPath("m 33.94,123.78 L 47.32,123.78 52.67,129.39 46.8,135.0 33.43,135.0 28.08,129.39 z"), // 4,
Polygon.createFromPath("m 1,126 L 20,126 25,130 20,135 1,135 -3,130 z"), // 5, Polygon.createFromPath("m 6.55,123.78 L 19.93,123.78 25.28,129.39 19.41,135.0 6.04,135.0 0.69,129.39 z"), // 5,
Polygon.createFromPath("m -7,126 L -4,75 1,70 5,75 1,126 -3,130 z"), // 6, Polygon.createFromPath("m 1.96,71.4 L 7.31,77.01 5.22,122.38 -0.64,127.99 -5.99,122.38 -3.9,77.01 z"), // 6,
Polygon.createFromPath("m -3,65 L 0,14 5,10 9,14 6,65 1,70 z"), // 7, Polygon.createFromPath("m 4.7,12.01 L 10.05,17.62 7.96,62.99 2.09,68.6 -3.25,62.99 -1.15,17.62 z"), // 7,
Polygon.createFromPath("m 6,65 L 25,65 29,70 24,75 5,75 1,70 z"), // 8, Polygon.createFromPath("m 9.29,64.39 L 22.67,64.39 28.02,70.0 22.15,75.61 8.78,75.61 3.43,70.0 z"), // 8,
Polygon.createFromPath("m 34,65 L 53,65 57,70 52,75 33,75 29,70 z"), // 9, Polygon.createFromPath("m 36.69,64.39 L 50.06,64.39 55.41,70.0 49.54,75.61 36.17,75.61 30.82,70.0 z"), // 9,
Polygon.createFromPath("m 14,14 L 26,56 25,65 20,65 8,24 9,14 z"), // 10, Polygon.createFromPath("m 12.01,18.2 L 17.06,18.2 22.73,50.48 22.18,62.41 17.13,62.41 11.46,30.13 z"), // 10,
Polygon.createFromPath("m 25,65 L 28,14 33,10 38,14 34,65 29,70 z"), // 11, Polygon.createFromPath("m 32.09,12.01 L 37.44,17.62 35.35,62.99 29.48,68.6 24.13,62.99 26.23,17.62 z"), // 11,
Polygon.createFromPath("m 52,14 L 35,56 34,65 39,65 56,24 57,14 z"), // 12, Polygon.createFromPath("m 46.56,18.2 L 51.61,18.2 51.06,30.13 42.41,62.41 37.36,62.41 37.91,50.48 z"), // 12,
Polygon.createFromPath("m 44,126 L 32,84 33,75 38,75 50,116 49,126 z"), // 13, Polygon.createFromPath("m 36.66,77.59 L 41.7,77.59 47.38,109.87 46.83,121.8 41.78,121.8 36.11,89.52 z"), // 13,
Polygon.createFromPath("m 20,126 L 24,75 29,70 33,75 30,126 25,130 z"), // 14, Polygon.createFromPath("m 29.35,71.4 L 34.7,77.01 32.61,122.38 26.74,127.99 21.39,122.38 23.49,77.01 z"), // 14,
Polygon.createFromPath("m 6,126 L 23,84 24,75 19,75 2,116 1,126 z"), // 15, Polygon.createFromPath("m 16.43,77.59 L 21.48,77.59 20.93,89.52 12.27,121.8 7.22,121.8 7.78,109.87 z"), // 15,
}; };
private static final Vector DOT = new Vector(58, 127); private static final Vector DOT = new Vector(58, 127);

View File

@ -11,10 +11,7 @@ import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.element.PinDescriptions; import de.neemann.digital.core.element.PinDescriptions;
import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.IOState;
import de.neemann.digital.draw.elements.Pins; 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.GraphicTransform;
import de.neemann.digital.draw.graphics.Style;
import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.draw.model.InverterConfig; import de.neemann.digital.draw.model.InverterConfig;
import de.neemann.digital.draw.shapes.GenericShape; import de.neemann.digital.draw.shapes.GenericShape;
import de.neemann.digital.draw.shapes.InteractorInterface; import de.neemann.digital.draw.shapes.InteractorInterface;
@ -65,7 +62,7 @@ public abstract class IEEEGenericShape implements Shape {
@Override @Override
public void drawTo(Graphic graphic, Style highLight) { public void drawTo(Graphic graphic, Style highLight) {
int offs = (inputs.size() / 2 - 1) * SIZE; int offs = (inputs.size() / 2 - 1) * SIZE;
drawIEEE(new GraphicTransform(graphic, v -> v.add(0, offs))); drawIEEE(new GraphicTransform(graphic, new TransformTranslate(new Vector(0, offs))));
if (offs > 0) { if (offs > 0) {
graphic.drawLine(new Vector(1, 0), new Vector(1, offs - SIZE2 - 1), Style.NORMAL); graphic.drawLine(new Vector(1, 0), new Vector(1, offs - SIZE2 - 1), Style.NORMAL);

View File

@ -12,6 +12,7 @@ import de.neemann.digital.draw.elements.Wire;
import de.neemann.digital.draw.graphics.Transform; import de.neemann.digital.draw.graphics.Transform;
import de.neemann.digital.draw.graphics.TransformRotate; import de.neemann.digital.draw.graphics.TransformRotate;
import de.neemann.digital.draw.graphics.Vector; import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.draw.graphics.VectorFloat;
import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
@ -70,6 +71,11 @@ public class ModifyMoveSelected implements Modification {
public Vector transform(Vector v) { public Vector transform(Vector v) {
return super.transform(v.sub(center)); return super.transform(v.sub(center));
} }
@Override
public VectorFloat transform(VectorFloat v) {
return super.transform(v.sub(center));
}
}; };
for (Movable m : elements) { for (Movable m : elements) {

View File

@ -18,9 +18,9 @@ public class PolygonTest extends TestCase {
private void check(Polygon p) { private void check(Polygon p) {
assertEquals(4, p.size()); assertEquals(4, p.size());
assertEquals(new Vector(10, 10), p.get(0)); assertEquals(new VectorFloat(10, 10), p.get(0));
assertEquals(new Vector(20, 10), p.get(1)); assertEquals(new VectorFloat(20, 10), p.get(1));
assertEquals(new Vector(20, 20), p.get(2)); assertEquals(new VectorFloat(20, 20), p.get(2));
assertEquals(new Vector(10, 20), p.get(3)); assertEquals(new VectorFloat(10, 20), p.get(3));
} }
} }