public static void EdgeFinder(PointTester tester, double x0, double y0, double x1, double y1, int recursionSteps, out double x, out double y) { var xc = (x0 + x1) * 0.5; var yc = (y0 + y1) * 0.5; x = xc; y = yc; if (recursionSteps == 0) { return; } var val0 = tester(x0, y0); var valC = tester(xc, yc); if (val0 != valC) { EdgeFinder(tester, x0, y0, xc, yc, recursionSteps - 1, out x, out y); } else { var val1 = tester(x1, y1); if (val1 != valC) { EdgeFinder(tester, xc, yc, x1, y1, recursionSteps - 1, out x, out y); } else { return; } } }
static public double Calc(PointTester tester, double dx = 1, double dy = 1, double xs = 0, double ys = 0) { int cnt = 0; var rnd = new System.Random(); for (int i = 0; i < Samples; i++) { Point2 pt; pt.x = rnd.NextDouble() * dx + xs; pt.y = rnd.NextDouble() * dy + ys; bool b = tester(pt); if (Log) { Console.WriteLine(String.Format("({0}, {1}) -> {2}", pt.x, pt.y, b)); } if (b) { cnt++; } } double maxa = dx * dy; return(maxa * cnt / Samples); }
public static void EdgeFinder(PointTester tester, double x0, double y0, double x1, double y1, int recursionSteps, out double x, out double y) { var xc = (x0 + x1)*0.5; var yc = (y0 + y1)*0.5; x = xc; y = yc; if(recursionSteps==0) return; var val0 = tester(x0,y0); var valC = tester(xc,yc); if (val0 != valC) EdgeFinder(tester, x0, y0, xc, yc, recursionSteps - 1, out x, out y); else { var val1 = tester(x1, y1); if (val1 != valC) EdgeFinder(tester, xc, yc, x1, y1, recursionSteps - 1, out x, out y); else return; } }
public static List <Triangle> PointsTriangulation(int count, Func <int, Point> xy, Func <bool> cancel) { List <Triangle> Triangles = new List <Triangle>(); if (count >= 3) { List <int> indices = new List <int>() { Capacity = count }; for (int i = 0; i < count; ++i) { indices.Add(i); } Comparison <int> comparison = (a, b) => xy(a).X <xy(b).X? -1 : xy(a).X> xy(b).X ? 1 : xy(a).Y.CompareTo(xy(b).Y); indices.Sort(comparison); #region add super triangle vertices double xmin = xy(indices[0]).X; double xmax = xy(indices[count - 1]).X; double ymin = xy(indices[0]).Y; double ymax = ymin; for (int i = 1; i < count; i++) { ymin = Math.Min(ymin, xy(indices[i]).Y); ymax = Math.Max(ymax, xy(indices[i]).Y); } double dx = xmax - xmin; double dy = ymax - ymin; double dmax = Math.Max(dx, dy); double xmid = (xmax + xmin) / 2; double ymid = (ymax + ymin) / 2; Point s0 = new Point(xmid - 20 * dmax, ymid - dmax); Point s1 = new Point(xmid, ymid + 20 * dmax); Point s2 = new Point(xmid + 20 * dmax, ymid - dmax); #endregion Triangle[] triangleBuffer = new Triangle[4 * count]; bool[] complete = new bool[triangleBuffer.Length]; HalfEdgeSet edgeBuffer = new HalfEdgeSet(); PointTester pointTester = new PointTester(); int triangleCount = 0; #region add super triangle and initial triangle buffer triangleBuffer[0] = new Triangle() { v0 = count, v1 = count + 1, v2 = count + 2 }; complete[0] = false; for (int i = 1; i < triangleBuffer.Length; ++i) { triangleBuffer[i] = new Triangle(); complete[i] = false; } ; ++triangleCount; #endregion #region point getter delegate Func <int, Point> XY = (i) => { if (i < count) { return(xy(indices[i])); } if (i == count) { return(s0); } if (i == count + 1) { return(s1); } return(s2); }; #endregion #region triangulate for (int i = 0; i < count; ++i) { if (cancel != null && cancel()) { return(null); } edgeBuffer.Clear(); for (int j = 0; j < triangleCount; ++j) { if (complete[j]) { continue; } pointTester.Test(XY(i), XY(triangleBuffer[j].v0), XY(triangleBuffer[j].v1), XY(triangleBuffer[j].v2)); complete[j] = pointTester.Complete; if (pointTester.Inside) { HalfEdge e; e = new HalfEdge(triangleBuffer[j].v0, triangleBuffer[j].v1); if (edgeBuffer.Contains(e)) { edgeBuffer.Remove(e); } else { edgeBuffer.Add(e); } e = new HalfEdge(triangleBuffer[j].v1, triangleBuffer[j].v2); if (edgeBuffer.Contains(e)) { edgeBuffer.Remove(e); } else { edgeBuffer.Add(e); } e = new HalfEdge(triangleBuffer[j].v2, triangleBuffer[j].v0); if (edgeBuffer.Contains(e)) { edgeBuffer.Remove(e); } else { edgeBuffer.Add(e); } triangleBuffer[j].v0 = triangleBuffer[triangleCount - 1].v0; triangleBuffer[j].v1 = triangleBuffer[triangleCount - 1].v1; triangleBuffer[j].v2 = triangleBuffer[triangleCount - 1].v2; complete[j] = complete[triangleCount - 1]; --triangleCount; --j; } } // (re)create triangles foreach (HalfEdge edge in edgeBuffer) { triangleBuffer[triangleCount].v0 = edge.B; triangleBuffer[triangleCount].v1 = edge.E; triangleBuffer[triangleCount].v2 = i; complete[triangleCount] = false; ++triangleCount; } } #endregion #region save permanent mesh for (int i = 0; i < triangleCount; ++i) { if (triangleBuffer[i].v0 < count && triangleBuffer[i].v1 < count && triangleBuffer[i].v2 < count) { Triangles.Add(new Triangle() { v0 = indices[triangleBuffer[i].v0], v1 = indices[triangleBuffer[i].v1], v2 = indices[triangleBuffer[i].v2] }); //triangleBuffer[i]); } } #endregion } return(Triangles); }