CircleTangents
Finds the external tangents of two circles, or internal if r2 is negated. Can return 0, 1, or 2 tangents -- 0 if one circle contains the other (or overlaps it, in the internal case, or if the circles are the same); 1 if the circles are tangent to each other (in which case .first = .second and the tangent line is perpendicular to the line between the centers). .first and .second give the tangency points at circle 1 and 2 respectively. To find the tangents of a circle with a point set r2 to 0.
13 lines tested
Needs: "Point.h"
content/geometry/CircleTangents.h — Victor Lecomte, chilli, source: https://vlecomte.github.io/cp-geo.pdf
template<class P>
vector<pair<P, P>> tangents(P c1, double r1, P c2, double r2) {
P d = c2 - c1;
double dr = r1 - r2, d2 = d.dist2(), h2 = d2 - dr * dr;
if (d2 == 0 || h2 < 0) return {};
vector<pair<P, P>> out;
for (double sign : {-1, 1}) {
P v = (d * dr + d.perp() * sqrt(h2) * sign) / d2;
out.push_back({c1 + v * r1, c2 + v * r2});
}
if (h2 == 0) out.pop_back();
return out;
}