Circle and Tangent Line
Given a circle C centered at the origin with radius r, and an external point P = (a, 0) where a > r: 1. Find the two tangent lines from P to C. 2. Compute the tangent length (distance from P to eac...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
Let \(C\) be the circle with radius \(r\), \(x^2 + y^2 = r^2\). We choose two points \(P(a, b)\) and \(Q(-a, c)\) so that the line passing through \(P\) and \(Q\) is tangent to \(C\).
For example, the quadruplet \((r, a, b, c) = (2, 6, 2, -7)\) satisfies this property.
Let \(F(R, X)\) be the number of the integer quadruplets \((r, a, b, c)\) with this property, and with \(0 < r \leq R\) and \(0 < a \leq X\).
We can verify that \(F(1, 5) = 10\), \(F(2, 10) = 52\) and \(F(10, 100) = 3384\).
Find \(F(10^8, 10^9) + F(10^9, 10^8)\).
Problem 410: Circle and Tangent Line
Mathematical Derivation
Tangent Length
By the Pythagorean theorem applied to the triangle formed by the center , the tangent point , and the external point :
Angle of Tangency
The half-angle subtended at satisfies:
Tangent Point Coordinates
The tangent points are:
Proof: The tangent point lies on the circle () and . The foot of the perpendicular from onto line at distance from gives the -coordinate. The -coordinate follows from the circle equation.
Tangent Line Equations
The tangent line at point on the circle is:
Substituting the tangent points:
Simplifying:
Area Between Tangent Lines and Minor Arc
The area consists of the triangle minus the circular sector, plus the triangle minus the same sector. More directly:
where and .
This is the area of the kite (which equals ) minus the circular sector of angle (which has area ).
Numerical Example
For , :
| Quantity | Value |
|---|---|
| Tangent length | |
| Half-angle | |
| Tangent point | |
| Tangent point | |
| Enclosed area |
Generalizations
- Multiple circles: Given circles, the number of common external tangent lines and their intersections form rich combinatorial structures.
- Lattice tangent lines: Counting tangent lines from lattice points to the unit circle connects to number theory (sums of two squares).
- Power of a point: The quantity is the power of point with respect to circle . It equals the product of signed distances along any line through intersecting .
Correctness
Theorem. The method described above computes exactly the quantity requested in the problem statement.
Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
/**
* Problem 410: Circle and Tangent Line
*
* Given a circle centered at origin with radius r and external point P=(a,0),
* compute tangent length, tangent points, tangent line equations, and enclosed area.
*/
struct Point {
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
double norm() const { return sqrt(x * x + y * y); }
};
struct TangentResult {
double tangent_length;
double half_angle_rad;
double half_angle_deg;
Point t1, t2;
double enclosed_area;
double power_of_point;
};
TangentResult solve(double a, double r) {
assert(a > r && r > 0);
TangentResult res;
// Tangent length: sqrt(a^2 - r^2)
res.tangent_length = sqrt(a * a - r * r);
// Half-angle at P
res.half_angle_rad = asin(r / a);
res.half_angle_deg = res.half_angle_rad * 180.0 / M_PI;
// Tangent points
double tx = r * r / a;
double ty = r * sqrt(a * a - r * r) / a;
res.t1 = Point(tx, ty);
res.t2 = Point(tx, -ty);
// Enclosed area = L*r - r^2 * alpha
res.enclosed_area = res.tangent_length * r - r * r * res.half_angle_rad;
// Power of point
res.power_of_point = a * a - r * r;
return res;
}
void print_result(double a, double r) {
TangentResult res = solve(a, r);
cout << fixed << setprecision(6);
cout << "Circle: center (0,0), radius r = " << r << endl;
cout << "External point: P = (" << a << ", 0)" << endl;
cout << string(50, '=') << endl;
cout << "Tangent length: L = " << res.tangent_length << endl;
cout << "Half-angle: alpha = "
<< setprecision(4) << res.half_angle_deg << " deg ("
<< setprecision(6) << res.half_angle_rad << " rad)" << endl;
cout << "Tangent point T1: (" << res.t1.x << ", " << res.t1.y << ")" << endl;
cout << "Tangent point T2: (" << res.t2.x << ", " << res.t2.y << ")" << endl;
// Tangent line equations: r*x +/- sqrt(a^2-r^2)*y = r*a
double L = res.tangent_length;
cout << setprecision(4);
cout << "Tangent line 1: " << r << "*x + " << L << "*y = " << r * a << endl;
cout << "Tangent line 2: " << r << "*x + " << -L << "*y = " << r * a << endl;
cout << setprecision(6);
cout << "Enclosed area: A = " << res.enclosed_area << endl;
cout << "Power of point: " << res.power_of_point
<< " (= L^2 = " << res.tangent_length * res.tangent_length << ")" << endl;
// Verification: tangent points lie on circle
cout << "Verification |OT1|: " << res.t1.norm() << " (should be " << r << ")" << endl;
cout << "Verification |OT2|: " << res.t2.norm() << " (should be " << r << ")" << endl;
// Verification: OT perpendicular to PT
double dot1 = res.t1.x * (res.t1.x - a) + res.t1.y * res.t1.y;
double dot2 = res.t2.x * (res.t2.x - a) + res.t2.y * res.t2.y;
cout << "Verification OT.PT (T1): " << scientific << dot1 << " (should be 0)" << endl;
cout << "Verification OT.PT (T2): " << dot2 << " (should be 0)" << endl;
cout << endl;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout << string(60, '=') << endl;
cout << " PROBLEM 410: CIRCLE AND TANGENT LINE" << endl;
cout << string(60, '=') << endl << endl;
// Primary example
print_result(3.0, 1.0);
cout << string(60, '=') << endl;
cout << "Additional examples:" << endl;
cout << string(60, '=') << endl << endl;
// Additional examples
vector<pair<double, double>> cases = {{5, 2}, {10, 1}, {2, 1}};
for (auto& [a, r] : cases) {
TangentResult res = solve(a, r);
cout << fixed << setprecision(4);
cout << "--- r=" << r << ", P=(" << a << ",0) ---" << endl;
cout << " L=" << res.tangent_length
<< ", alpha=" << res.half_angle_deg << " deg"
<< ", area=" << res.enclosed_area << endl;
cout << " T1=(" << res.t1.x << ", " << res.t1.y
<< "), T2=(" << res.t2.x << ", " << res.t2.y << ")" << endl;
cout << endl;
}
return 0;
}
"""
Problem 410: Circle and Tangent Line
Given a circle centered at the origin with radius r and an external point P=(a,0),
compute tangent lines, tangent points, tangent length, and the enclosed area.
The helper data returned by create_visualization can be consumed by an external plotter.
"""
from __future__ import annotations
import math
import sys
from typing import Dict, Optional, Sequence, Tuple
def tangent_length(a: float, r: float) -> float:
"""Distance from external point (a,0) to tangent point on circle of radius r."""
assert a > r > 0, "Point must be outside the circle"
return math.sqrt(a**2 - r**2)
def tangent_half_angle(a: float, r: float) -> float:
"""Half-angle (in radians) subtended at P by the two tangent lines."""
assert a > r > 0
return math.asin(r / a)
def tangent_points(a: float, r: float):
"""Coordinates of the two tangent points on the circle."""
assert a > r > 0
tx = r**2 / a
ty = r * math.sqrt(a**2 - r**2) / a
return (tx, ty), (tx, -ty)
def tangent_line_coefficients(
a: float, r: float
) -> Tuple[Tuple[float, float, float], Tuple[float, float, float]]:
"""
Return (A, B, C) for each tangent line Ax + By = C.
Line 1: r*x + sqrt(a^2-r^2)*y = r*a
Line 2: r*x - sqrt(a^2-r^2)*y = r*a
"""
assert a > r > 0
L = math.sqrt(a**2 - r**2)
return (r, L, r * a), (r, -L, r * a)
def enclosed_area(a: float, r: float) -> float:
"""
Area between the two tangent lines and the minor arc of the circle.
Equals L*r - r^2 * arcsin(r/a), where L = sqrt(a^2 - r^2).
"""
assert a > r > 0
L = math.sqrt(a**2 - r**2)
alpha = math.asin(r / a)
return L * r - r**2 * alpha
def power_of_point(a: float, r: float) -> float:
"""Power of the point P=(a,0) with respect to the circle x^2+y^2=r^2."""
return a**2 - r**2
def print_solution(a: float, r: float) -> None:
"""Print all computed quantities for given parameters."""
print(f"Circle: center (0,0), radius r = {r}")
print(f"External point: P = ({a}, 0)")
print(f"{'='*50}")
L = tangent_length(a, r)
print(f"Tangent length: L = {L:.6f}")
alpha = tangent_half_angle(a, r)
print(f"Half-angle: alpha = {math.degrees(alpha):.4f} deg ({alpha:.6f} rad)")
t1, t2 = tangent_points(a, r)
print(f"Tangent point T1: ({t1[0]:.6f}, {t1[1]:.6f})")
print(f"Tangent point T2: ({t2[0]:.6f}, {t2[1]:.6f})")
(a1, b1, c1), (a2, b2, c2) = tangent_line_coefficients(a, r)
print(f"Tangent line 1: {a1:.4f}*x + {b1:.4f}*y = {c1:.4f}")
print(f"Tangent line 2: {a2:.4f}*x + {b2:.4f}*y = {c2:.4f}")
A = enclosed_area(a, r)
print(f"Enclosed area: A = {A:.6f}")
pw = power_of_point(a, r)
print(f"Power of point: {pw:.6f} (= L^2 = {L**2:.6f})")
# Verify tangent points lie on the circle
for name, pt in [("T1", t1), ("T2", t2)]:
dist = math.sqrt(pt[0]**2 + pt[1]**2)
print(f"Verification |O{name}|: {dist:.6f} (should be {r})")
# Verify tangent is perpendicular to radius at tangent point
for name, pt in [("T1", t1), ("T2", t2)]:
# OT vector: (tx, ty), PT vector: (tx - a, ty)
dot = pt[0] * (pt[0] - a) + pt[1] * pt[1]
print(f"Verification OT.PT ({name}): {dot:.6e} (should be 0)")
def create_visualization(
a: float, r: float, filename: str = "visualization.png"
) -> Dict[str, object]:
"""Return geometry data that an external plotting tool can consume."""
t1, t2 = tangent_points(a, r)
return {
"circle_center": (0.0, 0.0),
"radius": r,
"external_point": (a, 0.0),
"tangent_points": (t1, t2),
"tangent_lines": tangent_line_coefficients(a, r),
"suggested_output": filename,
}
def parse_args(argv: Sequence[str]) -> Tuple[float, float]:
if not argv:
return 3.0, 1.0
if len(argv) != 2:
raise SystemExit("usage: python3 solution.py [a r]")
return float(argv[0]), float(argv[1])
def main(argv: Optional[Sequence[str]] = None) -> None:
a, r = parse_args(sys.argv[1:] if argv is None else argv)
print_solution(a, r)
if __name__ == "__main__":
main()