Насколько я помню, в общем случае первая задача решается так:
Код
Type
TPoint =
Record
x, y: Double;
End;
TCircle =
Record
x, y, r: Double;
End;
Const
Epsilon = 0.001;
n = 3;
{ координаты заданы для тестирования }
arrCircles: Array[1 .. n] Of TCircle =
((x:- 5; y:4; r:4),
(x:- 6; y:4; r:1),
(x:-10; y:8; r:3) );
Var
amount: Integer;
{ здесь хранятся координаты точек пересечения }
InterPoint: Array[1 .. 2*n] Of TPoint;
Function CircleIntersect( cr1, cr2: TCircle ): Integer;
Var
p1, p2: TPoint;
q, a, b, c, D: Double;
Dist: Double;
Begin
Dist := Sqrt( Sqr(cr2.x - cr1.x) +
Sqr(cr2.y - cr1.y));
cr2.x := cr2.x - cr1.x;
cr2.y := cr2.y - cr1.y;
CircleIntersect := 0;
If (Abs(Dist) < Epsilon) or (Dist > cr1.r + cr2.r) or
(Dist < Abs(cr1.r - cr2.r)) Then Exit;
CircleIntersect := 1;
If Abs(Dist - (cr1.r + cr2.r)) < Epsilon Then
Begin
p1.x := (cr2.x * cr1.r) / Dist;
p1.y := (cr2.y * cr1.r) / Dist;
p1.y := p1.y + cr1.y;
p1.x := p1.x + cr1.x;
Inc(Amount);
InterPoint[Amount] := p1;
Exit
End;
If cr2.x = 0 Then
Begin
p1.y := (Sqr(cr2.y) + Sqr(cr1.r) - Sqr(cr2.r)) /
(2 * cr2.y);
p1.x := Sqrt(Sqr(cr1.r) - Sqr(p1.y));
p2.x := -p1.x;
p2.y := p1.y;
End
Else
Begin
q := Sqr(cr1.r) - Sqr(cr2.r) + Sqr(cr2.x) + Sqr(cr2.y);
a := 4 * (Sqr(cr2.y) + Sqr(cr2.x));
b := (-4) * cr2.y * q;
c := Sqr(q) - 4 * Sqr(cr1.r) * Sqr(cr2.x);
D := Sqr(b) - 4 * a * c;
p1.y := ((-b + Sqrt(D))/(2*a));
p2.y := ((-b - Sqrt(D))/(2*a));
p1.x := ((Sqr(cr1.r) - Sqr(cr2.r) +
Sqr(cr2.x) + Sqr(cr2.y) -
2*cr2.y*p1.y) / (2*cr2.x));
p2.x := ((Sqr(cr1.r) - Sqr(cr2.r) +
Sqr(cr2.x) + Sqr(cr2.y) -
2*cr2.y*p2.y) / (2*cr2.x));
End;
p1.y := p1.y + cr1.y;
p2.y := p2.y + cr1.y;
p1.x := p1.x + cr1.x;
p2.x := p2.x + cr1.x;
Inc(Amount);
InterPoint[Amount] := p1;
Inc(Amount);
InterPoint[Amount] := p2;
CircleIntersect := 2
End;
Var
i, j: Integer;
Begin
For i := 1 To n Do
Begin
WriteLn( 'Окружность #', i );
Write( 'X центра>' ); ReadLn(arrCircles[i].x);
Write( 'Y центра>' ); ReadLn(arrCircles[i].y);
Write( 'Радиус>' ); ReadLn(arrCircles[i].r);
End;
Amount := 0;
For i := 1 To n Do
For j := Succ(i) To n Do
CircleIntersect(arrCircles[i], arrcircles[j]);
WriteLn( 'Найдено точек:', Amount );
For i := 1 To Amount Do
WriteLn( 'точка #', i, ': x = ', interpoint[i].x:7:3,
' y = ', interpoint[i].y:7:3 )
End.
Можно еще добавить проверку на совпадающие точки ... :p2: