代码又臭又长轻喷。85% 都是蓝书上的板子 :(
尝试过改数组大小,没用。
#include <bits/stdc++.h>
// #define debug(s, x) cout << s << ": " << (x) << '\n'
using namespace std;
using tp = double;
tp eps = 1e-10;
constexpr tp sq(tp x) { return x * x; }
int cmp(tp x) {
return abs(x) > eps ? x < 0 ? -1 : 1 : 0;
}
class Point {
public:
tp x, y;
Point(tp _x = 0, tp _y = 0) :
x(_x), y(_y) {}
explicit operator bool() { return x || y; }
public:
bool operator<(Point rhs) const {
return x < rhs.x || x == rhs.x && y < rhs.y;
}
bool operator==(Point rhs) const {
return !cmp(x - rhs.x) && !cmp(y - rhs.y);
}
bool operator>(Point rhs) const {
return !operator<(rhs) && !operator==(rhs);
}
bool operator<=(Point rhs) const {
return !operator>(rhs);
}
bool operator>=(Point rhs) const {
return !operator<(rhs);
}
bool operator!=(Point rhs) const {
return !operator==(rhs);
}
public:
Point operator+(Point rhs) {
return {x + rhs.x, y + rhs.y};
}
Point &operator+=(Point rhs) {
return *this = operator+(rhs);
}
Point operator-(Point rhs) {
return {x - rhs.x, y - rhs.y};
}
Point &operator-=(Point rhs) {
return *this = operator-(rhs);
}
Point operator*(tp p) {
return {x * p, y * p};
}
Point &operator*=(tp p) {
return *this = operator*(p);
}
Point operator/(tp p) {
return {x / p, y / p};
}
Point &operator/=(tp p) {
return *this = operator/(p);
}
tp operator*(Point rhs) {
return x * rhs.y - y * rhs.x;
}
Point &operator*=(Point rhs) {
return *this = operator*(rhs);
}
tp operator&(Point rhs) {
return x * rhs.x + y * rhs.y;
}
Point &operator&=(Point rhs) {
return *this = operator&(rhs);
}
tp operator~() {
return sqrt(operator&(*this));
}
tp operator^(Point rhs) {
return acos(operator&(rhs) / operator~() / ~rhs);
}
Point rot(tp rad) {
return {x * cos(rad) - y * sin(rad), x * sin(rad) + y * cos(rad)};
}
Point operator!() {
return {-y / operator~(), x / operator~()};
}
};
template <class cp, class trp>
basic_istream<cp, trp> &operator>>(basic_istream<cp, trp> &is, Point &rhs) {
return is >> rhs.x >> rhs.y;
}
template <class cp, class trp>
basic_ostream<cp, trp> &operator<<(basic_ostream<cp, trp> &os, Point rhs) {
return os << rhs.x << ' ' << rhs.y;
}
tp crs(Point lhs, Point mhs, Point rhs) {
return (mhs - lhs) * (rhs - lhs);
}
Point seg_intersect(Point p, Point v, Point q, Point w) {
return p + v * (w * (p - q) / (v * w));
}
bool has_seg_intersect(Point au, Point av, Point bu, Point bv) {
tp p = (av - au) * (bu - au), q = (av - au) * (bv - au),
s = (bv - bu) * (au - bu), t = (bv - bu) * (av - bu);
return cmp(p) * cmp(q) < 0 && cmp(s) * cmp(t) > 0;
}
tp dist_seg(Point p, Point u, Point v) {
if (u == v) return ~(p - u);
auto a = v - u, b = p - u, c = p - v;
if (cmp(a & b) < 0)
return ~b;
else if (cmp(a & c) > 0)
return ~c;
else
return abs(a * b) / ~a;
}
bool on_seg(Point p, Point u, Point v) {
return !cmp((u - p) * (v - p)) && cmp(u - p & v - p) < 0;
}
class Circ : public Point {
public:
tp r;
Circ(Point _O = {0, 0}, tp _r = 0) :
Point(_O), r(_r) {}
explicit operator bool() { return x || y || r; }
public:
Point operator()(tp g) {
return {x + cos(g) * r, y + sin(g) * r};
}
};
template <class cp, class trp>
basic_istream<cp, trp> &operator>>(basic_istream<cp, trp> &is, Circ &rhs) {
return is >> rhs.x >> rhs.y >> rhs.r;
}
template <class cp, class trp>
basic_ostream<cp, trp> &operator<<(basic_ostream<cp, trp> &os, Circ rhs) {
return os << rhs.x << ' ' << rhs.y << ' ' << rhs.r;
}
int get_tangent(Circ a, Circ b, Point *e, Point *f) {
if (a.r < b.r)
swap(a, b), swap(e, f);
tp Q = sq(a.x - b.x) + sq(a.y - b.y),
d = sq(a.r - b.r), s = sq(a.r + b.r);
// debug("Q", Q), debug("d", d), debug("s", s);
int top = 0;
if (Q < d) return 0;
tp z = atan2(b.y - a.y, b.x - a.x);
// debug("z", z);
if (!cmp(Q) && a.r == b.r) return -1;
// puts("--- Res is not 0 nor -1 ---");
if (Q == d) {
e[top] = a(z), f[top++] = b(z);
// debug("e top", e[top]), debug("f top", f[top]);
return 1;
}
tp G = acos((a.r - b.r) / sqrt(Q));
// debug("G", G);
e[top] = a(G + z), f[top++] = b(G + z);
// debug("e top", e[top]), debug("f top", f[top]);
e[top] = a(z - G), f[top++] = b(z - G);
// debug("e top", e[top]), debug("f top", f[top]);
if (Q == s)
e[top] = a(z), f[top++] = b(z + M_PI);
else if (Q > s) {
G = acos((a.r + b.r) / sqrt(Q));
e[top] = a(G + z), f[top++] = b(G + z + M_PI);
e[top] = a(z - G), f[top++] = b(z - G + M_PI);
}
return top;
}
Circ a, b;
Point e[10000], f[10000];
pair<Point, Point> res[10000];
void solve() {
// puts("------------------------");
int v = get_tangent(a, b, e, f);
cout << v << '\n';
for (int i = 0; i < v; i++)
res[i] = {e[i], f[i]};
sort(res, res + v);
for (int i = 0; i < v; i++)
cout << res[i].first << ' ' << res[i].second << ' '
<< ~(res[i].first - res[i].second) << '\n';
}
int main() {
// #ifdef _CC_
// freopen("password.in", "r", stdin);
// freopen("Tester.out", "w", stdout);
// #endif
cout << fixed << setprecision(5);
while (cin >> a >> b, a) solve();
}
是不是除以 / mod 0 导致的?话说 double 除以 0 好像是可以的,值为 nan……