From 9670db0064c81ed9dfd7d5184711a28aa8d5cf37 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 9 Nov 2014 11:38:49 -0500 Subject: Add special rotation solution to optimized transforms, found by Johan (bzr r13691) --- src/svg/svg-affine-test.h | 7 ++++--- src/svg/svg-affine.cpp | 18 +++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/svg/svg-affine-test.h b/src/svg/svg-affine-test.h index 6d8387328..af670a3a8 100644 --- a/src/svg/svg-affine-test.h +++ b/src/svg/svg-affine-test.h @@ -35,7 +35,7 @@ private: static test_t const write_matrix_tests[2]; static test_t const write_translate_tests[3]; static test_t const write_scale_tests[3]; - static test_t const write_rotate_tests[2]; + static test_t const write_rotate_tests[3]; static test_t const write_skew_tests[3]; public: SvgAffineTest() { @@ -242,9 +242,10 @@ SvgAffineTest::test_t const SvgAffineTest::write_scale_tests[3] = { {"scale(0)",Geom::Affine(0,0,0,0,0,0)}, {"scale(7)",Geom::Affine(7,0,0,7,0,0)}, {"scale(2,3)",Geom::Affine(2,0,0,3,0,0)}}; -SvgAffineTest::test_t const SvgAffineTest::write_rotate_tests[2] = { +SvgAffineTest::test_t const SvgAffineTest::write_rotate_tests[3] = { {"rotate(13)",Geom::Affine(cos(13.*DEGREE),sin(13.*DEGREE),-sin(13.*DEGREE),cos(13.*DEGREE),0,0)}, - {"rotate(-13,7,11)",Geom::Affine(cos(-13.*DEGREE),sin(-13.*DEGREE),-sin(-13.*DEGREE),cos(-13.*DEGREE),(1-cos(-13.*DEGREE))*7+sin(-13.*DEGREE)*11,(1-cos(-13.*DEGREE))*11-sin(-13.*DEGREE)*7)}}; + {"rotate(-13,7,11)",Geom::Affine(cos(-13.*DEGREE),sin(-13.*DEGREE),-sin(-13.*DEGREE),cos(-13.*DEGREE),(1-cos(-13.*DEGREE))*7+sin(-13.*DEGREE)*11,(1-cos(-13.*DEGREE))*11-sin(-13.*DEGREE)*7)}, + {"rotate(-34.5,6.7,89)",Geom::Affine(cos(-34.5*DEGREE),sin(-34.5*DEGREE),-sin(-34.5*DEGREE),cos(-34.5*DEGREE),(1-cos(-34.5*DEGREE))*6.7+sin(-34.5*DEGREE)*89,(1-cos(-34.5*DEGREE))*89-sin(-34.5*DEGREE)*6.7)}}; SvgAffineTest::test_t const SvgAffineTest::write_skew_tests[3] = { {"skewX(30)",Geom::Affine(1,0,tan(30.*DEGREE),1,0,0)}, {"skewX(-30)",Geom::Affine(1,0,tan(-30.*DEGREE),1,0,0)}, diff --git a/src/svg/svg-affine.cpp b/src/svg/svg-affine.cpp index af58c4544..c853f9930 100644 --- a/src/svg/svg-affine.cpp +++ b/src/svg/svg-affine.cpp @@ -217,29 +217,29 @@ sp_svg_transform_write(Geom::Affine const &transform) c[p++] = ')'; c[p] = '\000'; - /* } else if (transform.withoutTranslation().isRotation()) { - // FIXME someone please figure out if this can actually be done - // The rotation angle is correct, the points are not + } else if (transform.withoutTranslation().isRotation()) { + // Solution found by Johan Engelen // Refer to the matrix in svg-affine-test.h // We are a rotation about a special axis strcpy(c + p, "rotate("); p += 7; - Geom::Affine const sans_translate = transform.withoutTranslation(); - double angle = std::atan2(sans_translate[1], sans_translate[0]) * (180 / M_PI); + double angle = std::atan2(transform[1], transform[0]) * (180 / M_PI); p += sp_svg_number_write_de(c + p, sizeof(c) - p, angle, prec, min_exp); c[p++] = ','; - Geom::Point pt = transform.translation(); - p += sp_svg_number_write_de(c + p, sizeof(c) - p, pt[Geom::X], prec, min_exp); + Geom::Affine const& m = transform; + double tx = (m[2]*m[5]+m[4]-m[4]*m[3]) / (1-m[3]-m[0]+m[0]*m[3]-m[2]*m[1]); + p += sp_svg_number_write_de(c + p, sizeof(c) - p, tx, prec, min_exp); c[p++] = ','; - p += sp_svg_number_write_de(c + p, sizeof(c) - p, pt[Geom::Y], prec, min_exp); + double ty = (m[1]*tx + m[5]) / (1 - m[3]); + p += sp_svg_number_write_de(c + p, sizeof(c) - p, ty, prec, min_exp); c[p++] = ')'; - c[p] = '\000';*/ + c[p] = '\000'; } else if (transform.isHShear()) { // We are more or less a pure skewX strcpy(c + p, "skewX("); -- cgit v1.2.3