public bool IsInteriorPoint(Point3 p) { if (p.X < bounds[0] || p.X > bounds[1] || p.Y <bounds[2] || p.Y> bounds[3]) { return(false); } int[] indices = classifier.GetIndices(p.X, p.Y); int[] facets = lookup_table[indices[0], indices[1]].ToArray(); int paritycount = 0; //Store relevant faces List <Facet> relevants = new List <Facet>(); for (int i = 0; i < facets.Length; i++) { //NEED TO IMPLEMENT FACET COLLAPSING HERE! //Count the number of intersections in negative z direction (WLOG). int index = facets[i]; Facet currentFacet = temp_facet_data[index]; if (MathTools.IsAbovePlane(p, currentFacet)) //Ignore facets in Z+ direction. { Triangle projection = Triangle.FromFacet(currentFacet); //Project face onto xy plane Pair xy_p = new Pair(p.X, p.Y); if (projection.Contains(xy_p)) { //Test distance condition bool degenerate = false; foreach (Facet f in relevants) { //degenerate if you find a zero-distance facet degenerate = degenerate || check_degenerate(f, currentFacet); if (degenerate) { break; } } if (!degenerate) { relevants.Add(currentFacet); } } } } paritycount = relevants.Count; return(paritycount % 2 == 1); }
public RectangularCover(Triangle T, GridClassifier map) { tri = T; grid = map; //O(n^2) unfortunately. List <int> i_indices_list = new List <int>(); List <int> j_indices_list = new List <int>(); //Optimization here: Precompute containment of each point in the GridClassifier object, then load in O(1). Implement if performance is horrible. bool[,] grid_point_interior_status = new bool[map.Count + 1, map.Count + 1]; int[] ll = map.GetIndices(new Pair(T.Xmin, T.Ymin)); int[] ur = map.GetIndices(new Pair(T.Xmax, T.Ymax)); int imin = ll[0]; int jmin = ll[1]; int imax = ur[0]; int jmax = ur[1]; //Loop 1: precompute interiors for (int i = imin; i < imax + 1; i++) { for (int j = jmin; j < jmax + 1; j++) { grid_point_interior_status[i, j] = T.Contains(map.ComputeXY(i, j)); } } //Loop 2: iterate. for (int i = 0; i < 3; i++) { int[] vertexcoords = map.GetIndices(T[i]); i_indices_list.Add(vertexcoords[0]); j_indices_list.Add(vertexcoords[1]); } for (int i = imin; i < imax + 1; i++) { for (int j = jmin; j < jmax + 1; j++) { //Check corners of rectangle bool[] corners = { grid_point_interior_status[i, j], //Lower left grid_point_interior_status[i + 1, j], //Lower right grid_point_interior_status[i, j + 1], //Upper left grid_point_interior_status[i + 1, j + 1] //Upper right }; bool rectangle_has_interior_point = MathTools.CheckAny(corners); if (rectangle_has_interior_point) { //No more computations should occur after here. i_indices_list.Add(i); j_indices_list.Add(j); } else { //Only check three - see reference above. Pair[] ccw_orientation_cornerpoints = new Pair[] { new Pair(map.ComputeXY(i, j)), //Lower left new Pair(map.ComputeXY(i + 1, j)), //Lower right new Pair(map.ComputeXY(i + 1, j + 1)), //Upper right new Pair(map.ComputeXY(i, j + 1)) //Uppper left }; if (check_three_side(ccw_orientation_cornerpoints, T)) { i_indices_list.Add(i); j_indices_list.Add(j); } } } } i_indices = i_indices_list.ToArray(); j_indices = j_indices_list.ToArray(); }