/// <summary> /// Construct Voronoi region for given vertex. /// </summary> /// <param name="vertex"></param> /// <returns>The circumcenter indices which make up the cell.</returns> private void ConstructVoronoiRegion(Vertex vertex) { VoronoiRegion region = new VoronoiRegion(vertex); regions.Add(region); List <Point> vpoints = new List <Point>(); Otri f = default(Otri); Otri f_init = default(Otri); Otri f_next = default(Otri); Otri f_prev = default(Otri); Osub sub = default(Osub); // Call f_init a triangle incident to x vertex.tri.Copy(ref f_init); f_init.Copy(ref f); f_init.Onext(ref f_next); // Check if f_init lies on the boundary of the triangulation. if (f_next.triangle == Mesh.dummytri) { f_init.Oprev(ref f_prev); if (f_prev.triangle != Mesh.dummytri) { f_init.Copy(ref f_next); // Move one triangle clockwise f_init.OprevSelf(); f_init.Copy(ref f); } } // Go counterclockwise until we reach the border or the initial triangle. while (f_next.triangle != Mesh.dummytri) { // Add circumcenter of current triangle vpoints.Add(points[f.triangle.id]); if (f_next.Equal(f_init)) { // Voronoi cell is complete (bounded case). region.Add(vpoints); return; } f_next.Copy(ref f); f_next.OnextSelf(); } // Voronoi cell is unbounded region.Bounded = false; Vertex torg, tdest, tapex, intersection; int sid, n = mesh.triangles.Count; // Find the boundary segment id. f.Lprev(ref f_next); f_next.SegPivot(ref sub); sid = sub.seg.hash; // Last valid f lies at the boundary. Add the circumcenter. vpoints.Add(points[f.triangle.id]); // Check if the intersection with the bounding box has already been computed. if (rayPoints.ContainsKey(sid)) { vpoints.Add(rayPoints[sid]); } else { torg = f.Org(); tapex = f.Apex(); BoxRayIntersection(points[f.triangle.id], torg.y - tapex.y, tapex.x - torg.x, out intersection); // Set the correct id for the vertex intersection.id = n + rayIndex; points[n + rayIndex] = intersection; rayIndex++; vpoints.Add(intersection); rayPoints.Add(sid, intersection); } // Now walk from f_init clockwise till we reach the boundary. vpoints.Reverse(); f_init.Copy(ref f); f.Oprev(ref f_prev); while (f_prev.triangle != Mesh.dummytri) { vpoints.Add(points[f_prev.triangle.id]); f_prev.Copy(ref f); f_prev.OprevSelf(); } // Find the boundary segment id. f.SegPivot(ref sub); sid = sub.seg.hash; if (rayPoints.ContainsKey(sid)) { vpoints.Add(rayPoints[sid]); } else { // Intersection has not been computed yet. torg = f.Org(); tdest = f.Dest(); BoxRayIntersection(points[f.triangle.id], tdest.y - torg.y, torg.x - tdest.x, out intersection); // Set the correct id for the vertex intersection.id = n + rayIndex; points[n + rayIndex] = intersection; rayIndex++; vpoints.Add(intersection); rayPoints.Add(sid, intersection); } // Add the new points to the region (in counter-clockwise order) vpoints.Reverse(); region.Add(vpoints); }
private void ConstructBoundaryBvdCell(Vertex vertex) { VoronoiRegion region = new VoronoiRegion(vertex); regions.Add(region); Otri f = default(Otri); Otri f_init = default(Otri); Otri f_next = default(Otri); Otri f_prev = default(Otri); Osub sf = default(Osub); Osub sfn = default(Osub); Vertex torg, tdest, tapex, sorg, sdest; Point cc_f, cc_f_next, p; int n = mesh.triangles.Count; // Call P the polygon (cell) in construction List<Point> vpoints = new List<Point>(); // Call f_init a triangle incident to x vertex.tri.Copy(ref f_init); if (f_init.Org() != vertex) { throw new Exception("ConstructBoundaryBvdCell: inconsistent topology."); } // Let f be initialized to f_init f_init.Copy(ref f); // Call f_next the next triangle counterclockwise around x f_init.Onext(ref f_next); f_init.Oprev(ref f_prev); // Is the border to the left? if (f_prev.triangle != Mesh.dummytri) { // Go clockwise until we reach the border (or the initial triangle) while (f_prev.triangle != Mesh.dummytri && !f_prev.Equal(f_init)) { f_prev.Copy(ref f); f_prev.OprevSelf(); } f.Copy(ref f_init); f.Onext(ref f_next); } if (f_prev.triangle == Mesh.dummytri) { // For vertices on the domain boundaray, add the vertex. For // internal boundaries don't add it. p = new Point(vertex.x, vertex.y); p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } // Add midpoint of start triangles' edge. torg = f.Org(); tdest = f.Dest(); p = new Point((torg.X + tdest.X) / 2, (torg.Y + tdest.Y) / 2); p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); // repeat ... until f = f_init do { // Call Lffnext the line going through the circumcenters of f and f_next cc_f = this.points[f.triangle.id]; if (f_next.triangle == Mesh.dummytri) { if (!f.triangle.infected) { // Add last circumcenter vpoints.Add(cc_f); } // Add midpoint of last triangles' edge (chances are it has already // been added, so post process cell to remove duplicates???) torg = f.Org(); tapex = f.Apex(); p = new Point((torg.X + tapex.X) / 2, (torg.Y + tapex.Y) / 2); p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); break; } cc_f_next = this.points[f_next.triangle.id]; // if f is tagged non-blind then if (!f.triangle.infected) { // Insert the circumcenter of f into P vpoints.Add(cc_f); if (f_next.triangle.infected) { // Call S_fnext the constrained edge blinding f_next sfn.seg = subsegMap[f_next.triangle.hash]; // Insert point Lf,f_next /\ Sf_next into P if (SegmentsIntersect(sfn.SegOrg(), sfn.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } } else { // Call Sf the constrained edge blinding f sf.seg = subsegMap[f.triangle.hash]; sorg = sf.SegOrg(); sdest = sf.SegDest(); // if f_next is tagged non-blind then if (!f_next.triangle.infected) { tdest = f.Dest(); tapex = f.Apex(); // Both circumcenters lie on the blinded side, but we // have to add the intersection with the segment. // Center of f edge dest->apex Point bisec = new Point((tdest.X + tapex.X) / 2, (tdest.Y + tapex.Y) / 2); // Find intersection of seg with line through f's bisector and circumcenter if (SegmentsIntersect(sorg, sdest, bisec, cc_f, out p, false)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } // Insert point Lf,f_next /\ Sf into P if (SegmentsIntersect(sorg, sdest, cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } else { // Call Sf_next the constrained edge blinding f_next sfn.seg = subsegMap[f_next.triangle.hash]; // if Sf != Sf_next then if (!sf.Equal(sfn)) { // Insert Lf,fnext /\ Sf and Lf,fnext /\ Sfnext into P if (SegmentsIntersect(sorg, sdest, cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } if (SegmentsIntersect(sfn.SegOrg(), sfn.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } else { // Both circumcenters lie on the blinded side, but we // have to add the intersection with the segment. // Center of f_next edge org->dest Point bisec = new Point((torg.X + tdest.X) / 2, (torg.Y + tdest.Y) / 2); // Find intersection of seg with line through f_next's bisector and circumcenter if (SegmentsIntersect(sorg, sdest, bisec, cc_f_next, out p, false)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } } } // f <- f_next f_next.Copy(ref f); // Call f_next the next triangle counterclockwise around x f_next.OnextSelf(); } while (!f.Equal(f_init)); // Output: Bounded Voronoi cell of x in counterclockwise order. region.Add(vpoints); }
/// <summary> /// Construct Voronoi region for given vertex. /// </summary> /// <param name="vertex"></param> /// <returns>The circumcenter indices which make up the cell.</returns> private void ConstructVoronoiRegion(Vertex vertex) { VoronoiRegion region = new VoronoiRegion(vertex); regions.Add(region); List<Point> vpoints = new List<Point>(); Otri f = default(Otri); Otri f_init = default(Otri); Otri f_next = default(Otri); Otri f_prev = default(Otri); Osub sub = default(Osub); // Call f_init a triangle incident to x vertex.tri.Copy(ref f_init); f_init.Copy(ref f); f_init.Onext(ref f_next); // Check if f_init lies on the boundary of the triangulation. if (f_next.triangle == Mesh.dummytri) { f_init.Oprev(ref f_prev); if (f_prev.triangle != Mesh.dummytri) { f_init.Copy(ref f_next); // Move one triangle clockwise f_init.OprevSelf(); f_init.Copy(ref f); } } // Go counterclockwise until we reach the border or the initial triangle. while (f_next.triangle != Mesh.dummytri) { // Add circumcenter of current triangle vpoints.Add(points[f.triangle.id]); if (f_next.Equal(f_init)) { // Voronoi cell is complete (bounded case). region.Add(vpoints); return; } f_next.Copy(ref f); f_next.OnextSelf(); } // Voronoi cell is unbounded region.Bounded = false; Vertex torg, tdest, tapex, intersection; int sid, n = mesh.triangles.Count; // Find the boundary segment id. f.Lprev(ref f_next); f_next.SegPivot(ref sub); sid = sub.seg.hash; // Last valid f lies at the boundary. Add the circumcenter. vpoints.Add(points[f.triangle.id]); // Check if the intersection with the bounding box has already been computed. if (rayPoints.ContainsKey(sid)) { vpoints.Add(rayPoints[sid]); } else { torg = f.Org(); tapex = f.Apex(); BoxRayIntersection(points[f.triangle.id], torg.y - tapex.y, tapex.x - torg.x, out intersection); // Set the correct id for the vertex intersection.id = n + rayIndex; points[n + rayIndex] = intersection; rayIndex++; vpoints.Add(intersection); rayPoints.Add(sid, intersection); } // Now walk from f_init clockwise till we reach the boundary. vpoints.Reverse(); f_init.Copy(ref f); f.Oprev(ref f_prev); while (f_prev.triangle != Mesh.dummytri) { vpoints.Add(points[f_prev.triangle.id]); f_prev.Copy(ref f); f_prev.OprevSelf(); } // Find the boundary segment id. f.SegPivot(ref sub); sid = sub.seg.hash; if (rayPoints.ContainsKey(sid)) { vpoints.Add(rayPoints[sid]); } else { // Intersection has not been computed yet. torg = f.Org(); tdest = f.Dest(); BoxRayIntersection(points[f.triangle.id], tdest.y - torg.y, torg.x - tdest.x, out intersection); // Set the correct id for the vertex intersection.id = n + rayIndex; points[n + rayIndex] = intersection; rayIndex++; vpoints.Add(intersection); rayPoints.Add(sid, intersection); } // Add the new points to the region (in counter-clockwise order) vpoints.Reverse(); region.Add(vpoints); }
private void ConstructVoronoiRegion(Vertex vertex) { Vertex vertex1; Vertex vertex2; VoronoiRegion voronoiRegion = new VoronoiRegion(vertex); this.regions.Add(voronoiRegion); List <Point> points = new List <Point>(); Otri otri = new Otri(); Otri otri1 = new Otri(); Otri otri2 = new Otri(); Otri otri3 = new Otri(); Osub osub = new Osub(); vertex.tri.Copy(ref otri1); otri1.Copy(ref otri); otri1.Onext(ref otri2); if (otri2.triangle == Mesh.dummytri) { otri1.Oprev(ref otri3); if (otri3.triangle != Mesh.dummytri) { otri1.Copy(ref otri2); otri1.OprevSelf(); otri1.Copy(ref otri); } } while (otri2.triangle != Mesh.dummytri) { points.Add(this.points[otri.triangle.id]); if (otri2.Equal(otri1)) { voronoiRegion.Add(points); return; } otri2.Copy(ref otri); otri2.OnextSelf(); } voronoiRegion.Bounded = false; int count = this.mesh.triangles.Count; otri.Lprev(ref otri2); otri2.SegPivot(ref osub); int num = osub.seg.hash; points.Add(this.points[otri.triangle.id]); if (!this.rayPoints.ContainsKey(num)) { vertex1 = otri.Org(); Vertex vertex3 = otri.Apex(); this.BoxRayIntersection(this.points[otri.triangle.id], vertex1.y - vertex3.y, vertex3.x - vertex1.x, out vertex2); vertex2.id = count + this.rayIndex; this.points[count + this.rayIndex] = vertex2; this.rayIndex = this.rayIndex + 1; points.Add(vertex2); this.rayPoints.Add(num, vertex2); } else { points.Add(this.rayPoints[num]); } points.Reverse(); otri1.Copy(ref otri); otri.Oprev(ref otri3); while (otri3.triangle != Mesh.dummytri) { points.Add(this.points[otri3.triangle.id]); otri3.Copy(ref otri); otri3.OprevSelf(); } otri.SegPivot(ref osub); num = osub.seg.hash; if (!this.rayPoints.ContainsKey(num)) { vertex1 = otri.Org(); Vertex vertex4 = otri.Dest(); this.BoxRayIntersection(this.points[otri.triangle.id], vertex4.y - vertex1.y, vertex1.x - vertex4.x, out vertex2); vertex2.id = count + this.rayIndex; this.points[count + this.rayIndex] = vertex2; this.rayIndex = this.rayIndex + 1; points.Add(vertex2); this.rayPoints.Add(num, vertex2); } else { points.Add(this.rayPoints[num]); } points.Reverse(); voronoiRegion.Add(points); }
private void ConstructBvdCell(Vertex vertex) { VoronoiRegion region = new VoronoiRegion(vertex); regions.Add(region); Otri f = default(Otri); Otri f_init = default(Otri); Otri f_next = default(Otri); Osub sf = default(Osub); Osub sfn = default(Osub); Point cc_f, cc_f_next, p; int n = mesh.triangles.Count; // Call P the polygon (cell) in construction List<Point> vpoints = new List<Point>(); // Call f_init a triangle incident to x vertex.tri.Copy(ref f_init); if (f_init.Org() != vertex) { throw new Exception("ConstructBvdCell: inconsistent topology."); } // Let f be initialized to f_init f_init.Copy(ref f); // Call f_next the next triangle counterclockwise around x f_init.Onext(ref f_next); // repeat ... until f = f_init do { // Call Lffnext the line going through the circumcenters of f and f_next cc_f = this.points[f.triangle.id]; cc_f_next = this.points[f_next.triangle.id]; // if f is tagged non-blind then if (!f.triangle.infected) { // Insert the circumcenter of f into P vpoints.Add(cc_f); if (f_next.triangle.infected) { // Call S_fnext the constrained edge blinding f_next sfn.seg = subsegMap[f_next.triangle.hash]; // Insert point Lf,f_next /\ Sf_next into P if (SegmentsIntersect(sfn.SegOrg(), sfn.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } } else { // Call Sf the constrained edge blinding f sf.seg = subsegMap[f.triangle.hash]; // if f_next is tagged non-blind then if (!f_next.triangle.infected) { // Insert point Lf,f_next /\ Sf into P if (SegmentsIntersect(sf.SegOrg(), sf.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } else { // Call Sf_next the constrained edge blinding f_next sfn.seg = subsegMap[f_next.triangle.hash]; // if Sf != Sf_next then if (!sf.Equal(sfn)) { // Insert Lf,fnext /\ Sf and Lf,fnext /\ Sfnext into P if (SegmentsIntersect(sf.SegOrg(), sf.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } if (SegmentsIntersect(sfn.SegOrg(), sfn.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } } } // f <- f_next f_next.Copy(ref f); // Call f_next the next triangle counterclockwise around x f_next.OnextSelf(); } while (!f.Equal(f_init)); // Output: Bounded Voronoi cell of x in counterclockwise order. region.Add(vpoints); }
private void ConstructBoundaryBvdCell(Vertex vertex) { VoronoiRegion region = new VoronoiRegion(vertex); regions.Add(region); Otri f = default(Otri); Otri f_init = default(Otri); Otri f_next = default(Otri); Otri f_prev = default(Otri); Osub sf = default(Osub); Osub sfn = default(Osub); Vertex torg, tdest, tapex, sorg, sdest; Point cc_f, cc_f_next, p; int n = mesh.triangles.Count; // Call P the polygon (cell) in construction List <Point> vpoints = new List <Point>(); // Call f_init a triangle incident to x vertex.tri.Copy(ref f_init); if (f_init.Org() != vertex) { throw new Exception("ConstructBoundaryBvdCell: inconsistent topology."); } // Let f be initialized to f_init f_init.Copy(ref f); // Call f_next the next triangle counterclockwise around x f_init.Onext(ref f_next); f_init.Oprev(ref f_prev); // Is the border to the left? if (f_prev.triangle != Mesh.dummytri) { // Go clockwise until we reach the border (or the initial triangle) while (f_prev.triangle != Mesh.dummytri && !f_prev.Equal(f_init)) { f_prev.Copy(ref f); f_prev.OprevSelf(); } f.Copy(ref f_init); f.Onext(ref f_next); } if (f_prev.triangle == Mesh.dummytri) { // For vertices on the domain boundaray, add the vertex. For // internal boundaries don't add it. p = new Point(vertex.x, vertex.y); p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } // Add midpoint of start triangles' edge. torg = f.Org(); tdest = f.Dest(); p = new Point((torg.X + tdest.X) / 2, (torg.Y + tdest.Y) / 2); p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); // repeat ... until f = f_init do { // Call Lffnext the line going through the circumcenters of f and f_next cc_f = this.points[f.triangle.id]; if (f_next.triangle == Mesh.dummytri) { if (!f.triangle.infected) { // Add last circumcenter vpoints.Add(cc_f); } // Add midpoint of last triangles' edge (chances are it has already // been added, so post process cell to remove duplicates???) torg = f.Org(); tapex = f.Apex(); p = new Point((torg.X + tapex.X) / 2, (torg.Y + tapex.Y) / 2); p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); break; } cc_f_next = this.points[f_next.triangle.id]; // if f is tagged non-blind then if (!f.triangle.infected) { // Insert the circumcenter of f into P vpoints.Add(cc_f); if (f_next.triangle.infected) { // Call S_fnext the constrained edge blinding f_next sfn.seg = subsegMap[f_next.triangle.hash]; // Insert point Lf,f_next /\ Sf_next into P if (SegmentsIntersect(sfn.SegOrg(), sfn.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } } else { // Call Sf the constrained edge blinding f sf.seg = subsegMap[f.triangle.hash]; sorg = sf.SegOrg(); sdest = sf.SegDest(); // if f_next is tagged non-blind then if (!f_next.triangle.infected) { tdest = f.Dest(); tapex = f.Apex(); // Both circumcenters lie on the blinded side, but we // have to add the intersection with the segment. // Center of f edge dest->apex Point bisec = new Point((tdest.X + tapex.X) / 2, (tdest.Y + tapex.Y) / 2); // Find intersection of seg with line through f's bisector and circumcenter if (SegmentsIntersect(sorg, sdest, bisec, cc_f, out p, false)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } // Insert point Lf,f_next /\ Sf into P if (SegmentsIntersect(sorg, sdest, cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } else { // Call Sf_next the constrained edge blinding f_next sfn.seg = subsegMap[f_next.triangle.hash]; // if Sf != Sf_next then if (!sf.Equal(sfn)) { // Insert Lf,fnext /\ Sf and Lf,fnext /\ Sfnext into P if (SegmentsIntersect(sorg, sdest, cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } if (SegmentsIntersect(sfn.SegOrg(), sfn.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } else { // Both circumcenters lie on the blinded side, but we // have to add the intersection with the segment. // Center of f_next edge org->dest Point bisec = new Point((torg.X + tdest.X) / 2, (torg.Y + tdest.Y) / 2); // Find intersection of seg with line through f_next's bisector and circumcenter if (SegmentsIntersect(sorg, sdest, bisec, cc_f_next, out p, false)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } } } // f <- f_next f_next.Copy(ref f); // Call f_next the next triangle counterclockwise around x f_next.OnextSelf(); }while (!f.Equal(f_init)); // Output: Bounded Voronoi cell of x in counterclockwise order. region.Add(vpoints); }
private void ConstructBvdCell(Vertex vertex) { VoronoiRegion region = new VoronoiRegion(vertex); regions.Add(region); Otri f = default(Otri); Otri f_init = default(Otri); Otri f_next = default(Otri); Osub sf = default(Osub); Osub sfn = default(Osub); Point cc_f, cc_f_next, p; int n = mesh.triangles.Count; // Call P the polygon (cell) in construction List <Point> vpoints = new List <Point>(); // Call f_init a triangle incident to x vertex.tri.Copy(ref f_init); if (f_init.Org() != vertex) { throw new Exception("ConstructBvdCell: inconsistent topology."); } // Let f be initialized to f_init f_init.Copy(ref f); // Call f_next the next triangle counterclockwise around x f_init.Onext(ref f_next); // repeat ... until f = f_init do { // Call Lffnext the line going through the circumcenters of f and f_next cc_f = this.points[f.triangle.id]; cc_f_next = this.points[f_next.triangle.id]; // if f is tagged non-blind then if (!f.triangle.infected) { // Insert the circumcenter of f into P vpoints.Add(cc_f); if (f_next.triangle.infected) { // Call S_fnext the constrained edge blinding f_next sfn.seg = subsegMap[f_next.triangle.hash]; // Insert point Lf,f_next /\ Sf_next into P if (SegmentsIntersect(sfn.SegOrg(), sfn.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } } else { // Call Sf the constrained edge blinding f sf.seg = subsegMap[f.triangle.hash]; // if f_next is tagged non-blind then if (!f_next.triangle.infected) { // Insert point Lf,f_next /\ Sf into P if (SegmentsIntersect(sf.SegOrg(), sf.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } else { // Call Sf_next the constrained edge blinding f_next sfn.seg = subsegMap[f_next.triangle.hash]; // if Sf != Sf_next then if (!sf.Equal(sfn)) { // Insert Lf,fnext /\ Sf and Lf,fnext /\ Sfnext into P if (SegmentsIntersect(sf.SegOrg(), sf.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } if (SegmentsIntersect(sfn.SegOrg(), sfn.SegDest(), cc_f, cc_f_next, out p, true)) { p.id = n + segIndex; points[n + segIndex] = p; segIndex++; vpoints.Add(p); } } } } // f <- f_next f_next.Copy(ref f); // Call f_next the next triangle counterclockwise around x f_next.OnextSelf(); }while (!f.Equal(f_init)); // Output: Bounded Voronoi cell of x in counterclockwise order. region.Add(vpoints); }
private void ConstructBoundaryBvdCell(Vertex vertex) { Vertex vertex1; Point point; VoronoiRegion voronoiRegion = new VoronoiRegion(vertex); this.regions.Add(voronoiRegion); Otri otri = new Otri(); Otri otri1 = new Otri(); Otri otri2 = new Otri(); Otri otri3 = new Otri(); Osub item = new Osub(); Osub osub = new Osub(); int count = this.mesh.triangles.Count; List <Point> points = new List <Point>(); vertex.tri.Copy(ref otri1); if (otri1.Org() != vertex) { throw new Exception("ConstructBoundaryBvdCell: inconsistent topology."); } otri1.Copy(ref otri); otri1.Onext(ref otri2); otri1.Oprev(ref otri3); if (otri3.triangle != Mesh.dummytri) { while (otri3.triangle != Mesh.dummytri && !otri3.Equal(otri1)) { otri3.Copy(ref otri); otri3.OprevSelf(); } otri.Copy(ref otri1); otri.Onext(ref otri2); } if (otri3.triangle == Mesh.dummytri) { point = new Point(vertex.x, vertex.y) { id = count + this.segIndex }; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } Vertex vertex2 = otri.Org(); Vertex vertex3 = otri.Dest(); point = new Point((vertex2.X + vertex3.X) / 2, (vertex2.Y + vertex3.Y) / 2) { id = count + this.segIndex }; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); do { Point point1 = this.points[otri.triangle.id]; if (otri2.triangle != Mesh.dummytri) { Point point2 = this.points[otri2.triangle.id]; if (otri.triangle.infected) { item.seg = this.subsegMap[otri.triangle.hash]; Vertex vertex4 = item.SegOrg(); Vertex vertex5 = item.SegDest(); if (otri2.triangle.infected) { osub.seg = this.subsegMap[otri2.triangle.hash]; if (!item.Equal(osub)) { if (this.SegmentsIntersect(vertex4, vertex5, point1, point2, out point, true)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } if (this.SegmentsIntersect(osub.SegOrg(), osub.SegDest(), point1, point2, out point, true)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } } else if (this.SegmentsIntersect(vertex4, vertex5, new Point((vertex2.X + vertex3.X) / 2, (vertex2.Y + vertex3.Y) / 2), point2, out point, false)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } } else { vertex3 = otri.Dest(); vertex1 = otri.Apex(); if (this.SegmentsIntersect(vertex4, vertex5, new Point((vertex3.X + vertex1.X) / 2, (vertex3.Y + vertex1.Y) / 2), point1, out point, false)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } if (this.SegmentsIntersect(vertex4, vertex5, point1, point2, out point, true)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } } } else { points.Add(point1); if (otri2.triangle.infected) { osub.seg = this.subsegMap[otri2.triangle.hash]; if (this.SegmentsIntersect(osub.SegOrg(), osub.SegDest(), point1, point2, out point, true)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } } } otri2.Copy(ref otri); otri2.OnextSelf(); } else { if (!otri.triangle.infected) { points.Add(point1); } vertex2 = otri.Org(); vertex1 = otri.Apex(); point = new Point((vertex2.X + vertex1.X) / 2, (vertex2.Y + vertex1.Y) / 2) { id = count + this.segIndex }; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); break; } }while (!otri.Equal(otri1)); voronoiRegion.Add(points); }
private void ConstructBvdCell(Vertex vertex) { Point point; VoronoiRegion voronoiRegion = new VoronoiRegion(vertex); this.regions.Add(voronoiRegion); Otri otri = new Otri(); Otri otri1 = new Otri(); Otri otri2 = new Otri(); Osub item = new Osub(); Osub osub = new Osub(); int count = this.mesh.triangles.Count; List <Point> points = new List <Point>(); vertex.tri.Copy(ref otri1); if (otri1.Org() != vertex) { throw new Exception("ConstructBvdCell: inconsistent topology."); } otri1.Copy(ref otri); otri1.Onext(ref otri2); do { Point point1 = this.points[otri.triangle.id]; Point point2 = this.points[otri2.triangle.id]; if (otri.triangle.infected) { item.seg = this.subsegMap[otri.triangle.hash]; if (otri2.triangle.infected) { osub.seg = this.subsegMap[otri2.triangle.hash]; if (!item.Equal(osub)) { if (this.SegmentsIntersect(item.SegOrg(), item.SegDest(), point1, point2, out point, true)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } if (this.SegmentsIntersect(osub.SegOrg(), osub.SegDest(), point1, point2, out point, true)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } } } else if (this.SegmentsIntersect(item.SegOrg(), item.SegDest(), point1, point2, out point, true)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } } else { points.Add(point1); if (otri2.triangle.infected) { osub.seg = this.subsegMap[otri2.triangle.hash]; if (this.SegmentsIntersect(osub.SegOrg(), osub.SegDest(), point1, point2, out point, true)) { point.id = count + this.segIndex; this.points[count + this.segIndex] = point; this.segIndex = this.segIndex + 1; points.Add(point); } } } otri2.Copy(ref otri); otri2.OnextSelf(); }while (!otri.Equal(otri1)); voronoiRegion.Add(points); }
internal void AddNeighbor(int id, VoronoiRegion neighbor) { this.neighbors.Add(id, neighbor); }