fixed a bug in matrix multiply

This commit is contained in:
hneemann 2018-12-03 21:39:25 +01:00
parent 1e3c6ee806
commit 402a38387f
6 changed files with 94 additions and 30 deletions

View File

@ -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);
}

View File

@ -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);
}
/**

View File

@ -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) {

View File

@ -20,7 +20,7 @@ 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() {
@ -65,4 +65,30 @@ public class TransformMatrixTest extends TestCase {
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);
}
}

View File

@ -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();
}
//*****************************************************************************************************

View File

@ -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());
}
}