Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Cross Points of a Circe and a Line

For given a circle $c$ and a line $l$, print the coordinates of the cross points of them.

Input

The input is given in the following format.

$cx\; cy\; r$

$q$

$Line_1$

$Line_2$

:

$Line_q$

In the first line, the center coordinate of the circle and its radius are given by $cx$, $cy$ and $r$. In the second line, the number of queries $q$ is given.

In the following $q$ lines, as queries, $Line_i$ are given ($1 \leq i \leq q$) in the following format.

$x_1\; y_1\; x_2\; y_2$

Each line is represented by two points $p1$ and $p2$ which the line crosses. The coordinate of $p1$ and $p2$ are given by ($x1$, $y1$) and ($x2$, $y2$) respectively. All input values are given in integers.

Output

For each query, print the coordinates of the cross points in the following rules.

If there is one cross point, print two coordinates with the same values.

Print the coordinate with smaller $x$ first. In case of a tie, print the coordinate with smaller $y$ first.

The output values should be in a decimal fraction with an error less than 0.000001.

Constraints

$p1$ and $p2$ are different

The circle and line have at least one cross point

$1 \leq q \leq 1,000$

$-10,000 \leq cx, cy, x1, y1, x2, y2 \leq 10,000$

$1 \leq r \leq 10,000$

Sample Input and Output

Sample Input

2 1 1
2
0 1 4 1
3 0 3 3

Sample Output

1.00000000 1.00000000 3.00000000 1.00000000
3.00000000 1.00000000 3.00000000 1.00000000

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using static System.Console;
using static System.Math;
using static MyIO;
using static MyUtil;

using static Geometory;
using Vector = Geometory.Point;
using Line = Geometory.Segment;

public class D
{
	public static void Main() => (new Solver()).Solve();
}

public class Solver
{
	public void Solve()
	{
		var c = new Circle(new Point(GetDouble(), GetDouble()), GetDouble());
		int Q = GetInt();
		var ans = new string[Q];
		for(int i = 0; i < Q; i++)
			ans[i] = solve(c);

		WriteLine(string.Join("\n", ans));
	}

	private string solve(Circle c)
	{
		var p1 = new Point(GetDouble(), GetDouble());
		var p2 = new Point(GetDouble(), GetDouble());
		var l = new Line(p1, p2);
		var points = GetCrossPoints(c, l);
		var a = points.Item1;
		var b = points.Item2;
		if(a.X > b.X || (Equals(a.X, b.X) && a.Y > b.Y))
			swap(ref a, ref b);

		return $"{a.X:F9} {a.Y:F9} {b.X:F9} {b.Y:F9}";
	}
}

public static class Geometory
{
	private const double EPS = 1e-10;
	public static bool Equals(double a, double b) => Math.Abs(a - b) < EPS;

	public class Point
	{
		public double X;
		public double Y;		
		public Point(double x, double y)
		{
			X = x;
			Y = y;
		}
	
		public static Point operator+(Point p, Point q) => new Point(p.X + q.X, p.Y + q.Y);
		public static Point operator-(Point p, Point q) => new Point(p.X - q.X, p.Y - q.Y);
		public static Point operator*(Point p, double a) => new Point(a * p.X, a * p.Y);
		public static Point operator*(double a, Point p) => new Point(a * p.X, a * p.Y);
		public static Point operator/(Point p, double a) => new Point(p.X / a, p.Y / a);
	}

	public class Segment
	{
		public Point P1;
		public Point P2;
		public Segment(Point p1, Point p2)
		{
			P1 = p1;
			P2 = p2;
		}
	}

	public class Circle
	{
		public Point C;
		public double R;
		public Circle(Point c, double r)
		{
			C = c;
			R = r;
		}
	}

	public static double Abs(Vector a) => Math.Sqrt(Norm(a));
	public static double Norm(Vector a) => a.X * a.X + a.Y * a.Y;
	public static double Dot(Vector a, Vector b) => a.X * b.X + a.Y * b.Y;
	public static double Cross(Vector a, Vector b) => a.X * b.Y - a.Y * b.X;

	public static bool IsOrthogonal(Vector a, Vector b) => Equals(Dot(a, b), 0.0);
	public static bool IsOrthogonal(Point a1, Point a2, Point b1, Point b2) => IsOrthogonal(a1 - a2, b1 - b2);
	public static bool IsOrthogonal(Segment s1, Segment s2) => Equals(Dot(s1.P2 - s1.P1, s2.P2 - s2.P1), 0.0);
	public static bool IsParallel(Vector a, Vector b) => Equals(Cross(a, b), 0.0);
	public static bool IsParallel(Point a1, Point a2, Point b1, Point b2) => IsParallel(a1 - a2, b1 - b2);
	public static bool IsParallel(Segment s1, Segment s2) => Equals(Cross(s1.P2 - s1.P1, s2.P2 - s2.P1), 0.0);

