ETOOBUSY 🚀 minimal blogging for the impatient
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:
x′1=−x′2=cos(ϕ)⋅x1−x22+sin(ϕ)y1−y22y′1=−y′2=−sin(ϕ)⋅x1−x22+cos(ϕ)y1−y22These 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 P′1, considering that our ellipse is centered in C′ in the new coordinate system (we will go back later, don’t worry!):
(x′1−C′x)2r2x+(y′1−C′y)2r2y=1Let’s multiply both ends by r2x⋅r2y and expand the two squares on the numerators of the fractions:
r2y⋅x′12−2⋅r2y⋅x′1⋅C′x+r2y⋅C′x2+r2x⋅y′12−2⋅r2x⋅y′1⋅C′y+r2x⋅C′y2=r2x⋅r2yLet’s not proceed for P2:
(−x′1−C′x)2r2x+(−y′1−C′y)2r2y=1(x′1+C′x)2r2x+(y′1+C′y)2r2y=1They are the same equations as before, only with a change of sign, so we get:
r2y⋅x′12+2⋅r2y⋅x′1⋅C′x+r2y⋅C′x2+r2x⋅y′12+2⋅r2x⋅y′1⋅C′y+r2x⋅C′y2=r2x⋅r2yHow about subtracting the first expansion from te one above? A lot of terms cancel out, leaving us with:
4⋅r2y⋅x′1⋅C′x+4⋅r2x⋅y′1⋅C′y=0r2y⋅x′1⋅C′x+r2x⋅y′1⋅C′y=0C′y=−r2yr2x⋅x′1y′1⋅C′xC′y2=r4yr4x⋅x′12y′12⋅C′x2Now we can substitute this in any of the two starting equations and get a second-degree equation in C′x only:
r2y⋅x′12−2⋅r2y⋅x′1⋅C′x+r2y⋅C′x2+r2x⋅y′12−2⋅r2x⋅y′1⋅C′y+r2x⋅C′y2=r2x⋅r2yr2y⋅x′12−2⋅r2y⋅x′1⋅C′x+r2y⋅C′x2+r2x⋅y′12+2⋅r2y⋅x′1⋅C′x+r2y⋅r2yr2x⋅x′12y′12C′x2=r2x⋅r2yr2y⋅(r2x⋅y′12+r2y⋅x′12r2x⋅y′12)⋅C′x2=r2x⋅r2y−(r2x⋅y′12+r2y⋅x′12)C′x2=r2x⋅r2y−(r2x⋅y′12+r2y⋅x′12)r2x⋅y′12+r2y⋅x′12⋅r2xr2y⋅y′12C′x2=(1(x′1rx)2+(y′1ry)2−1)⋅(rxry⋅y′1)2Similarly, we find the following for C′y2:
C′y2=(1(x′1rx)2+(y′1ry)2−1)⋅(ryrx⋅x′1)2We have to take a square root at this point… is it safe?
Ensuring that the solution is Real
Let’s call:
Λ=(x′1rx)2+(y′1ry)2We 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=(x′1k⋅rx)2+(y′1k⋅ry)2k2=(x′1rx)2+(y′1ry)2=Λk=√Λrx←√Λ⋅rxry←√Λ⋅rywhich 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):
Λ=(x′1rx)2+(y′1ry)2After 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.:
C′x=±√1Λ−1⋅rxry⋅y′1C′y=∓√1Λ−1⋅ryrx⋅x′1Whether we have to take the upper or the lower sign depends on the flags. In particular, if fA≠fS 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(ϕ)⋅C′x−sin(ϕ)⋅C′yCy=y1+y22+sin(ϕ)⋅C′x+cos(ϕ)⋅C′ySo… we are done with the center, next time we will address the parameters - but it will be easier.
Hopefully.