Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to mutate the coordinates of primitives? #31

Open
richrd opened this issue Jan 12, 2018 · 5 comments
Open

Is it possible to mutate the coordinates of primitives? #31

richrd opened this issue Jan 12, 2018 · 5 comments

Comments

@richrd
Copy link

richrd commented Jan 12, 2018

The readme states that mathematical translations could be added. I'd like to move paths by some delta coordinates e.g. move a path 30 units down. Is this currently possible?

EDIT: I'm also wondering why imaginary numbers are used?

@richrd
Copy link
Author

richrd commented Jan 12, 2018

I've been checking out the source code and it seems like there aren't any methods for directly manipulating paths or primitives. However it seems that adding a translate feature (to move the path by delta coordinates) wouldn't be so hard to implement.

My use case is for SVG normalization. I need to normalize paths that have a transform="translate(x,y) so that the transform is removed and applied to the coordinates of the path instead.

I might be able to make a pull request for this. Let me know what you think.

@regebro
Copy link
Owner

regebro commented Jan 13, 2018

Support for SVG transforms would make sense.
https://www.w3.org/TR/SVG11/coords.html#TransformAttribute
I'm not sure if this should be a part of svg.path, or if it should be a separate package svg.transform, that can make those calculations on any set of coordinates.

And imaginary numbers are used because they are good for doing coordinates. A Coordinate class that is an implementation/subclass of imaginary numbers could also make sense.

@richrd
Copy link
Author

richrd commented Jan 15, 2018

Nice to hear! I'd like to try and implement some function(s) that will take a path and move its coordinates by some delta.

The first set of functions could be for delta movement for each type of primitive. Then after that a general function could be written that takes a parsed path, iterates through the primitives and applies the relevant move functions to them, replacing the primitives with a transformed version and returning the new path.

I'm not sure how best to structure the code, but my intuition would say that each primitive could have its delta move method, which either modifies it in-place or returns a new primitive. Obviously an alternative is writing the transformations as separate functions instad of class methods.

Let me know what you think. I'd be willing to try to write an implementation for delta moving paths regardless of how the code is structured.

@regebro
Copy link
Owner

regebro commented Aug 14, 2018

I think it's definitely better to return a new primitive. I think separate functions probably makes more sense from an API perspective, but it might be best implemented by having helper transforms on the primitives themselves, not sure.

@tatarize
Copy link
Contributor

tatarize commented Sep 7, 2018

I rewrote some of the svgpathtools data to fix some issues where I thought all the extra sorts of parsing data was ugling it up.

https://github.com/tatarize/svgpathtools/blob/tatarize-decoupled/svgpathtools/svg_parser.py

I updated the path parsing to svg 2.0 with the new use of 'z' (which required get_pos() to be a function, and kinda made the whole thing a class). And kept all the dependencies clean. This does mean I simply parsed the svg transform without actually having a matrix. But, I also parsed the svg paths without an indication of where the parsing ends up.

The transformations actually have some really cool tricks with regard to complex numbers you can do a lot of the operations without matrices. To transform you simply add a complex number to your complex number points. To scale up you multiple by a real number, multiplying by 2 gives you 2x the shape. To rotate you multiply by a complex number that avoids scaling. For example, multiplying by i gives you a tau/4 rotation. I don't completely follow the logic on how to avoid the scaling effects ( https://betterexplained.com/articles/understanding-why-complex-multiplication-works/ ). SVG includes skewX and skewY and I'm not sure you can implement those directly with complex numbers but then I'm not great with the math at this level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants