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

Add Polar coordinate syntaxe to path data #2

Open
JeremiePat opened this issue Oct 3, 2019 · 4 comments
Open

Add Polar coordinate syntaxe to path data #2

JeremiePat opened this issue Oct 3, 2019 · 4 comments

Comments

@JeremiePat
Copy link

JeremiePat commented Oct 3, 2019

Hi Community group,

Along my recent use of SVG, I feel more en more uncomfortable with SVG not having a polar coordinate system in addition to the current Cartesian coordinate system. Polar coordinates are amazingly useful to create regular shapes like euclidean polygons, organic shapes like flowers/trees or when handling some cartography use-cases such as polar maps.

It is pretty straight forward (not to said trivial) to convert from one system to the other and many libs exist to handle that (some examples: JS, Rust…)

I would suggest to extend the syntax of path to support polar coordinates. As both 2D Cartesian and polar coordinates are tuples of 2 numbers ([x/y] for Cartesian, [theta/distance] for polar with theta express in degrees) I would love to have a simple modifier to the current syntax of path command. My personal preference would be to add the support for parenthesis inside path syntax to identify tuple of coordinates that are polar coordinates (as an easy short cut for developer, parentheses could also be allowed to wrap several tuple at the same time).

For example:

Cartesian Polar
M10,10 M(45,14.14)
M10,10 0,10 m(45,14.14 90,10) same as m(45,14.14) (90,10)
m10,10 10,10 m(45,14.14 45,14.14) same as m(45,14.14) (45,14.14)
A5,5 0,0,0 10,10 A(5,5 0,0,0 45,14.14) same as A5,5 0,0,0 (45,14.14)

Also mixed tuples should be okay:
m10,10 10,10= m10,10 (45,14.14) = m(45,14.14) 10,10 = m(45,14.14 45,14.14) = m(45,14.14) (45,14.14)

Okay, what about syntax error. I would be in favor of having some fallback rules rather than just discarding all or part of the path in case of error with the parenthesis (either matching issues or misplacement)

Here are some possible fallback rules in case of error or ambiguous syntax

Wrong Various suggested fix at parsing (my own preference in bold)
1 M(45,14.14 l10,10 l10,10 M(45,14.14) l10,10 l10,10 or M(45,14.14) l(10,10) l(10,10)
2 M45,14.14 l10,10) l10,10 M45,14.14 l(10,10) l10,10 or M(45,14.14) l(10,10) l10,10
3 M(45,14.14 l10,10 l10,10) M(45,14.14) l10,10 l(10,10) or M(45,14.14) l(10,10) l(10,10)
4 M45(14.14) l10,10 l10,10 M45 14.14 l10,10 l10,10 (Not a valid tuple, just ignore the parenthesis)
5 M45 (14.14 10) 10 M45 14.14 10 10 (Still not a valid tuple, just ignore the parenthesis)
6 M45 (14.14 10 10) M45 14.14 10 10 or M45 14.14 (10 10)

Such syntax error can be handled either at a global level or at tuple/command level. My own preference is to handle that at the tuple/command level. I think it should ease parsing if it's handle at that level (but I'm far from a parser expert). However from my point of view it's more an author concern as it's clearer at which level things operate when they handle path either "by hand" or programmatically.

Let me know it is worth of interest and/or if you have other ideas on how to add Polar coordinates to SVG :)

@BigBadaboom
Copy link

There is a proposal for a "Bearing" (B) command in the path syntax. Have you seen that?

https://svgwg.org/specs/paths/#PathDataBearingCommands

Would that suit your use cases?

@JeremiePat
Copy link
Author

JeremiePat commented Oct 4, 2019

The "Bearing" command is very interesting and it allows to somewhat mimic polar coordinates, which allows to covers some of the use cases I mentioned.

But it is significantly different than a true polar coordinates system. Polar coordinates are meant to define individual point coordinates in the 2D plan where Bearing is a way to rotate the whole subsequent coordinates system of a path definition. The former is a single vector operation where the latter is a global transformation that impact all subsequent vector operations.

Because of that different behavior, B command isn't sharp enough for some cases. For example, when dealing with Bézier curve command it can be handy to mix both Cartesian and polar coordinates, especially in their relative form: c(45,10) (30,20) 30,0 (polar for control point, Cartesian for end point… okay the 2nd control point is still hard to figure, but less hard than with Cartesian coordinates)

That say, mixing both B command and polar coordinates could be a nice easy way to draw spirals (which is currently unbearable with SVG): polar coordinates are easier to define the starting point of a spiral arc based on a center points where B commands are easier to draw relative subsequent segments of such arc (I'm thinking out loud here and it would worth deeper investigation)

@derrickoswald
Copy link

Rather than parenthesis, would it satisfy the use-cases to use an @ or < character in place of the comma to separate a distance and an angle instead of x and y? So assuming degrees as the angular unit,
M 3,4 would become M [email protected]
M 2,2 would become M 2.828427125<45

For the relative commands, it would be relative to the current point, rather than absolute position.

I'm not sure what the specification says about a missing second number (after a comma), but if no angle was supplied, it could imply tangent to last segment or curve, so
M 2,2 2@ would draw a line 4.828427125 long at 45°

@BigBadaboom
Copy link

BigBadaboom commented Oct 31, 2019

M 2,2 2@ would draw a line 4.828427125 long at 45°

Why 45deg? Are you assuming a previous point of 0,0? An M at the start of a path establishes the first "current point". So I would think that a missing angle there would either be invalid, or would have to default to something like 0deg.

Also, the 2 in "2@" would be a length, going by your previous examples, correct? So it wouldn't be a line "2 long"?

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

No branches or pull requests

3 participants