Related:
- Calculating the height of a circular segment at all points provided only chord and arc lengths - but this doesn't care about height, and doesn't have the arc-angle as a given
- Finding out an arc's radius by arc length and endpoints - pretty close, but I do not have the same 180° constraint, and I need offset angles for both endpoints in the chord, not just the angle between them
The not-particularly-relevant background is that I'm writing visualisation to project a network from non-Euclidean space to Euclidean space, and inter-node distances are usually higher than what straight lines permit so I need to draw curves (really, of any kind). Arcs seem like the simplest option.
This is an excerpt from a working but slow solution:
Given
- coordinates of ingress node $a$, represented as an arc endpoint;
- coordinates of egress node $b$, represented as an arc endpoint;
- arc-length $l$;
I need (for matplotlib ellipsoidal arc patches) the circle centre $c$, radius $r$, and angles $\theta_a$, $\theta_b$ to each end of the arc. Convexity-like orientation of the arc doesn't matter. I've already calculated chord length but in my current solution this is not applicable.
I have a working, mostly-brute-force solution where I run the following system of equations through least-squares root-finding to determine $c$, $\theta$ and radius $r$:
$$r^2 = (a_x - c_x)^2 + (a_y - c_y)^2$$ $$r^2 = (b_x - c_x)^2 + (b_y - c_y)^2$$ $$a_x = c_x + r \cos(\theta_a)$$ $$a_y = c_y + r \sin(\theta_a)$$ $$b_x = c_x + r \cos(\theta_b)$$ $$b_y = c_y + r \sin(\theta_b) $$ $$ \theta_b = \theta_a + l/r $$
It works(ish), and depending on the network edge converges in ~20-200 iterations. That's not great.
Things that could help:
- an analytic solution (though I doubt this is possible)?
- better initial estimate than $c=(a+b)/2, \theta_a=0, r=100$?
- leverage @Claude Leibovici's quite-interesting polynomial expansion, if that's applicable?
I also think that the first two ($r^2=...$) equations might be redundant, but without them, the output is often incorrect.
