Ellipses (for SVG): finding the center

TL;DR

Our first step will be finding the ellipse’s center from the SVG representation of the ellipse.

As anticipated, Appendix B of the proposed standard already contains all needed maths for our purposes, we’ll just elaborate a bit to explain a few passages. In particular, we will start from Conversion from endpoint to center parametrization.

The first move is to translate our coordinates system to the midpoint between our known points P1 and P2. Why does this simplify the equations?

After the translation, the two points will be at opposite ends of the new origin. For this reason, their coordinates will be equal in absolute value, and opposite in sign. This basically means dealing with two less values (there’s only some fiddling with signs) and get way simpler equations.

After this translation, a rotation is performed to set a new coordinates system that as the new X axis parallel to the x direction in the ellipse. This means that our new coordinates system is rotated by ϕ with respect to the old one. Note that this rotation does not change the relative position of P1 and P2: they still land on opposite places with respect to the origin, so the property in the previous paragraph are preserved.

After this translation-then-rotation, we end up with the following new coordinates for the two points:

x1=x2=cos(ϕ)x1x22+sin(ϕ)y1y22y1=y2=sin(ϕ)x1x22+cos(ϕ)y1y22

These two points belong to the ellipse, so they have to fit in any of the representation. Let’s use the implicit one and put the values for the new point P1, considering that our ellipse is centered in C in the new coordinate system (we will go back later, don’t worry!):

(x1Cx)2r2x+(y1Cy)2r2y=1

Let’s multiply both ends by r2xr2y and expand the two squares on the numerators of the fractions:

r2yx122r2yx1Cx+r2yCx2+r2xy122r2xy1Cy+r2xCy2=r2xr2y

Let’s not proceed for P2:

(x1Cx)2r2x+(y1Cy)2r2y=1(x1+Cx)2r2x+(y1+Cy)2r2y=1

They are the same equations as before, only with a change of sign, so we get:

r2yx12+2r2yx1Cx+r2yCx2+r2xy12+2r2xy1Cy+r2xCy2=r2xr2y

How about subtracting the first expansion from te one above? A lot of terms cancel out, leaving us with:

4r2yx1Cx+4r2xy1Cy=0r2yx1Cx+r2xy1Cy=0Cy=r2yr2xx1y1CxCy2=r4yr4xx12y12Cx2

Now we can substitute this in any of the two starting equations and get a second-degree equation in Cx only:

r2yx122r2yx1Cx+r2yCx2+r2xy122r2xy1Cy+r2xCy2=r2xr2yr2yx122r2yx1Cx+r2yCx2+r2xy12+2r2yx1Cx+r2yr2yr2xx12y12Cx2=r2xr2yr2y(r2xy12+r2yx12r2xy12)Cx2=r2xr2y(r2xy12+r2yx12)Cx2=r2xr2y(r2xy12+r2yx12)r2xy12+r2yx12r2xr2yy12Cx2=(1(x1rx)2+(y1ry)21)(rxryy1)2

Similarly, we find the following for Cy2:

Cy2=(1(x1rx)2+(y1ry)21)(ryrxx1)2

We have to take a square root at this point… is it safe?

Ensuring that the solution is Real

Let’s call:

Λ=(x1rx)2+(y1ry)2

We can easily see that values of Λ greater than 1 will give us trouble, because our squared coordinates for the center would become negative, yielding non-Real values for the center’s coordinates.

At this point, the standard tells us to enlarge the ellipse (keeping the aspect ratio) until it’s necessary, i.e. until our Λ goes down to exactly 1. This means multiplying both rx and ry by a factor $k so that the following applies:

1=(x1krx)2+(y1kry)2k2=(x1rx)2+(y1ry)2=Λk=ΛrxΛrxryΛry

which is exactly what is suggested in section Correction of out-of-range radii. This might happen, most probably, due to some numerical approximation, so the value of the correction should not be too big.

CAVEAT the group of transformations above only applies when Λ>1, it should be ignored otherwise!

The much sought result

Let’s calculate (again):

Λ=(x1rx)2+(y1ry)2

After the check in the previous section, we’re now sure that Λ1, so it’s safe to take the square roots.

For reasons that are left as a simple exercise for the reader (i.e. I’m too bored to look at), we have to take opposite signs for the two coordinates, i.e.:

Cx=±1Λ1rxryy1Cy=1Λ1ryrxx1

Whether we have to take the upper or the lower sign depends on the flags. In particular, if fAfS then we take the upper sign (positive for the X coordinate, negative for the Y coordinate), otherwise we take the lower one.

The last thing to do is to go back to our original coordinates system, i.e. revert the rotation and then the translation. We obtain:

Cx=x1+x22+cos(ϕ)Cxsin(ϕ)CyCy=y1+y22+sin(ϕ)Cx+cos(ϕ)Cy

So… we are done with the center, next time we will address the parameters - but it will be easier.

Hopefully.


Comments? Octodon, , GitHub, Reddit, or drop me a line!