public void TestSample_0(string gameObjectName, AllPointsSampler.Configuration.NormalProcessing normalProcessing) { EditorSceneManager.OpenScene(sceneName); //The 'default' child of a mesh contains the stuff we are interested in GameObject gameObject = GameObject.Find(gameObjectName).transform.GetChild(0).gameObject; DoubleConnectedEdgeListStorage dcelStorage = gameObject.GetComponent <DoubleConnectedEdgeListStorage>(); dcelStorage.DCEL = DCEL.FromMesh(gameObject.GetComponent <MeshFilter>().sharedMesh); SamplingInformation samplingInformation = new SamplingInformation(gameObject); RandomSubSampling.Configuration config = new RandomSubSampling.Configuration( referenceTransform: gameObject.transform.root, normalProcessing: normalProcessing, percentage: 0 ); SamplingInformation samplingInfo = new SamplingInformation(gameObject); List <Point> expected = new List <Point>(); List <Point> actual = new RandomSubSampling(config).Sample(samplingInfo); Assert.That(actual, Is.EquivalentTo(expected)); }
public void TestSample(string gameObjectname, float percentage, int expectedSampleSize, AllPointsSampler.Configuration.NormalProcessing normalProcessing) { EditorSceneManager.OpenScene(sceneName); //The 'default' child of a mesh contains the stuff we are interested in GameObject gameObject = GameObject.Find(gameObjectname).transform.GetChild(0).gameObject; DoubleConnectedEdgeListStorage dcelStorage = gameObject.GetComponent <DoubleConnectedEdgeListStorage>(); dcelStorage.DCEL = DCEL.FromMesh(gameObject.GetComponent <MeshFilter>().sharedMesh); SamplingInformation samplingInformation = new SamplingInformation(gameObject); RandomSubSampling.Configuration randomConfig = new RandomSubSampling.Configuration( referenceTransform: gameObject.transform.root, normalProcessing: normalProcessing, percentage: percentage ); SamplingInformation samplingInfo = new SamplingInformation(gameObject); AllPointsSampler.Configuration allPointsConfig = new AllPointsSampler.Configuration( referenceTransform: gameObject.transform.root, normalProcessing: normalProcessing ); List <Point> allPoints = new AllPointsSampler(allPointsConfig).Sample(samplingInfo); List <Point> actual = new RandomSubSampling(randomConfig).Sample(samplingInfo); Assert.AreEqual(expectedSampleSize, actual.Count); Assert.That(actual, Is.SubsetOf(allPoints)); bool allUnique = actual.GroupBy(x => x).All(g => g.Count() == 1); Assert.IsTrue(allUnique); }
/// <summary> /// Find cut lines that separates all point sets equally. /// Generates dcel of dual lines and generates cut lines through intersection of middle faces. /// </summary> /// <param name="a_points1"></param> /// <param name="a_points2"></param> /// <param name="a_points3"></param> /// <returns></returns> public static List <Line> FindCutLines(IEnumerable <Vector2> a_points1, IEnumerable <Vector2> a_points2, IEnumerable <Vector2> a_points3) { // obtain dual lines for game objects var lines1 = PointLineDual.Dual(a_points1); var lines2 = PointLineDual.Dual(a_points2); var lines3 = PointLineDual.Dual(a_points3); // add lines together var allLines = lines1.Concat(lines2.Concat(lines3)); // calculate bounding box around line intersections with some margin var bBox = BoundingBoxComputer.FromLines(allLines, 10f); // calculate dcel for line inside given bounding box var dcel1 = new DCEL(lines1, bBox); var dcel2 = new DCEL(lines2, bBox); var dcel3 = new DCEL(lines3, bBox); // find faces in the middle of the lines vertically var archerFaces = MiddleFaces(dcel1, lines1); var swordsmenFaces = MiddleFaces(dcel2, lines2); var mageFaces = MiddleFaces(dcel3, lines3); // obtain cut lines for the dcel middle faces return(FindCutlinesInDual(archerFaces, swordsmenFaces, mageFaces)); }
public TriangulatorTest() { m_topVertex = new Vector2(0, 1); m_botVertex = new Vector2(0, -1); m_leftVertex = new Vector2(-1, 0); m_rightVertex = new Vector2(1, 0); m_farRightVertex = new Vector2(2, 0); m_arrowVertices = new List <Vector2>() { m_topVertex, m_farRightVertex, m_botVertex, m_rightVertex }; m_diamondVertices = new List <Vector2>() { m_topVertex, m_rightVertex, m_botVertex, m_leftVertex }; m_arrow = new Polygon2D(m_arrowVertices); m_diamond = new Polygon2D(m_diamondVertices); var lines = new List <Line>() { new Line(-1, 3), new Line(2, 0) }; var rect = new Rect(-5, -5, 10, 10); m_dcel = new DCEL(lines, rect); }
/// <summary> /// Finds a number of solutions for the cut problem. Both per type of soldier and for all soldiers. /// /// NOTE: only works if the x coords of all things are all positive or all negative /// </summary> public void FindSolution() { // obtain dual lines for game objects m_archerLines = PointLineDual.Dual(m_archers.Select(x => (Vector2)x.transform.position)).ToList(); m_spearmenLines = PointLineDual.Dual(m_spearmen.Select(x => (Vector2)x.transform.position)).ToList(); m_mageLines = PointLineDual.Dual(m_mages.Select(x => (Vector2)x.transform.position)).ToList(); // add lines together var allLines = m_archerLines.Concat(m_spearmenLines.Concat(m_mageLines)); // calculate bounding box around line intersections with some margin var bBox = BoundingBoxComputer.FromLines(allLines, 10f); // calculate dcel for line inside given bounding box m_archerDcel = new DCEL(m_archerLines, bBox); m_spearmenDcel = new DCEL(m_spearmenLines, bBox); m_mageDcel = new DCEL(m_mageLines, bBox); // find faces in the middle of the lines vertically m_archerFaces = HamSandwich.MiddleFaces(m_archerDcel, m_archerLines); m_spearmenFaces = HamSandwich.MiddleFaces(m_spearmenDcel, m_spearmenLines); m_mageFaces = HamSandwich.MiddleFaces(m_mageDcel, m_mageLines); // obtain cut lines for the dcel middle faces and final possible cutlines m_solution = new DivideSolution(HamSandwich.FindCutlinesInDual(m_archerFaces), HamSandwich.FindCutlinesInDual(m_spearmenFaces), HamSandwich.FindCutlinesInDual(m_mageFaces), HamSandwich.FindCutlinesInDual(m_archerFaces, m_spearmenFaces, m_mageFaces)); // update solution to the drawer m_lineDrawer.Solution = m_solution; }
/// <summary> /// Creates new voronoi and updates mesh and player area. /// </summary> private void UpdateVoronoi() { // create voronoi diagram from delaunay triangulation m_DCEL = Voronoi.Create(m_delaunay); UpdateMesh(); UpdatePlayerAreaOwned(); }
// Random endless level generation // Determines the amount of shepherds placed based on the current level number private ShepherdLevel CreateEndlessLevel(int level) { // create the output scriptable object var asset = ScriptableObject.CreateInstance <ShepherdLevel>(); // place the shepherds and sheep randomly List <Vector2> shepherds = RandomPos(level + 4); List <Vector2> sheep = RandomPos(2 * (level + 4)); // Print locations string sls = "Shepherd locations: \n"; foreach (Vector2 v in shepherds) { sls += "(" + v.x + ", " + v.y + "), "; } Debug.Log(sls); string shls = "Sheep locations: \n"; foreach (Vector2 v in sheep) { shls += "(" + v.x + ", " + v.y + "), "; } Debug.Log(shls); // Construct the voronoi diagram corresponding to the shepherd locations StartVoronoi(); foreach (Vector2 me in shepherds) { // Add vertex to the triangulation and update the voronoi Delaunay.AddVertex(m_delaunay, me); m_delaunay.SetOwner(me, Random.Range(0, 4)); m_dcel = Voronoi.Create(m_delaunay); } // Create vertical decomposition VerticalDecomposition vd = VertDecomp(m_dcel); // Use the vertical decomposition to determine the ownership of each sheep // and add the sheep to the level foreach (Vector2 s in sheep) { Trapezoid trap = vd.Search(s); Face area = trap.bottom.face; int i = area.owner; asset.addSheep(s, i); } // Normalize coordinates var rect = BoundingBoxComputer.FromPoints(asset.SheepList); asset.SheepList = Normalize(rect, 6f, asset.SheepList); // Set shepherd budget asset.setBudget(shepherds.Count); return(asset); }
static void Main(string[] args) { DCEL <Vector2> dcel = new DCEL <Vector2>("test", "this is a test"); List <VectorBase> vectors = new List <VectorBase>(); vectors.Add(new Vector2(3.0d, 4.5d)); dcel.AddVertex(vectors[0] as Vector2); }
/// <summary> /// Creates a Voronoi DCEL from a triangulation. Triangulation should be Delaunay /// </summary> /// <param name="m_Delaunay"></param> /// <returns></returns> public static DCEL Create(Triangulation m_Delaunay) { if (!Delaunay.IsValid(m_Delaunay)) { throw new GeomException("Triangulation should be delaunay for the Voronoi diagram."); } var dcel = new DCEL(); // create vertices for each triangles circumcenter and store them in a dictionary Dictionary <Triangle, DCELVertex> vertexMap = new Dictionary <Triangle, DCELVertex>(); foreach (var triangle in m_Delaunay.Triangles) { // degenerate triangle, just ignore if (!triangle.Circumcenter.HasValue) { continue; } var vertex = new DCELVertex(triangle.Circumcenter.Value); dcel.AddVertex(vertex); vertexMap.Add(triangle, vertex); } // remember which edges where visited // since each edge has a twin var edgesVisited = new HashSet <TriangleEdge>(); foreach (var edge in m_Delaunay.Edges) { // either already visited twin edge or edge is outer triangle if (edgesVisited.Contains(edge) || edge.IsOuter) { continue; } // add edge between the two adjacent triangles vertices // vertices at circumcenter of triangle if (edge.T != null && edge.Twin.T != null) { var v1 = vertexMap[edge.T]; var v2 = vertexMap[edge.Twin.T]; HalfEdge e1 = dcel.AddEdge(v1, v2); e1.Twin.Face.owner = m_Delaunay.GetOwner(edge.Point1); e1.Face.owner = m_Delaunay.GetOwner(edge.Point2); edgesVisited.Add(edge); edgesVisited.Add(edge.Twin); } } return(dcel); }
public void DCELFromBboxTest() { var rect = new Rect(-1, -1, 2, 2); var dcel = new DCEL(rect); Assert.AreEqual(4, dcel.VertexCount); Assert.AreEqual(4, dcel.EdgeCount); Assert.AreEqual(2, dcel.FaceCount); Assert.AreEqual(1, dcel.OuterFace.InnerComponents.Count()); }
public void EmptyDCELTest() { var dcel = new DCEL(); Assert.Zero(dcel.VertexCount); Assert.Zero(dcel.EdgeCount); Assert.AreEqual(1, dcel.FaceCount); Assert.Zero(dcel.InnerFaces.Count()); Assert.Zero(dcel.OuterFace.InnerComponents.Count()); }
public void FindVertexTest() { var dcel = new DCEL(); var v1 = dcel.AddVertex(new DCELVertex(1, -1)); DCELVertex v2; Assert.IsTrue(dcel.FindVertex(new Vector2(1, -1), out v2)); Assert.AreEqual(v1, v2); Assert.IsFalse(dcel.FindVertex(new Vector2(0, 0), out v2)); Assert.IsNull(v2); }
private static void drawDCEL(DCEL dcel) { GL.Begin(GL.LINES); GL.Color(Color.black); foreach (HalfEdge halfEdge in dcel.Edges) { GL.Vertex3(halfEdge.From.Pos.x, halfEdge.From.Pos.y, 0); GL.Vertex3(halfEdge.To.Pos.x, halfEdge.To.Pos.y, 0); } GL.End(); }
/* * Given an Voronoi diagram in DCEL format: * Extract all edges and map them to LineSegments * Store with each segment the shepherd above it * Incrementally add each segment to the vertical decomposition */ public VerticalDecomposition(DCEL InGraph, MeshFilter m_meshFilter) { // *** Initialize vertical decomposition with one trapezoid containing the entire canvas *** // Determine bounding box corners float width = 10000; float height = 10000; LineSegment bottom = new LineSegment(new Vector2(-width, -height), new Vector2(width, -height), null); LineSegment top = new LineSegment(new Vector2(-width, height), new Vector2(width, height), null); // Create initial trapezoid and root of searchtree Trapezoid inital_trapezoid = new Trapezoid(new Vector2(-width, height), new Vector2(width, -height), top, bottom); traps.Add(inital_trapezoid); this.TreeRoot = new SearchNode(inital_trapezoid); inital_trapezoid.SetLeaf(TreeRoot); // *** Add all edges to the vertical decomposition *** // Randomize the collection of half-edges ICollection <HalfEdge> c_edges = InGraph.Edges; List <HalfEdge> temp_edges = new List <HalfEdge>(); List <HalfEdge> edges = new List <HalfEdge>(); foreach (HalfEdge edge in c_edges) { temp_edges.Add(edge); } for (int i = 0; i < c_edges.Count; i++) { int randomIndex = Random.Range(0, temp_edges.Count); //Choose a random object in the list edges.Add(temp_edges[randomIndex]); //add it to the new, random list temp_edges.RemoveAt(randomIndex); //remove to avoid duplicates } Debug.Log("Adding voronoi with " + edges.Count + " halfedges"); // Transform all DCEL edges into Linesegments foreach (HalfEdge edge in edges) { // Only add half-edges whose face is above it // So only add half-edges whose to-vertex is to the right of the from-vertex // So skip half-edges where 'to' has smaller x value than 'from' if (edge.To.Pos.x > edge.From.Pos.x) { continue; } if (edge.To.Pos.x == edge.From.Pos.x && edge.To.Pos.y <= edge.From.Pos.y) { continue; } LineSegment segment = new LineSegment(edge.From.Pos, edge.To.Pos, edge.Face); Debug.Log("Inserting segment: " + segment.show()); this.Insert(segment); } }
public void AddEdgeTest() { var dcel = new DCEL(); var v1 = dcel.AddVertex(new DCELVertex(0, 0)); var v2 = dcel.AddVertex(new Vector2(2, 2)); dcel.AddEdge(v1, v2); Assert.AreEqual(1, dcel.EdgeCount); dcel.AddEdge(new Vector2(0, 2), new Vector2(2, 0)); Assert.AreEqual(4, dcel.EdgeCount); Assert.Throws <GeomException>(() => dcel.AddEdge(new DCELVertex(-1, -1), v1)); }
public void AreaTest() { var segs = new List <LineSegment> { new LineSegment(new Vector2(-1, 0), new Vector2(1, 0)) }; var dcel = new DCEL(segs, new Rect(-1, -1, 2, 2)); foreach (var face in dcel.InnerFaces) { Assert.AreEqual(2f, face.Area); } }
public HamSandwichTest() { m_points = new List <Vector2>() { new Vector2(1, -2), new Vector2(2, 0), new Vector2(5, 5), new Vector2(-3, -1) }; m_lines = new List <Line>() { new Line(1, 2), new Line(2, 0), new Line(5, -5), new Line(-3, 1) }; m_rect = BoundingBoxComputer.FromLines(m_lines, 10f); m_dcel = new DCEL(m_lines, m_rect); m_points1 = new List <Vector2>() { new Vector2(-1, 1), new Vector2(2, -1) }; m_points2 = new List <Vector2>() { new Vector2(3, 2), new Vector2(3.5f, 0) }; m_points3 = new List <Vector2>() { new Vector2(-3, 1), new Vector2(-3.4f, -3) }; m_lines1 = new List <Line>() { new Line(-1, -1), new Line(2, 1) }; m_lines2 = new List <Line>() { new Line(3, -2), new Line(3.5f, 0) }; m_lines3 = new List <Line>() { new Line(-3, -1), new Line(-3.4f, 3) }; m_allLines = m_lines1.Concat(m_lines2.Concat(m_lines3)).ToList(); m_rect = BoundingBoxComputer.FromLines(m_allLines, 10f); m_dcel1 = new DCEL(m_lines1, m_rect); m_dcel2 = new DCEL(m_lines2, m_rect); m_dcel3 = new DCEL(m_lines3, m_rect); }
public void GetContainingFaceTest() { var dcel = new DCEL(); var v1 = dcel.AddVertex(new DCELVertex(0, 0)); var v2 = dcel.AddVertex(new DCELVertex(10, 10)); var v3 = dcel.AddVertex(new DCELVertex(20, 0)); dcel.AddEdge(v1, v2); dcel.AddEdge(v2, v3); dcel.AddEdge(v3, v1); var expFace = dcel.InnerFaces.FirstOrDefault(); Assert.AreEqual(expFace, dcel.GetContainingFace(new Vector2(10, 5))); Assert.AreEqual(dcel.OuterFace, dcel.GetContainingFace(new Vector2(-1, 0))); }
public void DCELFromLinesTest() { var rect = new Rect(new Vector2(-1, -1), new Vector2(2, 2)); var lines = new List <Line>() { new Line(new Vector2(-1, 0), new Vector2(1, 0)), new Line(new Vector2(0, -1), new Vector2(0, 1)) }; var dcel = new DCEL(lines, rect); Assert.AreEqual(9, dcel.VertexCount); Assert.AreEqual(12, dcel.EdgeCount); Assert.AreEqual(5, dcel.FaceCount); Assert.AreEqual(1, dcel.OuterFace.InnerComponents.Count()); }
public static List <Line> FindCutLines(IEnumerable <Vector2> a_points) { // obtain dual lines for points var lines = PointLineDual.Dual(a_points); // calculate bounding box around line intersections with some margin var bBox = BoundingBoxComputer.FromLines(lines, 10f); // calculate dcel for line inside given bounding box var m_dcel = new DCEL(lines, bBox); // find faces in the middle of the lines vertically and calculate cut lines var faces = MiddleFaces(m_dcel, lines); return(FindCutlinesInDual(faces)); }
public void ConstructionTest() { var segs = new List <LineSegment> { new LineSegment(new Vector2(-1, -1), new Vector2(1, 1)) }; var dcel = new DCEL(segs, new Rect(-1, -1, 2, 2)); Assert.AreEqual(4, dcel.OuterFace.InnerHalfEdges.Count()); Assert.AreEqual(2, dcel.InnerFaces.Count()); foreach (var f in dcel.InnerFaces) { Assert.AreEqual(3, f.Polygon.Vertices.Count()); } }
public void AddVertexInEdgeTest() { var dcel = new DCEL(); var v1 = dcel.AddVertex(new DCELVertex(0, 0)); var v2 = dcel.AddVertex(new Vector2(2, 2)); var e = dcel.AddEdge(v1, v2); var v3 = dcel.AddVertexInEdge(e, new Vector2(1.5f, 1.5f)); Assert.AreEqual(3, dcel.VertexCount); Assert.AreEqual(2, dcel.EdgeCount); var e2 = new HalfEdge(v3, v1); Assert.Throws <GeomException>(() => dcel.AddVertexInEdge(e2, v3.Pos)); Assert.Throws <GeomException>(() => dcel.AddVertexInEdge(e, new Vector2(-1, -1))); }
public void AddVertexTest() { var dcel = new DCEL(); var v1 = dcel.AddVertex(new DCELVertex(0, 0)); var v2 = dcel.AddVertex(new Vector2(2, 2)); Assert.AreEqual(2, dcel.VertexCount); // vertex on edge test var e = dcel.AddEdge(v1, v2); Assert.AreEqual(e, v1.Leaving); Assert.AreEqual(e.Twin, v2.Leaving); dcel.AddVertex(new Vector2(1, 1)); Assert.AreEqual(3, dcel.VertexCount); Assert.AreEqual(2, dcel.EdgeCount); }
public void Start() { if (CLI.Instance.CLIModeActive) { Destroy(this); } Normal.MagnitudeFactor = normalScale; normals = new List <Normal>(); DCEL dcel = GetComponent <DoubleConnectedEdgeListStorage>().DCEL; foreach (Face face in dcel.Faces) { normals.Add(Normal.FaceNormal(face)); } }
public void AdjacentEdgesTest() { var dcel = new DCEL(); var v1 = dcel.AddVertex(new DCELVertex(0, 0)); var v2 = dcel.AddVertex(new DCELVertex(10, 10)); var v3 = dcel.AddVertex(new DCELVertex(20, 0)); dcel.AddEdge(v1, v2); dcel.AddEdge(v2, v3); Assert.AreEqual(2, dcel.AdjacentEdges(v1).Count); Assert.AreEqual(4, dcel.AdjacentEdges(v2).Count); Assert.AreEqual(2, dcel.AdjacentEdges(v3).Count); Assert.AreEqual(1, dcel.OutgoingEdges(v1).Count); Assert.AreEqual(2, dcel.OutgoingEdges(v2).Count); Assert.AreEqual(1, dcel.OutgoingEdges(v3).Count); }
public void InnerFacesTest() { var dcel = new DCEL(); // create large triangle var v1 = dcel.AddVertex(new DCELVertex(0, 0)); var v2 = dcel.AddVertex(new DCELVertex(10, 10)); var v3 = dcel.AddVertex(new DCELVertex(20, 0)); dcel.AddEdge(v1, v2); dcel.AddEdge(v2, v3); dcel.AddEdge(v3, v1); // create smaller inner triangle var v4 = dcel.AddVertex(new DCELVertex(9, 2)); var v5 = dcel.AddVertex(new DCELVertex(10, 3)); var v6 = dcel.AddVertex(new DCELVertex(11, 2)); dcel.AddEdge(v4, v5); dcel.AddEdge(v5, v6); dcel.AddEdge(v6, v4); Assert.AreEqual(6, dcel.VertexCount); Assert.AreEqual(6, dcel.EdgeCount); Assert.AreEqual(3, dcel.FaceCount); Assert.AreEqual(1, dcel.OuterFace.InnerComponents.Count); Assert.AreEqual(1, dcel.InnerFaces.FirstOrDefault().InnerComponents.Count); // create outside triangle // create smaller inner triangle var v7 = dcel.AddVertex(new DCELVertex(-1, -1)); var v8 = dcel.AddVertex(new DCELVertex(-2, -2)); var v9 = dcel.AddVertex(new DCELVertex(-3, -1)); dcel.AddEdge(v7, v8); dcel.AddEdge(v8, v9); dcel.AddEdge(v9, v7); Assert.AreEqual(9, dcel.VertexCount); Assert.AreEqual(9, dcel.EdgeCount); Assert.AreEqual(4, dcel.FaceCount); Assert.AreEqual(2, dcel.OuterFace.InnerComponents.Count); }
public void CycleTest() { var dcel = new DCEL(); var v1 = dcel.AddVertex(new DCELVertex(0, 0)); var v2 = dcel.AddVertex(new DCELVertex(10, 10)); var v3 = dcel.AddVertex(new DCELVertex(20, 0)); var e1 = dcel.AddEdge(v1, v2); var e2 = dcel.AddEdge(v2, v3); var e3 = dcel.AddEdge(v3, v1); Assert.Contains(e1, DCEL.Cycle(e1)); Assert.Contains(e2, DCEL.Cycle(e1)); Assert.Contains(e3, DCEL.Cycle(e1)); Assert.Contains(e1, DCEL.Cycle(e2)); Assert.Contains(e2, DCEL.Cycle(e2)); Assert.Contains(e3, DCEL.Cycle(e2)); Assert.Contains(e1, DCEL.Cycle(e3)); Assert.Contains(e2, DCEL.Cycle(e3)); Assert.Contains(e3, DCEL.Cycle(e3)); }
private SamplingInformation(Transform transform, MeshFilter meshFilter, Collider collider, DoubleConnectedEdgeListStorage dcelStorage) { if (meshFilter == null) { throw new System.ArgumentNullException("mesh filter"); } if (collider == null) { throw new System.ArgumentNullException("collider"); } if (dcelStorage == null) { throw new System.ArgumentNullException("dcel storage"); } this.Transform = transform; this.Mesh = Application.isEditor ? meshFilter.sharedMesh : meshFilter.mesh; this.Collider = collider; this.DCEL = dcelStorage.DCEL; }
/// <summary> /// Finds faces that are vertically right in middle of the dual lines in the given dcel. /// </summary> /// <remarks> /// Output may be unexpected for vertical lines. /// Assumes the dcel was constructed using the given dual lines, /// with a bounding box with a slight margin (to avoid vertices with too many intersecting lines) /// </remarks> /// <param name="m_dcel"></param> /// <returns></returns> public static List <Face> MiddleFaces(DCEL m_dcel, IEnumerable <Line> m_dualLines) { if (m_dcel == null) { return(new List <Face>()); } var workingEdge = LeftMostMiddleHalfEdge(m_dcel, m_dualLines); var middleFaces = new List <Face>(); // iterate trough the faces until we hit the outer face again while (workingEdge.Face != m_dcel.OuterFace) { // get edge of face on the right if (middleFaces.Contains(workingEdge.Face)) { throw new GeomException("Middle face added twice"); } middleFaces.Add(workingEdge.Face); // loop until finding edge to rightmost vertex of face var dbstartedge = workingEdge; while (!IsEdgeLeadingToRightMostVertex(workingEdge)) { workingEdge = workingEdge.Next; Debug.Assert((workingEdge != dbstartedge), "Returned to starting Edge"); } if (workingEdge.Twin.Face == m_dcel.OuterFace) { break; } workingEdge = workingEdge.Twin.Prev.Twin; // Goes from *\ / to \/* } return(middleFaces); }
// Initial call for the construction of the Voronoi diagram public void StartVoronoi() { m_delaunay = Delaunay.Create(); m_dcel = Voronoi.Create(m_delaunay); VoronoiDrawer.setDCEL(m_dcel); }