mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 15:58:41 -04:00
fixed a bug in matrix multiply
This commit is contained in:
parent
1e3c6ee806
commit
402a38387f
@ -46,12 +46,12 @@ public interface Transform {
|
||||
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);
|
||||
m1.a * m2.a + m1.c * m2.b,
|
||||
m1.b * m2.a + m1.d * m2.b,
|
||||
m1.a * m2.c + m1.c * m2.d,
|
||||
m1.b * m2.c + m1.d * m2.d,
|
||||
m2.a * m1.x + m2.b * m1.y + m2.x,
|
||||
m2.c * m1.x + m2.d * m1.y + m2.y);
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class TransformMatrix implements Transform {
|
||||
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);
|
||||
return new TransformMatrix(cos, -sin, sin, cos, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,7 +152,7 @@ class Context {
|
||||
|
||||
private static void readTransform(Context c, String value) throws SvgException {
|
||||
StringTokenizer st = new StringTokenizer(value, "(),");
|
||||
Transform t = null;
|
||||
Transform t;
|
||||
final String trans = st.nextToken();
|
||||
switch (trans) {
|
||||
case "translate":
|
||||
@ -170,10 +170,13 @@ class Context {
|
||||
t = new TransformMatrix(xs, 0, 0, ys, 0, 0);
|
||||
break;
|
||||
case "matrix":
|
||||
final float ma = Float.parseFloat(st.nextToken());
|
||||
final float mb = Float.parseFloat(st.nextToken());
|
||||
final float mc = Float.parseFloat(st.nextToken());
|
||||
t = new TransformMatrix(
|
||||
Float.parseFloat(st.nextToken()),
|
||||
Float.parseFloat(st.nextToken()),
|
||||
Float.parseFloat(st.nextToken()),
|
||||
ma,
|
||||
mc,
|
||||
mb,
|
||||
Float.parseFloat(st.nextToken()),
|
||||
Float.parseFloat(st.nextToken()),
|
||||
Float.parseFloat(st.nextToken()));
|
||||
@ -184,15 +187,15 @@ class Context {
|
||||
t = TransformMatrix.rotate(w);
|
||||
float xc = Float.parseFloat(st.nextToken());
|
||||
float yc = Float.parseFloat(st.nextToken());
|
||||
t = Transform.mul(new TransformTranslate(xc, yc), t);
|
||||
t = Transform.mul(t, new TransformTranslate(-xc, -yc));
|
||||
t = Transform.mul(new TransformTranslate(-xc, -yc), t);
|
||||
t = Transform.mul(t, new TransformTranslate(xc, yc));
|
||||
} else
|
||||
t = TransformMatrix.rotate(w);
|
||||
break;
|
||||
default:
|
||||
throw new SvgException("unknown transform: " + value, null);
|
||||
}
|
||||
c.tr = Transform.mul(c.tr, t);
|
||||
c.tr = Transform.mul(t, c.tr);
|
||||
}
|
||||
|
||||
private static Color getColorFromString(String v) {
|
||||
|
@ -20,11 +20,11 @@ public class TransformMatrixTest extends TestCase {
|
||||
TransformMatrix tr = TransformMatrix.rotate(45);
|
||||
VectorInterface p = new VectorFloat(2, 0).transform(tr);
|
||||
assertEquals(Math.sqrt(2), p.getXFloat(), 1e-4);
|
||||
assertEquals(-Math.sqrt(2), p.getYFloat(), 1e-4);
|
||||
assertEquals(Math.sqrt(2), p.getYFloat(), 1e-4);
|
||||
}
|
||||
|
||||
public void testRotateInverse() {
|
||||
Transform tr = new TransformRotate(new Vector(2,3),1);
|
||||
Transform tr = new TransformRotate(new Vector(2, 3), 1);
|
||||
VectorInterface p = new VectorFloat(7, 8);
|
||||
|
||||
VectorInterface t = p.transform(tr).transform(tr.invert());
|
||||
@ -43,26 +43,52 @@ public class TransformMatrixTest extends TestCase {
|
||||
|
||||
public void testUniform() {
|
||||
assertTrue(TransformMatrix.rotate(30).isUniform());
|
||||
assertTrue(new TransformRotate(new Vector(2,2),0).getMatrix().isUniform());
|
||||
assertTrue(new TransformRotate(new Vector(2,2),1).getMatrix().isUniform());
|
||||
assertTrue(new TransformRotate(new Vector(2,2),2).getMatrix().isUniform());
|
||||
assertTrue(new TransformRotate(new Vector(2,2),3).getMatrix().isUniform());
|
||||
assertTrue(new TransformTranslate(4,5).getMatrix().isUniform());
|
||||
assertTrue(TransformMatrix.scale(2,2).isUniform());
|
||||
assertTrue(new TransformRotate(new Vector(2, 2), 0).getMatrix().isUniform());
|
||||
assertTrue(new TransformRotate(new Vector(2, 2), 1).getMatrix().isUniform());
|
||||
assertTrue(new TransformRotate(new Vector(2, 2), 2).getMatrix().isUniform());
|
||||
assertTrue(new TransformRotate(new Vector(2, 2), 3).getMatrix().isUniform());
|
||||
assertTrue(new TransformTranslate(4, 5).getMatrix().isUniform());
|
||||
assertTrue(TransformMatrix.scale(2, 2).isUniform());
|
||||
|
||||
assertFalse(TransformMatrix.scale(2,3).isUniform());
|
||||
assertFalse(TransformMatrix.scale(2, 3).isUniform());
|
||||
}
|
||||
|
||||
public void testNoRotation() {
|
||||
assertFalse(TransformMatrix.rotate(30).noRotation());
|
||||
assertTrue(new TransformRotate(new Vector(2,2),0).getMatrix().noRotation());
|
||||
assertFalse(new TransformRotate(new Vector(2,2),1).getMatrix().noRotation());
|
||||
assertTrue(new TransformRotate(new Vector(2,2),2).getMatrix().noRotation());
|
||||
assertFalse(new TransformRotate(new Vector(2,2),3).getMatrix().noRotation());
|
||||
assertTrue(new TransformTranslate(4,5).getMatrix().noRotation());
|
||||
assertTrue(TransformMatrix.scale(2,2).noRotation());
|
||||
assertTrue(new TransformRotate(new Vector(2, 2), 0).getMatrix().noRotation());
|
||||
assertFalse(new TransformRotate(new Vector(2, 2), 1).getMatrix().noRotation());
|
||||
assertTrue(new TransformRotate(new Vector(2, 2), 2).getMatrix().noRotation());
|
||||
assertFalse(new TransformRotate(new Vector(2, 2), 3).getMatrix().noRotation());
|
||||
assertTrue(new TransformTranslate(4, 5).getMatrix().noRotation());
|
||||
assertTrue(TransformMatrix.scale(2, 2).noRotation());
|
||||
|
||||
assertTrue(TransformMatrix.scale(2,3).noRotation());
|
||||
assertTrue(TransformMatrix.scale(2, 3).noRotation());
|
||||
}
|
||||
|
||||
public void testMul() {
|
||||
final TransformMatrix t1 = new TransformTranslate(10, 10).getMatrix();
|
||||
final TransformMatrix t2 = new TransformTranslate(10, 10).getMatrix();
|
||||
final VectorFloat v = new VectorFloat(2, 3);
|
||||
compare(v.transform(t1).transform(t2), v.transform(Transform.mul(t1, t2)));
|
||||
}
|
||||
|
||||
public void testMul2() {
|
||||
final TransformMatrix t1 = new TransformTranslate(10, 10).getMatrix();
|
||||
final TransformMatrix t2 = new TransformRotate(new Vector(10, 10), 1).getMatrix();
|
||||
final VectorFloat v = new VectorFloat(2, 3);
|
||||
compare(v.transform(t1).transform(t2), v.transform(Transform.mul(t1, t2)));
|
||||
}
|
||||
|
||||
public void testMul3() {
|
||||
final TransformMatrix t1 = new TransformTranslate(10, 10).getMatrix();
|
||||
final TransformMatrix t2 = TransformMatrix.rotate(45);
|
||||
final VectorFloat v = new VectorFloat(2, 3);
|
||||
compare(v.transform(t1).transform(t2), v.transform(Transform.mul(t1, t2)));
|
||||
}
|
||||
|
||||
private void compare(VectorInterface v1, VectorInterface v2) {
|
||||
assertEquals(v1.getXFloat(), v2.getXFloat(), 1e-4);
|
||||
assertEquals(v1.getYFloat(), v2.getYFloat(), 1e-4);
|
||||
}
|
||||
|
||||
}
|
@ -424,6 +424,34 @@ public class SvgImporterTest extends TestCase {
|
||||
.check();
|
||||
}
|
||||
|
||||
public void testInkscape7() throws IOException, SvgException, PolygonParser.ParserException, PinException {
|
||||
CustomShapeDescription custom = new SvgImporter(
|
||||
in("<svg viewBox=\"0 0 200 200\" xmlns=\"http://www.w3.org/2000/svg\">\n" +
|
||||
"<g transform=\"rotate(45, 100, 100)\">\n" +
|
||||
"<g transform=\"translate(10,10)\">\n" +
|
||||
"<rect fill=\"none\" stroke=\"black\" stroke-width=\"3\"\n" +
|
||||
" x=\"50\" y=\"50\" width=\"100\" height=\"100\" /> \n" +
|
||||
"</g>\n" +
|
||||
"</g>\n" +
|
||||
"</svg>")).create();
|
||||
|
||||
new CSDChecker(custom)
|
||||
.checkPolygon("M 100,43.431458 L 170.71068,114.142136 L 100,184.85281 L 29.289322,114.142136 Z")
|
||||
.check();
|
||||
}
|
||||
|
||||
public void testInkscape8() throws IOException, SvgException, PolygonParser.ParserException, PinException {
|
||||
CustomShapeDescription custom = new SvgImporter(
|
||||
in("<svg viewBox=\"0 0 200 200\" xmlns=\"http://www.w3.org/2000/svg\">\n" +
|
||||
"<rect fill=\"none\" stroke=\"yellow\" stroke-width=\"5\" transform=\"rotate(45, 100, 100) translate(10,10)\"\n" +
|
||||
" x=\"50\" y=\"50\" width=\"100\" height=\"100\" />\n" +
|
||||
"</svg>")).create();
|
||||
|
||||
new CSDChecker(custom)
|
||||
.checkPolygon("M 100,43.431458 L 170.71068,114.142136 L 100,184.85281 L 29.289322,114.142136 Z")
|
||||
.check();
|
||||
}
|
||||
|
||||
//*****************************************************************************************************
|
||||
|
||||
|
||||
|
@ -13,4 +13,11 @@ public class ContextTest extends TestCase {
|
||||
assertEquals(new Color(63, 127, 191), Context.readStyle(new Context(), "stroke:rgb(25%,50%,75%)").getStroke());
|
||||
}
|
||||
|
||||
public void testInkscape1() throws SvgException {
|
||||
Context c = Context.readStyle(new Context(), "fill:#000000;fill-opacity:0.5;stroke:none");
|
||||
assertNull(c.getStroke());
|
||||
assertEquals(new Color(0, 0, 0, 127), c.getFilled());
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user