private static IEnumerable <SolutionSpec> EnumerateInitialSolutions(Polygon convexPolygon) { var rationalEdges = convexPolygon.Segments.Where(x => Arithmetic.IsSquare(x.QuadratOfLength)).OrderByDescending(x => x.QuadratOfLength); foreach (var rationalEdge in rationalEdges) { yield return(GetInitialSolutionAtTheMiddleOfRationalEdge(convexPolygon, rationalEdge)); } }
private static SolutionSpec GetInitialSolutionByLongestRationalEdge(Polygon problemPolygon) { var longestRationalEdge = problemPolygon.Segments.Where(x => Arithmetic.IsSquare(x.QuadratOfLength)).OrderBy(x => x.QuadratOfLength).LastOrDefault(); if (longestRationalEdge == null) { return(null); } return(GetInitialSolutionAtTheMiddleOfRationalEdge(problemPolygon, longestRationalEdge)); }
private void PaintSegments(Graphics g, Segment[] segments) { foreach (var segment in segments) { var color = Arithmetic.IsSquare(segment.QuadratOfLength) ? Color.Cyan : Color.Black; PaintSegment(g, color, segment); //PaintNode(g, color, segment.Start); //PaintNode(g, color, segment.End); } }
public static KeyValuePair <Rational, double>[] ParallelGist(PointProjectionSolver solver, out double hasParallelFactor) { var result = new Dictionary <Rational, double>(); var segments = GetSegments(solver); var hasParallelCount = 0; foreach (var s1 in segments) { bool hasParallel = false; foreach (var s2 in segments) { var sd = Arithmetic.InDistance2(s1.Start, s2); var ed = Arithmetic.InDistance2(s1.End, s2); if (sd.HasValue && ed.HasValue) { if (sd.Value == ed.Value) { var d = sd.Value; if (d == 0 || d == 1) { continue; } if (!Arithmetic.IsSquare(d)) { continue; } d = Arithmetic.Sqrt(d); d = d.Reduce(); if (!result.ContainsKey(d)) { result[d] = 0; } result[d]++; if (!hasParallel) { hasParallelCount++; hasParallel = true; } } } } } hasParallelFactor = ((double)hasParallelCount) / segments.Length; return(result.OrderByDescending(p => p.Value).Take(3).ToArray()); }
public static SolutionSpec GetInitialSolutionAlongRationalEdge(Segment rationalEdge) { var initialSolution = SolutionSpec.CreateTrivial(x => x + rationalEdge.Start); var edgeLen = new Rational(Arithmetic.Sqrt(rationalEdge.QuadratOfLength.Numerator), Arithmetic.Sqrt(rationalEdge.QuadratOfLength.Denomerator)); var a = rationalEdge.ToVector() / edgeLen; var b = Vector.Parse("1,0"); if (b.VectorProdLength(a) == 0) { if (b.ScalarProd(a) > 0) { return(initialSolution); } return(initialSolution.Reflect(rationalEdge)); } var bisect = new Segment(rationalEdge.Start, a + b + rationalEdge.Start); return(initialSolution.Reflect(bisect).Reflect(rationalEdge)); }
public Rational Distance2To(Vector p) { return(Arithmetic.Distance2(p, this)); }