	public static Point Project(Segment s, Point p)
	{
		Vector b = s.P2 - s.P1;
		double r = Dot(p - s.P1, b) / Norm(b);
		return s.P1 + b * r;
	}
	public static Point Reflect(Segment s, Point p) => p + (Project(s, p) - p) * 2.0;

	public static double GetDistance(Point a, Point b) => Abs(a - b);
	public static double GetDistanceLP(Line l, Point p) => Math.Abs(Cross(l.P2 - l.P1, p - l.P1) / Abs(l.P2 - l.P1));
	public static double GetDistanceSP(Segment s, Point p)
	{
		if(Dot(s.P2 - s.P1, p - s.P1) < 0.0) return Abs(p - s.P1);
		if(Dot(s.P1 - s.P2, p - s.P2) < 0.0) return Abs(p - s.P2);
		return GetDistanceLP(s, p);
	}
	public static double GetDistance(Segment s1, Segment s2)
	{
		if(Intersect(s1, s2)) return 0.0;
		return Math.Min(Math.Min(GetDistanceSP(s1, s2.P1), GetDistanceSP(s1, s2.P2)),
		                Math.Min(GetDistanceSP(s2, s1.P1), GetDistanceSP(s2, s1.P2)));
	}

	public const int COUNTER_CLOCKWISE = 1;
	public const int CLOCKWISE = -1;
	public const int ONLINE_BACK = 2;
	public const int ONLINE_FRONT = -2;
	public const int ON_SEGMENT = 0;
	public static int Ccw(Point p0, Point p1, Point p2)
	{
		Vector a = p1 - p0;
		Vector b = p2 - p0;
		if(Cross(a, b) > EPS) return COUNTER_CLOCKWISE;
		if(Cross(a, b) < -EPS) return CLOCKWISE;
		if(Dot(a, b) < -EPS) return ONLINE_BACK;
		if(Norm(a) < Norm(b)) return ONLINE_FRONT;
		return ON_SEGMENT;
	}
	public static bool Intersect(Point p1, Point p2, Point p3, Point p4)
	{
		return (Ccw(p1, p2, p3) * Ccw(p1, p2, p4) <= 0 && 
		        Ccw(p3, p4, p1) * Ccw(p3, p4, p2) <= 0);
	}
	public static bool Intersect(Segment s1, Segment s2) => Intersect(s1.P1, s1.P2, s2.P1, s2.P2);
	public static bool Intersect(Circle c, Line l) => GetDistanceLP(l, c.C) - c.R < EPS;

	public static Point GetCrossPoint(Segment s1, Segment s2)
	{
		Vector b = s2.P2 - s2.P1;
		double d1 = Math.Abs(Cross(b, s1.P1 - s2.P1));
		double d2 = Math.Abs(Cross(b, s1.P2 - s2.P1));
		double t = d1 / (d1 + d2);
		return s1.P1 + (s1.P2 - s1.P1) * t;
	}
	public static Tuple<Point, Point> GetCrossPoints(Circle c, Line l)
	{
		if(!Intersect(c, l)) throw new Exception();
		Vector pr = Project(l, c.C);
		Vector e = (l.P2 - l.P1) / Abs(l.P2 - l.P1);
		double b = Math.Sqrt(c.R * c.R - Norm(pr - c.C));
		return Tuple.Create(pr + e * b, pr - e * b);
	}
}

public static class MyIO
{
	private static string[] args = null;
	private static int num = -1;
	private static int used = -1;

	private static string getArg()
	{
		if(used == num)
		{
			args = Console.ReadLine().Split(' ');
			num = args.Length;
			used = 0;
		}
		return args[used++];
	}

	public static int GetInt() => int.Parse(getArg());
	public static long GetLong() => long.Parse(getArg());
	public static double GetDouble() => double.Parse(getArg());
	public static decimal GetDecimal() => decimal.Parse(getArg());
	public static string GetString() => getArg();
	public static char GetChar() => getArg()[0];
	public static int[] GetInts(long N) => Enumerable.Range(0, (int)N).Select(_ => GetInt()).ToArray();
	public static long[] GetLongs(long N) => Enumerable.Range(0, (int)N).Select(_ => GetLong()).ToArray();
	public static double[] GetDoubles(long N) => Enumerable.Range(0, (int)N).Select(_ => GetDouble()).ToArray();
	public static decimal[] GetDecimals(long N) => Enumerable.Range(0, (int)N).Select(_ => GetDecimal()).ToArray();
	public static string[] GetStrings(long N) => Enumerable.Range(0, (int)N).Select(_ => GetString()).ToArray();
}

public static class MyUtil
{
	public static void chmax<T>(ref T x, T y) where T : IComparable<T>
	{
		if(x.CompareTo(y) < 0)
			x = y;
	}

	public static void chmin<T>(ref T x, T y) where T : IComparable<T>
	{
		if(x.CompareTo(y) > 0)
			x = y;
	}

	public static void swap<T>(ref T x, ref T y)
	{
		T tmp = x;
		x = y;
		y = tmp;
	}
}