I am trying to restore original graphic primitives from Postscript / SVG paths. Thus, an original circle is created (in SVG markup) as:
<path stroke-width="0.5" d="M159.679 141.309 C159.679 141.793 159.286 142.186 158.801 142.186 C158.318 142.186 157.925 141.793 157.925 141.309 C157.925 140.825 158.318 140.432 158.801 140.432 C159.286 140.432 159.679 140.825 159.679 141.309" />
This is an approximation using Bezier curves to create a circle. In other places, circular arcs are approximated by connected Bezier curves.
My question is whether there is an algorithm that I can use to recognize this construct and restore the βbestβ circle. I am not against small mistakes - in the worst case they will be second order.
UPDATE: Please note that I do not know a priori that it is a circle or an arc - it can be anything. And on the curve there may be 2, 3 4 or, possibly, even more points. Therefore, I would really like a function of this kind:
error = getCircleFromPath(path)
where error will give an early indication of whether it could be a circle.
[I agree that if I know this is a circle, this is a simpler problem.]
UPDATE: @george does some way to answer my problem, but I don't think this is the whole story.
After translation to the beginning and normalization, I see the following four points on the curve:
point [0, 1] with control point at [+-d,1] // horizontal tangent point [1, 0] with control point at [1,+-d] // vertical tangent point [0, -1] with control point at [+-d,-1] // horizontal tangent point [-1, 0] with control point at [-1,+-d] // vertical tangent
This ensures that the tangent at each point is "parallel" to the direction of the path at the point. It also guarantees symmetry (a 4-fold axis with reflection, but it does not guarantee a circle. For example, a large value of d will give a rounded box and a small value of a rounded diamond.
My d value is about 0.57. It could be 1 / sqrt (3.), or it could be something else. These are the relationships I ask for.
@george gives the midpoint of the arc as:
{p1,(p1 + 3 (p2 + p3) + p4)/8,p4}
therefore, in my example (from 1.0 to 0.1) it will be: [[1,0]+3[1,d]+3[d,1]+[0,1]] / 8 that is.
[0.5+3d/8, 3d/8+0.5]
and if d = 0.57, this gives 0.71, therefore, possibly d
(sqrt(0.5)-0.5)*8./3.
This is true for a square diamond, but for circular arcs the formula should be more general, and I would appreciate it if someone had it. For example, I am not familiar with Bezier's math, so @george's formula was new to me.
enter code here