[svgwg] Add circular arc path command 'R'. (#767)

tatarize has just created a new issue for https://github.com/w3c/svgwg:

== Add circular arc path command 'R'. ==
https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands

Also, note the SVG 2 requirement: 
"SVG 2 Requirement: | Make it simpler to draw arcs in SVG path syntax."
https://www.w3.org/2011/11/04-svg-minutes.html#item08
also,
https://www.w3.org/Graphics/SVG/WG/wiki/SVG2_Requirements_Input#Look_at_making_path_arcto_command_work_with_drawing_360_degree_arcs

Circular arcs are quite common and the current arc grammar is basically impossible to do by hand. Current arc grammar is also weird and atypical. However, if an arc is taken as *only* circular rather than elliptical much simpler grammars exist. Circular arcs don't need rx and ry and they don't need a rotation or the sweep flags etc. And most arcs you see in svgs are actually circular anyway. A/a is overbuilt for most uses.

The easiest and most consistent method, with regard to the other path commands is, would be to define the circular arc by three points. This would be the start point, an intermediate point, and an end point. This would be similar to the grammar of quad bezier curves, and all other path commands since all of them (except current arc) give you lists of points. Since we cannot break backwards compatibility we need to either add in a new command or modify a special case of 'A/a'. There's not a great way to modify that, so we introduce a new command. Arc has three letters and A is taken and C is taken and R works and reminds one of like `r` for radius.

`R x1,y1 ex,ey` and the relative lowercase form of 'r x1,y1 ex,ey` defines the smallest permitted circular arc touching the start, intermediate and end points.

With three defined non-coincident points there is 1 circle that goes through all three of those points. Any three non-coincident points define exactly one circle. The start point and end point are two of those three points. The third point is anywhere between them on the circular arc you're defining. Requiring the intermediate arc-point be between the on the arc, means we also define the sweep/arc. It tells us the direction of the sweep along the circle.

Special cases 1: If the three points defined are collinear, they simply define a line. And a line will be drawn from the start point to end point. This must also be the case in the error case where the intermediate point is both collinear and not a midpoint between the start and end point. Strictly speaking, this would happen if there were a circle with an infinite radius. 

Special case 2: coincident, start and end points. If the start point is coincident with the end point then *any* intermediate point defines an infinite number of circles. Except that we stipulate that we add the *smallest* arc. In the case of coincident start and end points, the smallest defined arc is a 360° arc with the intermediate position being exactly 180º away from the start/end position on defined circle. It is the case, however, that this defines 2 different circles namely a counter-clockwise circle and a clockwise circle full circle-arc. The preference is for the clockwise circle as that is the circle deconstruction preference. 

Special case 3: coincident start, end, and intermediate points. This defines nothing. It shall not add any segment. However, it might be used as a flag to, for example, toggle the directionality of special case 2, and make counterclockwise full circle arcs preferred. So `r0,0 0,0 r20,20 0,0` would define counterclockwise full circle arc.

Special case 4: coincident start and intermediate points, or coincident end and intermediate points. This is a special case of special case 1, as these points are also collinear. `r0,0 20,20` would likely define a line qua special case 1. Otherwise of unknown utility.

Advantages:  
1) Easy to define an arc by hand.
2) Provides coverage for most arcs actually used.
3) Almost all values are valid.
4) Can define full circular arcs.
5) All points given exist on the curve.
6) The intermediate point can be placed anywhere on the arc, allowing significant advantage markers.
7) Grammar consists entirely of points putting it in line with all other PathSegment grammars except A/a.
8) Allows easy path circles. `M20,20r0,50z` This clearly defines a circle with a center located at 20,45 with a radius of 25. `M0,0r0,50z` (path-closing-z) defines a circle with center located at 0,25 and radius of 25. Or rather draws a circle between the points 0,0 and 0,50. These circles have a clearly defined start position unlike the circle shape object deconstructions.
9) Circular arcs are found in gcode, hpgl, a lot of graphics libraries (where elliptical versions are not).
10) Except for 360 degree arcs, you could just convert the 'R' commands to A commands since because of backwards compatibility A/a commands will have to remain. And they'd easily feed into the already established rendering pipelines.


Other considerations:
The same smooth curve functionality of T and S would work for R. Where the next intermediate point is the reflection of the previous intermediate point. Which could use a command 'd/D' for raDius or sort of Diameter, and the letter 'D' sort of looks like the shape it'd be making.

---

Alternative 1: 2 points and radius. You can also define circle with 2 different non-coincident points and the radius of the circle. This defines 2 different circle and the clockwise or counterclockwise direction would denoted by the sign on the radius. However, this is hacky, and dissimilar to the other path commands. It does however exactly parallel one method for how gcode defines arcs.

Alternative 2: 2 points and the center point. You can define a circle with 2 points on the arc and a center point for the circle. This is another way gcode defines a circular arc. This is less hacky, and does not try to decide between two circles with the radius sign. It also makes the math easier. However, you could define invalid values. If the distance from p_end to p_center is different than the distance from p_start to p_center this actually defines something kind of broken.

Please view or discuss this issue at https://github.com/w3c/svgwg/issues/767 using your GitHub account

Received on Monday, 16 December 2019 03:13:58 UTC