How can I calculate the size of a circle from a set of arcs?
Specifically, I have this SVG path definition which draws a circle, I'm looking to work out its size.
<path clip-path="url(#SVGID_2_)" fill="#99C44C" d="M334.293,56.846c0-4.782,3.88-8.659,8.665-8.659c4.78,0,8.66,3.877,8.66,8.659
c0,4.783-3.88,8.661-8.66,8.661C338.173,65.507,334.293,61.629,334.293,56.846"/>
For your information, the circle is drawn in the 'd' attribute. M334.293,56.846 moves to this x,y position, then the c commands are curves.
Curves:
Draws a cubic Bézier curve from the current point to (x,y) using (x1,y1) as the control point at the beginning of the curve and (x2,y2) as the control point at the end of the curve. C (uppercase) indicates that absolute coordinates will follow; c (lowercase) indicates that relative coordinates will follow.
relative curves
c0-4.782,3.88-8.659,8.665-8.659
c4.78,0,8.66,3.877,8.66,8.659
c0,4.783-3.88,8.661-8.66,8.661
absolute curve
C338.173,65.507,334.293,61.629,334.293,56.846
At this juncture you have two possibilites:
You can treat the bezier curve as a circle (which is, as commented, wrong; it's just really circle-looking). To calculate the area, determine the radius and use π * r^2 as usual.
If you want to calculate generally the area enclosed by a path element; that requires some moderate calculus, and is not for the faint of heart.
Related
Given two points and a control point, one can easily draw a bezier path between the two points. What I would like to do use a bezier curve to draw a path that with changing width, by a assigning a "weight" to a the points of the curve which will determine its width. For example, if I give weight=0 to the first point of the curve and weight = 1 to the second point of the curve then something like the following path should be generated (the curve in the picture is cubic, but I am working with quadratic bezier curves):
In order to do this I would need to find the control points of the "edge" curves that determine the shape and then fill the shape that is found between the two new curves. However, I am quite unsure on how this can be done. One thing I thought about was to determine the starting and ending points of the new curves by simple drawing perpendicular segments to the line connecting the original control point and the original end points, but this still doesn't solve the problem of finding the new control points for the new curves.
I would use cubics instead of quadratics.
Yes you offset the control points perpendicularly by your weight but not the control points of BEZIER but control points of interpolation cubic (or catmull-rom) and then just convert that into Bezier control points. See related QAs:
How can i produce multi point linear interpolation?
How to create bezier curves for an arc with different start and end tangent slopes
draw outline for some connected lines
However much easier would be to directly render curve using Shaders and (perpendicular) distance. See:
Draw Quadratic Curve on GPU
That way you would not need to offset anything just interpolate the width of your curve ...
Maybe this could help, also there is an example on variable offseting
https://microbians.com/mathcode
I have a straight line which intersects a convex polygon in 2D plane. There exists a circle with constant radius. The center of circle is moving on this line. So at first the polygon and circle don't intersect with each other, as the circle gets closer to the polygon the intersection increases and then decreases as they go further from each other. I want to prove the area of the intersection of the convex polygon and circle doesn't have local minima(as the circle moves on the line).
Interesting problem. Please post solution once you find it. My approach would be to take a similar route to Fortunes algorithm to build a Voronoi graph - meaning I would consider "events" that are happening when the circle traverses a convex polygon.
Basically to better understand the problem, consider the restriction that the circle is traveling on straight line - why is that important - look at counter examples. Then look when will this fail if poly is not convex?
The events that I would consider would be an entry/exit of a poly vertex into circle, and entry exit of an poly edge from/into the circle. Then keep track of area increasing or decreasing through each event, and show that it is necessarily monotonic.
I am doing a project on the TSP on the surface of the sphere. I would like to illustrate the method uniformly distributing points to the surface of the sphere, i.e. filling a cube with uniform (x,y,z) points with the restriction that x^2+y^2+z^2 > 1 and then dividing each radius vector by it's magnitude. I can plot the points along with the sphere but how do I go about specifying a radial vector to each point in gnuplot? Also, how does one specify a line to run through the points in their order? (The chosen path).
When a polygon gets rotated it skips all possible rotations in between the current and the desired situation. Here are 3 images illustrating what I mean:
This is the current polygon:
Rotating it 45 degrees (in clockwise direction) would result in:
The current polygon rotated by 45 degrees in clockwise direction, with all possible situations in between would result in:
How are these "sleeves" (in-between situations) actually called, and how are these "complete polygons" calculated/approximated based on the current polygon and desired angle of rotation?
In the CAD industry, we would call this operation a 2d sweep, or a 2d planar sweep; in this case a 2d planar rotational sweep. (Not to be confused with a sweep line algorithm.) The resulting area would be the 2d swept area or 2d swept face, and the outline called the 2d swept boundary.
A couple of papers on the topic can be found here:
Polygonal boundary approximation for a 2D general sweep based on envelope and boolean operations (2000) (another link, and a direct PDF Link.)
Approximate General Sweep Boundary of a 2D Curved Object (1993).
Your case of a 2d rotational sweep is not as general as the cases considered in these papers. If you think about sweeping just a single curve -- a line or an arc, say -- then the boundary curves of the swept area in 2d will as follows. Imagine sweeping the curve in 3d, where the curve is simultaneously extruded along the axis of rotation as it is rotated around the axis. In that case, the boundaries of your 2d sweep would be the boundaries of the 3d swept surface projected back to 2d plus the 3d silhouettes of the swept surface projected back into 2d, taking the axis of rotation as the view vector for silhouette creation.
Computing silhouettes of general surfaces is nontrivial, but for a rotational sweep + extrusion along the axis of rotation the silhouettes will be traced out by points where the tangent of the swept curve is parallel to the direction of rotation -- i.e., perpendicular to the radius vector drawn out from the center of rotation. Thus an algorithm to compute your 2d area might look like:
For each edge segment of the area to be rotationally swept,
Split the edge where the tangent becomes parallel to the direction of rotation.
Exclude any degenerate curves -- arcs that are coaxial with the axis of rotation.
For each split edge segment, form a 2d area comprised of the start position of the curve, the end position of the curve, and the start and end points connected by arcs. Since we split at the silhouette points, there should be no self intersections.
Do a 2d boolean of the 2d area in its start position, its end position, and the swept areas created in the first steps.
Looking at Convert a quadratic bezier to a cubic?, I can finally understand why programming teachers always told me that math was so important. Sadly, I didn't listen.
Can anyone provide a more concrete - e.g., computer-language-y - formula for converting a quadratic curve to a cubic? Understanding that there's some rounding errors possible, which is fine.
Given a quad curve represented by variables:
StartX, StartY
ControlX, ControlY
EndX, EndY
And desiring StartX, StartY and EndX, EndY to remain the same, but to now have Control1X, Control1Y and Control2X, Control2Y of a cubic curve.
Is it...
Control1X = StartX + (.66 * (ControlX - StartX))
Control2X = EndX + (.66 * (ControlX - EndX))
With the same essential functions used to calculate Control1Y and Control2Y?
Your code is right except that you should use 2.0/3.0 instead of 0.66.
You avoid most rounding errors by using
Control1 = (Start + 2 * Control) / 3
Control2 = (End + 2 * Control) / 3
Note that line segments are also convertible to cubic Bezier curves using:
Control1 = Start
Control2 = End
This can be handy when converting a complex path mixing various types of curves (linear, quadratic, cubic).
There's also a basic transform for converting elliptic arcs to cubic (with some minor unnoticeable errors): you just have to split at least the arc on elliptic quadrans (cutting the ellipse first on the two orthogonal axis of symetries, or on arbitrary orthogonal axis passing through the center if the ellipse is a circle, then representing each arc; when the ellipse is a circle, the two focal points are confused on the same point, the center of the circle, so you can use any direction for one of the orthogonal axis).
Many SVG renderers do that by adding an additional split on octants (so that you get also precise position not only for points where the two main axis are passing through, but also for two diagonal axis which are bissecting (when the ellipse is a circle) each quadrant (when the ellipse is not a circle, assimilate it as a circle flattened with a linear transform along the small axis only, you do the same computation), because octants are also quite precisely positioned:
cos(pi/4) = sin(pi/4) = sqrt(2)/2 ≈ 0.71, and because this additional splitting will allow precise rendering of tangents on points crossing the diagonals at 45 degrees of the circle.
A full ellipse is then converted to 8 cubic arcs (i.e. 8 points on ellipse and 16 control points): you'll almost not notice the difference between elliptical arcs and these generated cubic arcs
You can create an algorithm that uses the same "flattening error" computed when splitting a Bezier to a list of linear segments, which are then drawn using the classic fast Bresenham algo for line segments; a "flattenning" algorithm just has to measure the relative deviation of the sum of lengths of the two straight segments joining the two focal points of the ellipse to any point of the generated cubic arcs, as this sum is constant on any true ellipse: if you make this measurement on the generated control points for the cubic arcs, the difference should be below a given percentage of the expected sum, or within an absolute distance precision, and can be used to create better approximation of control points with a simple linear formula so that these added points will be on the real ellipse.
Such transform of arbitrary paths is useful when you want to derive other curves from the path, notably the curves of "buffers" at a given distance, notably when these paths must be converted to "strokes" with a defined "stroke width": you need to compute two "inner" and "outer" curves and then concentrate on how to converting the miters/buts/squares/rounded corners, and then to cut long miters at a convenient distance (matching the "miter limit" factor times the "stroke width").
More advanced renderers will also use miters represented by tangent circles when there's a corner between two arcs instead of two segments (this is useful for drawing cute geographic maps)...
Converting an arbitrary path mixing segments, elliptic and bezier arcs to only cubic arcs is a necessary step to compute precise images without excessive defects visible when zooming in. This is then necessary when your "stroke" buffers have to take some effects (such as computing dashes), and then enhancing the result with semi-transparent pixels or subpixels to smooth the rendered strokes (smoothing is easy to computez only when everything has been flattened to line segments, and alsos may be simpler to develop if it only has to manage paths containing only cubic beziers: it can easily be parallelized if needed and accelerated by hardware). Bezier arcs are always interesting because drawing them is fast and requires only basic arithmetics, and the time needed to draw them is proportional to the length of the curve with every point drawn with the same accuracy level.
In summary, all curves are representable by cubic Bezier arcs with a maximum measurable deviation allowed (you can set this maximum deviation to one half pixel, or one subpixel if you first scale up the measurement grid for half-toning or subpixel shading, and then represent accurately every curve with a reasonnaly fast rendering, and get accurate rendering at any zoom level with curves smoothed everywhere, including with half-toning or transparency levels when finally drawing the linear strokes with the classic Bresenham algorithm using fast integer-only arithmetics). These rendered curve will all have the correct tangeants everywhere, without any unexpected angles visible on approximation points, and the remaining control points in the approximation will make also a good smooth rendering of the curvature everywhere (i.e. radius of the tangeant circle), so you can use this approximation as well to derive other measurements such as acceleration, inertial forces, or magnetic effects of paths of charged particles).
If you ever need higher precision, use Bezier arcs with degree 4 (i.e. with 3 control points between points on curve) to get smoothed derivation at a supplementary degree (e.g. gradients of forces), or just split the cubic arcs with additional steps further, until the derivation is smooth enough (but using degree-4 Bezier arcs requires much less points curves and less control points for the same accuracy tolerances, than when using cubic Bezier only).