// 如果 A B 两点在直线同侧 返回 true
bool theSameSideOfLine(Point A, Point B) {
return sgn((A-s)^(e-s)) * sgn((B-s)^(e-s)) > 0;
}
// a[i] 和 b[i] 分别是第i条切线在圆A和圆B上的切点 f[i]为1内切 为2外切
int getTangents(circle A, Point* a, Point* b,int* f) {
circle BB=(*this);
circle B=BB;
int cnt = 0;
if (A.r < B.r) {
swap(A, B);
swap(a, b);
}
double d2 =(A.p.x - B.p.x) * (A.p.x - B.p.x) + (A.p.y - B.p.y) * (A.p.y - B.p.y);
double rdiff = A.r - B.r;
double rsum = A.r + B.r;
if (sgn(d2 - rdiff * rdiff) < 0) return 0; // 内含
double base = atan2(B.p.y - A.p.y, B.p.x - A.p.x);
Point pa=Point(A.r,0);
Point pb=Point(B.r,0);
Point p0=Point(0,0);
if (sgn(d2) == 0 && sgn(A.r - B.r) == 0) return -1; // 无限多条切线
if (sgn(d2 - rdiff * rdiff) == 0) { // 内切,一条切线
a[cnt] = A.p+pa.rotate(p0,base);
b[cnt] = B.p+pb.rotate(p0,base);
f[cnt] = 1;
++cnt;
return 1;
}
// 有外公切线
double ang = acos(rdiff / sqrt(d2));
a[cnt] = A.p+pa.rotate(p0,base+ang);
b[cnt] = B.p+pb.rotate(p0,base+ang);
f[cnt] = 2;
++cnt;
a[cnt] = A.p+pa.rotate(p0,base-ang);
b[cnt] = B.p+pb.rotate(p0,base-ang);
f[cnt] = 2;
++cnt;
if (sgn(d2 - rsum * rsum) == 0) { // 一条内公切线
a[cnt] = A.p+pa.rotate(p0,base);
b[cnt] = B.p+pb.rotate(p0,base+pi);
f[cnt] = 1;
++cnt;
} else if (sgn(d2 - rsum * rsum) > 0) { // 两条内公切线
double ang = acos(rsum / sqrt(d2));
a[cnt] = A.p+pa.rotate(p0,base+ang);
b[cnt] = B.p+pb.rotate(p0,base+pi+ang);
f[cnt] = 1;
++cnt;
a[cnt] = A.p+pa.rotate(p0,base-ang);
b[cnt] = B.p+pb.rotate(p0,base+pi-ang);
f[cnt] = 1;
++cnt;
}
return cnt;
} // 两圆公切线 返回切线的条数,-1表示无穷多条切线
Point LA[1010], LB[1010];
circle ansc[1010];
int fl[1010];
int main() {
int t;
cin>>t;
circle c1,c2;
circle cc1,cc2;
Point pt;
while(t--) {
c1.p.input();
scanf("%lf",&c1.r);
c2.p.input();
scanf("%lf",&c2.r);
pt.input();
iv=Inversion(pt,10.0);
Line lt;
int f;
iv.getCircleInv(c1,lt,cc1,f);
iv.getCircleInv(c2,lt,cc2,f);
Line l1,l2,l3,l4;
circle C1,C2,C3,C4;
int q = cc2.getTangents(cc1, LA, LB, fl), ans = 0;
for (int i = 0; i < q; ++i) {
Line lt=Line(LA[i],LB[i]);
if (lt.theSameSideOfLine(cc1.p, cc2.p)) {
if (!lt.theSameSideOfLine(pt, cc1.p)) continue;
iv.getLineInv(lt,ansc[ans],f);
ans++;
}
}
printf("%d\n", ans);
for (int i = 0; i < ans; ++i) {
printf("%.8f %.8f %.8f\n", ansc[i].p.x, ansc[i].p.y, ansc[i].r);
}
}
return 0;
}