Task: Problem of Apollonius

C: #include <stdio.h>
#include <tgmath.h>

#define VERBOSE 0
#define for3 for(int i = 0; i < 3; i++)

typedef complex double vec;
typedef struct { vec c; double r; } circ;

#define re(x) creal(x)
#define im(x) cimag(x)
#define cp(x) re(x), im(x)
#define CPLX "(%6.3f,%6.3f)"
#define CPLX3 CPLX" "CPLX" "CPLX

double cross(vec a, vec b) { return re(a) * im(b) - im(a) * re(b); }
double abs2(vec a) { return a * conj(a); }
 
int apollonius_in(circ aa[], int ss[], int flip, int divert)
{
	vec n[3], x[3], t[3], a, b, center;
	int s[3], iter = 0, res = 0;
	double diff = 1, diff_old = -1, axb, d, r;
 
	for3 {
		s[i] = ss[i] ? 1 : -1;
		x[i] = aa[i].c;
	}
 
	while (diff > 1e-20) {
		a = x[0] - x[2], b = x[1] - x[2];
		diff = 0;
		axb = -cross(a, b);
		d = sqrt(abs2(a) * abs2(b) * abs2(a - b));

		if (VERBOSE) {
			const char *z = 1 + "-0+";
			printf("%c%c%c|%c%c|",
				z[s[0]], z[s[1]], z[s[2]], z[flip], z[divert]);
			printf(CPLX3, cp(x[0]), cp(x[1]), cp(x[2]));
		}

		
		r = fabs(d / (2 * axb));
		center = (abs2(a)*b - abs2(b)*a) / (2 * axb) * I + x[2];
 
 		
		if (!axb && flip != -1 && !divert) {
			if (!d) { 
				printf("Given conditions confused me.\n");
				return 0;
			}

			if (VERBOSE) puts("\n[divert]");
			divert = 1;
			res = apollonius_in(aa, ss, -1, 1);
		}

 		
		for3 n[i] = axb ? aa[i].c - center : a * I * flip;
		for3 t[i] = aa[i].c + n[i] / cabs(n[i]) * aa[i].r * s[i];

		
		for3 diff += abs2(t[i] - x[i]), x[i] = t[i];

		if (VERBOSE) printf(" %g\n", diff);
 
 		
		if (diff >= diff_old && diff_old >= 0)
			if (iter++ > 20) return res;

		diff_old = diff;
	}

	printf("found: ");
	if (axb) printf("circle "CPLX", r = %f\n", cp(center), r);
	else	 printf("line "CPLX3"\n", cp(x[0]), cp(x[1]), cp(x[2]));

	return res + 1;
}
 
int apollonius(circ aa[])
{
	int s[3], i, sum = 0;
	for (i = 0; i < 8; i++) {
		s[0] = i & 1, s[1] = i & 2, s[2] = i & 4;

		
		if (s[0] && !aa[0].r) continue;
		if (s[1] && !aa[1].r) continue;
		if (s[2] && !aa[2].r) continue;
		sum += apollonius_in(aa, s, 1, 0);
	}
	return sum;
}
 
int main()
{
	circ a[3] = {{0, 1}, {4, 1}, {2 + 4 * I, 1}};
	circ b[3] = {{-3, 2}, {0, 1}, {3, 2}};
	circ c[3] = {{-2, 1}, {0, 1}, {2 * I, 1}};
	
 
	puts("set 1"); apollonius(a);
	puts("set 2"); apollonius(b);
	puts("set 3"); apollonius(c);
}




Go: package main

import (
    "fmt"
    "math"
)

type circle struct {
    x, y, r float64
}

func main() {
    c1 := circle{0, 0, 1}
    c2 := circle{4, 0, 1}
    c3 := circle{2, 4, 2}
    fmt.Println(ap(c1, c2, c3, true))
    fmt.Println(ap(c1, c2, c3, false))
}

func ap(c1, c2, c3 circle, s bool) circle {
    x1sq := c1.x * c1.x
    y1sq := c1.y * c1.y
    r1sq := c1.r * c1.r
    x2sq := c2.x * c2.x
    y2sq := c2.y * c2.y
    r2sq := c2.r * c2.r
    x3sq := c3.x * c3.x
    y3sq := c3.y * c3.y
    r3sq := c3.r * c3.r
    v11 := 2 * (c2.x - c1.x)
    v12 := 2 * (c2.y - c1.y)
    v13 := x1sq - x2sq + y1sq - y2sq - r1sq + r2sq
    v14 := 2 * (c2.r - c1.r)
    v21 := 2 * (c3.x - c2.x)
    v22 := 2 * (c3.y - c2.y)
    v23 := x2sq - x3sq + y2sq - y3sq - r2sq + r3sq
    v24 := 2 * (c3.r - c2.r)
    if s {
        v14 = -v14
        v24 = -v24
    }
    w12 := v12 / v11
    w13 := v13 / v11
    w14 := v14 / v11
    w22 := v22/v21 - w12
    w23 := v23/v21 - w13
    w24 := v24/v21 - w14
    p := -w23 / w22
    q := w24 / w22
    m := -w12*p - w13
    n := w14 - w12*q
    a := n*n + q*q - 1
    b := m*n - n*c1.x + p*q - q*c1.y
    if s {
        b -= c1.r
    } else {
        b += c1.r
    }
    b *= 2
    c := x1sq + m*m - 2*m*c1.x + p*p + y1sq - 2*p*c1.y - r1sq
    d := b*b - 4*a*c
    rs := (-b - math.Sqrt(d)) / (2 * a)
    return circle{m + n*rs, p + q*rs, rs}
}