Arc paths with rounded corners - svg

I'd like to draw an arc segment:
(90° here, but I want different arcs, for something like Fan Chart)
I can draw the arc (the yellow segment) fine with an a/A path segment, however, as soon as I want to round the corners, the arc (blue segment) isn't actually a full (circular) arc any longer, but is "flattened". Is there still any way to draw this part of the path with the a/A primitives, or should I just draw them in a separate path that allows me to set the center point correctly?

This must be explained with a bit of trigonometry. Consider the following three paths:
The first has the path definition (center of the arc at 0, 100).
d="M 0,100 H 80 A 80,80 0 0 0 0,20 z"
In the second one, the corners have been rounded with a radius of 15. To keep the connection of the small corner arcs with the larger arc smooth, the larger radius is reduced from 80 to 65. As you can see, the arc sits wide outside its original position.
d="M 0,100 H 65 A 15,15 0 0 0 80,85 65,65 0 0 0 15,20 15,15 0 0 0 0,35 Z"
In the third one, the connection is ignored and the radius kept at 80. Still, the position of the arc is too wide.
d="M 0,100 H 65 A 15,15 0 0 0 80,85 80,80 0 0 0 15,20 15,15 0 0 0 0,35 Z"
That is because the small corner arc is too far from the center of the large arc. For a visual construction, you would draw a circle with radius 15 inside the pie, and move it towards the corner until it meets both the straight line and the arc in a tangent. See the green circle:
It is meeting the arc to the right of the upper corner, and a bit lower. How much lower, you have to compute.
Suppose you want to round the corner with a radius of d=15. Then, the center of the circle sits at the intersection of the vertical line at x = d = 15 and the reduced arc with r₂ = r₁ - d = 65.
The angle α of a line from the inner corner to that point computes to
α = arcsin(d / r₂) = arcsin(15 / 65) = 13.342364°
The end point of the large arc then is at
x = cx + r₁ × sin(α) = 80 × sin(13.342364°) = 18.4615
y = cy - r₁ × cos(α) = 100 - 80 × cos(13.342364°) = 22.1593
The point where the rounded corner begins is at
x = cx = 0
y = cy - r₂ × cos(α) = 100 - 65 × cos(13.342364°) = 36.7544
After doing the same computation for the lower right corner, the final path computes to
d="M 0,100 H 63.25 A 15,15 0 0 0 77.85,81.54 80,80 0 0 0 18.46,22.15 15,15 0 0 0 0,36.75 Z"

Related

Fill non-convex SVG path

I have a non-convex region (made from several circle arcs) and want to fill the interior region with a color. However, the fill-property will instead fill the outside, as shown in the picture. How can I achieve the interiour being filled? This is an example code:
<path
id="curved_path"
style="stroke:#000000; stroke-width:0.2px; fill:none"
d="M 79, 66 c 0,0 -17,0 -17, 15
M 45, 66 c 0,0 17,0 17, 15
M 79, 66 c 0,0 -17,0 -17,-15
M 45, 66 c 0,0 17,0 17,-15"
/>
Eventually, I want to write a script which draws a large number (possibly millions) of these curved polygons. If this turns out complicated in SVG, are there other languages or scriptable tools that can handle these problems better?
All those M commands create separate subpaths which are filled independently. You need to draw the star as one continuous path:
<svg width="350" height="300" viewBox="45,51 35,30">
<path id="curved_path"
style="stroke:#000000; stroke-width:0.2px; fill:dodgerblue"
d="M 79,66 c 0, 0 -17, 0 -17, 15
c 0,-15 -17,-15 -17,-15
c 0, 0 17, 0 17,-15
c 0, 15 17, 15 17, 15"
/>
</svg>

Drawing a partial circle with path

I'm trying to draw a partial circle with svg's path. I have the circle center coordinates, radius and the start/end coordinates (where the partial circle will end), but I can't wrap my head around on how to draw the circle.
I hope that this small example can help you. The path starts in 50%,50% (center), moves to 50%,0 (that is 12 o'clock), creates an arc where radius x and y are 50 (the fist two numbers after a) and ends in the position that is a calculation with sin() and cos() on 45 degrees (the angle should be in radians). The three numbers in between (0 0 1) are flags.
See more here: d - Elliptical Arc Curve
// 45 deg:
console.log(Math.cos(Math.PI/4)*50, 50-Math.sin(Math.PI/4)*50);
document.querySelector('path')
.setAttribute('d', `M50,50 L50,0 a 50 50 0 0 1 ${Math.cos(Math.PI/4)*50} ${50-Math.sin(Math.PI/4)*50} z`);
<svg width="200" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" fill="lightblue" />
<path fill="navy" />
</svg>

I have a text file of a grid that has x y z coordinates and varying lengths of the sides of the cells(sx, sy and sz)

I have a text file of a grid that has x y z coordinates (of cell centers and are in UTM) and varying lengths of the sides of the cells(sx, sy and sz). The points are random points. I would like to plot this in Python. Can anyone offer any suggestions?
x y z sx sy sz
584597 1848923 210 143 53 143
584885 1848927 210 143 62 143
585173 1853185 210 143 224 143
As far as how? I would start by:
1) using readline, you split each by the " "(space) values
2) create dict with a for loop, and setting the key.. x y z etc...
3) ?? You say you want to plot but since I don't know the end game here; I imagine matploit should be the goto forgraphical plotting
4) As to the other variables, the non-coordinantes, it's up to you in how you want to correlate/express these values.

How to Fill and Stroke the SVG rectangle with corners with negative radius?

I need to create a block with specific borders around it:
I want to have this block scalable, that is why I try doing it with svg.
Here is what I've done:
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none slice" viewBox="0 0 300 400">
<path stroke-width="1" stroke="#7DD37D" fill="red" d="
M20 0h260
m20 20v360
m-20 20H20
m-20 -20V20
M0 20a20 20 0 0 0 20 -20
M300 20a20 20 0 0 1 -20 -20
M300 380a20 20 0 0 0 -20 20
M0 380a20 20 0 0 1 20 20" id="path"/>
</svg>
Demo on codepen
The border was created as path from lines and arcs.
The problem is, that I can't make svg to fill the area inside this path. It fills some space inside arcs instead of rectangle. What I'm doing wrong?
When I do something similar with Inkscape, the resulting path is combined from lines and Cubic Bezier curves. Can it be done with simple arcs instead of Bezier curves?
Each time you use a move ('m' or 'M') path command, it creates a new subpath. Each subpath gets filled, not the whole thing.
If you want the whole thing filled, it has to be a continuous path. In other words, in this case, it should be a move followed by a line, then an arc, then another line, and arc, and so on until you have completed all four sides of the shape.

Draw a voided shape in SVG

I want to draw a shape in SVG that has the centre hollowed out.
I asked this question for drawing a circle with a circle in the middle here.
I would like to draw any shape in SVG with the middle (of another shape) hollowed out.
Any ideas?
I'm thinking it could be possible using Masks or ClipPaths but I'm not sure if I understand them fully
Create your shape as a path, which consists of two sub-paths. The first subpath describes your outer shape; the second subpath describes the inside shape. Set the fill-rule of the pathto 'evenodd'.
e.g. for a hollowed out rectangle, we make a path consisting of two sub-paths. One for the outside rectangle; one for the inner rectangle:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<path d="M 100 100 L 200 100 L 200 200 L 100 200 z
M 110 110 L 190 110 L 190 190 L 110 190 z"
fill="red"
stroke="black" stroke-width="1"
fill-rule="evenodd"/>
</svg>

Resources