cppAcademy
← Learning PathLESSON 16 / 25 · COMPUTATIONAL GEOMETRY · 45 MIN✕

Circle-Circle Intersection

Two circle boundaries may meet at zero, one, two or infinitely many points. Distances between centers classify the configuration; subtracting the two circle equations constructs the intersections. This lesson distinguishes external tangency, internal tangency, nesting and coincidence, including circles of radius zero. The program outputs an approximate construction with a stated tolerance rather than treating a near-tangent numerical result as an exact symbolic answer.

Prerequisites: Circle Geometry Fundamentals; algebraic elimination.

Build the idea

  1. Classify before dividing

    Let centers be A,B with radii r,s and distance d. If d>r+s the circles are separate. If d<|r−s| one is strictly nested inside the other without boundary contact. Equality gives external or internal tangency. If d is zero, equal positive radii mean coincident boundaries and infinitely many points; different radii mean none.

  2. Derive distance along the center line

    Write an intersection as A+t·u+h·w, where u points from A to B and w is perpendicular. The two squared-distance equations are t²+h²=r² and (t−d)²+h²=s². Subtract to eliminate h², yielding t=(r²−s²+d²)/(2d). This formula requires distinct centers; that case was separated first.

    t=(r²−s²+d²)/(2d)

  3. Construct perpendicular offsets

    The base point is A+t·u. Then h=√(r²−t²) and the two candidates are base±h·w. A tangent has h=0 and is printed once. The program tests the center-distance tangency conditions with tolerance and clamps only rounding-scale negative radicands after feasibility checks. Output points are sorted for deterministic samples.

  4. Trace two equal circles

    For A=(0,0),B=(6,0),r=s=5, d=6 and t=3. The base is (3,0) and h=4, giving (3,−4) and (3,4). Each is distance 5 from both centers. Move B to (10,0) to obtain one external tangent point (5,0), or to (11,0) to obtain no intersections.

  5. Make degenerate semantics explicit

    A radius-zero circle is a single point, so coincident zero-radius circles have one common point, not infinitely many. A point circle on another boundary is a tangent-like one-point intersection. The absolute 10^−10 tolerance merges extremely close represented configurations; within that uncertainty band exact zero/one/two classification is not promised. The input scale is limited to moderate finite numbers.

C++17 implementation

This is a complete program. Compile with C++17 and enter the input described below.

#include<iostream>
#include<cmath>
#include<iomanip>
#include<algorithm>
struct Point{
    long double x,y;
    Point operator+(Point p)const{
        return {x+p.x,y+p.y};
    }
    Point operator-(Point p)const{
        return {x-p.x,y-p.y};
    }
    Point operator*(long double t)const{
        return {x*t,y*t};
    }
};
int main(){
    Point a,b;
    long double r,s;
    std::cin>>a.x>>a.y>>r>>b.x>>b.y>>s;
    if(r<0||s<0){
        std::cout<<"INVALID RADIUS\n";
        return 0;
    }
    const long double eps=1e-10L;
    Point v=b-a;
    long double d=std::hypotl(v.x,v.y);
    std::cout<<std::fixed<<std::setprecision(6);
    if(d<=eps){
        if(std::fabs(r-s)>eps){
            std::cout<<0<<'\n';
        }
        else if(r<=eps){
            std::cout<<1<<'\n'<<a.x<<' '<<a.y<<'\n';
        }
        else{
            std::cout<<"INFINITE\n";
        }
        return 0;
    }
    if(d>r+s+eps||d<std::fabs(r-s)-eps){
        std::cout<<0<<'\n';
        return 0;
    }
    // Subtract the squared circle equations to find the shared chord base.
    long double along=(r*r-s*s+d*d)/(2*d);
    Point unit=v*(1/d),base=a+unit*along;
    long double h=std::sqrt(std::max(0.0L,r*r-along*along));
    if(std::fabs(d-r-s)<=eps||std::fabs(d-std::fabs(r-s))<=eps){
        std::cout<<1<<'\n'<<base.x<<' '<<base.y<<'\n';
        return 0;
    }
    Point perpendicular{-unit.y,unit.x},x=base-perpendicular*h,y=base+perpendicular*h;
    if(x.x>y.x||(x.x==y.x&&x.y>y.y)){
        std::swap(x,y);
    }
    std::cout<<2<<'\n'<<x.x<<' '<<x.y<<'\n'<<y.x<<' '<<y.y<<'\n';
}

Complexity analysis

O(1) time and O(1) auxiliary space. At most two intersection points are constructed after constant-time classification.

Common mistakes and edge cases. Do not divide by d before treating coincident centers. Nested circles can have no intersections even when their disks overlap. Coincident point circles are a singleton. Clamp after feasibility checks; a large negative radicand signals a wrong classification or formula, not a number to hide.

Example input and output

Read ax ay r bx by s; finite coordinates/radii within magnitude 10^4, radii nonnegative. Print 0, 1 or 2 followed by coordinates, or INFINITE for coincident positive-radius boundaries. Negative radii produce INVALID RADIUS.

Input

0 0 5 6 0 5

Output

2
3.000000 -4.000000
3.000000 4.000000

Symmetry places the shared chord at x=3, with vertical offsets ±4.

Practical applications

Use for locating points at prescribed distances, circle arrangements and geometric feasibility. Disk overlap area is a different calculation. For exact symbolic coordinates, rational/algebraic representations may be required beyond this numerical construction.

Check your understanding

How many boundary intersections do identical zero-radius circles have?

Put it into practice

Test external/internal tangency, concentric unequal circles and two point circles.

Show a hint

Classify centers and radii before using the intersection formula.

Further reading