8

I am using wxPython to prototype some display interfaces for a project that will eventually become an embedded design. Since we are iterating with a graphics designer, it is much easier to let them work in a WYSIWYG editor like Inkscape than constantly rewrite 2D graphics drawing calls. For elements that need animation or dynamic text, the SVG elements are easily identifiable by ID so that they can be programatically updated before rendering. The rendering flow looks like this:

Inkscape SVG as XML --> Python modification of XML --> Drawing onto wxPython buffered canvas using Cairo and pyRSVG

I'd like to animate a pivoting needle around a fixed axis for a gauge. To define a needle, the graphics designer draws the graphical "needle" and a "needle_axis" element which is a small circle. Then, I thought I could set the transform property using the desired angle and the center coordinates of the "needle_axis." However, since the relative positions could have been affected because of other transforms, determining the absolute location of the rotation axis is non-trivial.

I cannot seem to find a Python library for determining absolute coordinates of an element, and it feels like reinventing the wheel to try an implement the part of the SVG spec. necessary to calculate it. The rsvg API mentions rsvg_handle_get_dimensions_sub and arsvg_handle_get_position_sub functions to get the dimensions and positions of elements, but I can't find an API for pyRSVG.

Is there a better way to find the rotation axis than manually calculating it? An example Inkscape SVG file and test snippet are available as a gist.

1
  • Trying to do something similar, found a Python Extension library function simpletransform.py - but it's in the Deprecated folder of my installed InkScape, and couldn't be imported (without a lot of work).
    – John C
    Commented Feb 3, 2022 at 1:55

1 Answer 1

-1

If I understood correctly, you have the needle's coordinates and the rotation axis coordinates, and you want to programatically change the needle's "angle" and then change the needle's shape in the SVG file accordingly?

I think this is a really bad idea: making changes to the SVG, saving and then rendering the "new SVG" will take too much ressources and is exactly why such a simple task seems complicated.

Instead, parse your SVG once (using lxml for instance, it's a piece of cake to extract coordinates just by doing some XPATH queries) and build your shapes into a model (a Needle class for instance, with the paths and center) and then simply rotate that needle using Cairo transforms. They already provide a rotate function that will do what you're looking for!

3
  • Could you provide more detail on how to extract the coordinates? I actually started doing something along those lines but realized I'd have to re-implement all of the SVG specification with regards to transformations and absolute/relative coordinates. I'm actually getting "good enough" framerates by just modifying the SVG XML between frames. This avoids this file I/O which helps but still seems dirty since it involves pyRSVG reparsing the entire tree every frame.
    – superlou
    Commented Aug 2, 2013 at 0:18
  • It is true that you could have some issues if your SVG software doesn't "apply" transformations on the coordinates and leaves them as SVG transformations intead. But I think that you can force the opposite behavior on Inkscape. Then you'll "just" have to build a Cairo path (cairographics.org/manual/cairo-Paths.html) from the SVG path. Not that hard but you'll still have to read the SVG specs about paths: w3schools.com/svg/svg_path.asp
    – halflings
    Commented Aug 2, 2013 at 11:16
  • You can force Inkscape to export without using relative coordinates, but I have not found an option to prevent using transforms under all situations. I agree that it would be better to get the SVG data into Cairo paths or some object responsible for generating the Cairo paths, but will leave the question open since I don't think there should have to be "roll-your-own" translation code for everybody who needs this functionality.
    – superlou
    Commented Aug 6, 2013 at 12:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.