using System; using System.Collections.Generic; public struct Complex { public double Real; public double Imaginary; public Complex(double real, double imaginary) { Real = real; Imaginary = imaginary; } public static Complex operator -(Complex a, Complex b) { return new Complex(a.Real - b.Real, a.Imaginary - b.Imaginary); } public static double Abs(Complex c) { return Math.Sqrt(c.Real * c.Real + c.Imaginary * c.Imaginary); } public static double Atan2(double y, double x) { return Math.Atan2(y, x); } } public class Program { const int MAX_POINTS = 500; // This function returns the maximum points that // can lie inside the circle of radius 'r' being // rotated about point 'i' static int GetPointsInside(int i, double r, int n, Complex[] arr, double[,] dis) { // This list stores alpha and beta and flag // is marked true for alpha and false for beta List<(double, bool)> angles = new List<(double, bool)>(); for (int j = 0; j < n; j++) { if (i != j && dis[i, j] <= 2 * r) { // acos returns the arc cosine of the complex // used for cosine inverse double B = Math.Acos(dis[i, j] / (2 * r)); // arg returns the phase angle of the complex double A = Complex.Atan2(arr[j].Imaginary - arr[i].Imaginary, arr[j].Real - arr[i].Real); double alpha = A - B; double beta = A + B; angles.Add((alpha, true)); angles.Add((beta, false)); } } // angles list is sorted and traversed angles.Sort(CompareAngles); // count maintains the number of points inside // the circle at certain value of theta // res maintains the maximum of all count int count = 1, res = 1; foreach (var angle in angles) { // entry angle if (angle.Item2) count++; // exit angle else count--; if (count > res) res = count; } return res; } // Returns count of maximum points that can lie // in a circle of radius r. static int MaxPoints(Complex[] arr, int n, int r) { // dis array stores the distance between every // pair of points double[,] dis = new double[n, n]; for (int i = 0; i < n - 1; i++) for (int j = i + 1; j < n; j++) // abs gives the magnitude of the complex // number and hence the distance between // i and j dis[i, j] = dis[j, i] = Complex.Abs(arr[i] - arr[j]); // This loop picks a point p int ans = 0; for (int i = 0; i < n; i++) // maximum number of points for point arr[i] ans = Math.Max(ans, GetPointsInside(i, r, n, arr, dis)); return ans; } // Custom comparer for sorting angles static int CompareAngles((double, bool) A, (double, bool) B) { if (A.Item1 < B.Item1) return -1; else if (A.Item1 > B.Item1) return 1; else return A.Item2.CompareTo(B.Item2); } // Driver code public static void Main(string[] args) { Complex[] arr = { new Complex(6.47634, 7.69628), new Complex(5.16828, 4.79915), new Complex(6.69533, 6.20378) }; int r = 1; int n = arr.Length; Console.WriteLine("The maximum number of points are: " + MaxPoints(arr, n, r)); } }