protected void CalculateBoundingBox() { if (nodeDict.Count > 0) { boundingBox = new BoxF(); boundingBox = ((ShapeNode)nodeDict.Keys.First()).BoundingBox; foreach (Node n in nodeDict.Keys) { ShapeNode sn = (ShapeNode)n; boundingBox.Extend(sn.BoundingBox); } } }
protected void ConnectEdge(ShapeNode n, ref int index, List <Node> nl) { // Attempts to connect an edge(index) on a ShapeNode(n) against all edges in a list of Nodes(nl) // Subdivides matching edges accordingly if the intersection is less than the entire length of one of the edges. // Note: Subdivision code is fairly basic at the moment. Some edge cases are not covered. if (n.LinkList[index] != null) { return; } Vector2D edge = n.GetEdge(index); Vector2D norm1 = edge.Normalized(); foreach (ShapeNode n2 in nl) { if (n2 != n) { for (int index2 = 0; index2 < n2.points.Count; index2++) { Vector2D edge2 = n2.GetAntiClockwiseEdge(index2); Vector2D norm2 = edge2.Normalized(); if (edge.a == edge2.a && norm1 == norm2) { NodeLink nodeLink = ShapeNode.ConnectEdges(n, index, n2, index2); if (edge.Length() > edge2.Length()) { n.AddPoint(index + 1, edge2.b); index--; } if (edge2.Length() > edge.Length()) { n2.AddPoint(index2 + 1, edge.b); n2.LinkList[index2 + 1] = n2.LinkList[index2]; n2.LinkList[index2] = null; ConnectEdge(n2, ref index2, nl); } return; } } } } }
protected void AddTriangleGridCell(PointF offset, float size, ref List <Node> cellNodeList) { int oldNodeListCount = nodeDict.Count; SizeF cellSize = new SizeF(size, size); PointF point = new PointF(); Point i = new Point(0, 0); point.X = offset.X + (i.X * size); point.Y = offset.Y + (i.Y * size); // Randomly flip orientation of triangles in a cell if (_random.Next(0, 2) == 0) { ShapeNode node = new ShapeNode(); node.AddPoint(0, point); point.X += size; point.Y += size; node.AddPoint(1, point); point.X -= size; node.AddPoint(2, point); nodeDict.Add(node, node.LinkList); node = new ShapeNode(); point.X += size; node.AddPoint(0, point); point.X -= size; point.Y -= size; node.AddPoint(1, point); point.X += size; node.AddPoint(2, point); nodeDict.Add(node, node.LinkList); } else { ShapeNode node = new ShapeNode(); point.X += size; node.AddPoint(0, point); point.X -= size; point.Y += size; node.AddPoint(1, point); point.Y -= size; node.AddPoint(2, point); nodeDict.Add(node, node.LinkList); node = new ShapeNode(); point.Y += size; node.AddPoint(0, point); point.X += size; point.Y -= size; node.AddPoint(1, point); point.Y += size; node.AddPoint(2, point); nodeDict.Add(node, node.LinkList); } for (int index = oldNodeListCount; index < nodeDict.Count; index++) { cellNodeList.Add(nodeDict.ElementAt(index).Key); } }
public void Initialize(int gridWidth, int gridHeight, int weavePercent, float weighting) { horizontalWeighting = weighting; verticalWeighting = 1.0f - weighting; // Create grid RectNode[,] basicGrid = new RectNode[gridWidth, gridHeight]; // Create square nodes SizeF cellSize = new SizeF(1, 1); Point p = new Point(); for (p.X = 0; p.X < gridWidth; p.X++) { for (p.Y = 0; p.Y < gridHeight; p.Y++) { RectNode node = new RectNode(p, cellSize); nodeDict.Add(node, node.LinkList); basicGrid[p.X, p.Y] = node; } } // Connect nodes for (p.X = 1; p.X < gridWidth; p.X++) { for (p.Y = 0; p.Y < gridHeight; p.Y++) { ShapeNode.ConnectEdges(basicGrid[p.X - 1, p.Y], RectNode.RightIndex, basicGrid[p.X, p.Y], RectNode.LeftIndex, horizontalWeighting); } } for (p.X = 0; p.X < gridWidth; p.X++) { for (p.Y = 1; p.Y < gridHeight; p.Y++) { ShapeNode.ConnectEdges(basicGrid[p.X, p.Y - 1], RectNode.BottomIndex, basicGrid[p.X, p.Y], RectNode.TopIndex, verticalWeighting); } } boundingBox.ptMin.X = 0; boundingBox.ptMin.Y = 0; boundingBox.ptMax.X = gridWidth; boundingBox.ptMax.Y = gridHeight; // Add Weaves int numWeaveNodes = (gridWidth - 2) * (gridHeight - 2); if (numWeaveNodes > 0) { for (p.X = 1; p.X < (gridWidth - 1); p.X++) { for (p.Y = 1; p.Y < (gridHeight - 1); p.Y++) { int chance = r.Next(0, 100); if (chance < weavePercent) { NodeLink link; Node gridNode = basicGrid[p.X, p.Y]; Node upperNode = gridNode.LinkList[0].Other(gridNode); Node leftNode = gridNode.LinkList[1].Other(gridNode); Node lowerNode = gridNode.LinkList[2].Other(gridNode); Node rightNode = gridNode.LinkList[3].Other(gridNode); RectNode weaveNode = new RectNode(p, cellSize); nodeDict.Add(weaveNode, weaveNode.LinkList); weaveNode.LinkList[0] = gridNode.LinkList[0]; gridNode.LinkList[0] = null; weaveNode.LinkList[2] = gridNode.LinkList[2]; gridNode.LinkList[2] = null; link = weaveNode.LinkList[0]; if (link.a == gridNode) { link.a = weaveNode; } else { link.b = weaveNode; } link = weaveNode.LinkList[2]; if (link.a == gridNode) { link.a = weaveNode; } else { link.b = weaveNode; } link = new NodeLink(upperNode, lowerNode); upperNode.LinkList[2] = link; lowerNode.LinkList[0] = link; link.visited = true; link = new NodeLink(leftNode, rightNode); leftNode.LinkList[3] = link; rightNode.LinkList[1] = link; link.visited = true; gridNode.LinkList[1].visited = true; gridNode.LinkList[3].visited = true; weaveNode.LinkList[0].visited = true; weaveNode.LinkList[2].visited = true; } } } } // Add start and end nodes Node startNode = basicGrid[0, 0]; startNode.LinkList[3] = new NodeLink(startNode, null); startNode.LinkList[3].visited = true; Node endNode = basicGrid[gridWidth - 1, gridHeight - 1]; endNode.LinkList[1] = new NodeLink(endNode, null); endNode.LinkList[1].visited = true;; }
protected void AddDiamondGridCell(PointF offset, float size, ref List<Node> cellNodeList) { int oldNodeListCount = nodeDict.Count; SizeF cellSize = new SizeF(size, size); PointF point = new PointF(); //Point i = new Point(0,0); point.X = offset.X * 1; point.Y = offset.Y * 3; for(int id = 0; id < 6; id++) { ShapeNode node = new ShapeNode(); for(int ip = 0; ip < 4; ip++) { point.X = (offset.X * 2) + (d[id,ip].X * 2); point.Y = (offset.Y * 3) + d[id,ip].Y; node.AddPoint(ip, point); } nodeDict.Add(node, node.LinkList); } for (int index = oldNodeListCount; index < nodeDict.Count; index++) { cellNodeList.Add(nodeDict.ElementAt(index).Key); } }
protected void AddTriangleGridCell(PointF offset, float size, ref List<Node> cellNodeList) { int oldNodeListCount = nodeDict.Count; SizeF cellSize = new SizeF(size, size); PointF point = new PointF(); Point i = new Point(0,0); point.X = offset.X + (i.X * size); point.Y = offset.Y + (i.Y * size); // Randomly flip orientation of triangles in a cell if(_random.Next(0,2) == 0) { ShapeNode node = new ShapeNode(); node.AddPoint(0, point); point.X += size; point.Y += size; node.AddPoint(1, point); point.X -= size; node.AddPoint(2, point); nodeDict.Add(node, node.LinkList); node = new ShapeNode(); point.X += size; node.AddPoint(0, point); point.X -= size; point.Y -= size; node.AddPoint(1, point); point.X += size; node.AddPoint(2, point); nodeDict.Add(node, node.LinkList); } else { ShapeNode node = new ShapeNode(); point.X += size; node.AddPoint(0, point); point.X -= size; point.Y += size; node.AddPoint(1, point); point.Y -= size; node.AddPoint(2, point); nodeDict.Add(node, node.LinkList); node = new ShapeNode(); point.Y += size; node.AddPoint(0, point); point.X += size; point.Y -= size; node.AddPoint(1, point); point.Y += size; node.AddPoint(2, point); nodeDict.Add(node, node.LinkList); } for (int index = oldNodeListCount; index < nodeDict.Count; index++) { cellNodeList.Add(nodeDict.ElementAt(index).Key); } }
public static NodeLink ConnectEdges(ShapeNode node1, int index1, ShapeNode node2, int index2, float weighting = 0.0f) { NodeLink result; if (node1.LinkList[index1] != null) { result = node1.LinkList[index1]; } else { NodeLink newLink = new NodeLink(node1, node2); newLink.weight = weighting; /* string s; s = "(" + ((RectNode)node1).rect.Left + ", " + ((RectNode)node1).rect.Top + ")"; s += "(" + ((RectNode)node1).rect.Right + ", " + ((RectNode)node1).rect.Bottom + ")"; s += " - "; s += "(" + ((RectNode)node2).rect.Left + ", " + ((RectNode)node2).rect.Top + ")"; s += "(" + ((RectNode)node2).rect.Right + ", " + ((RectNode)node2).rect.Bottom + ")"; System.Diagnostics.Trace.WriteLine(" : New Link", s); */ node1.LinkList[index1] = newLink; node2.LinkList[index2] = newLink; result = newLink; } return result; }
protected void ConnectEdge(ShapeNode n, ref int index, List<Node> nl) { // Attempts to connect an edge(index) on a ShapeNode(n) against all edges in a list of Nodes(nl) // Subdivides matching edges accordingly if the intersection is less than the entire length of one of the edges. // Note: Subdivision code is fairly basic at the moment. Some edge cases are not covered. if (n.LinkList[index] != null) { return; } Vector2D edge = n.GetEdge(index); Vector2D norm1 = edge.Normalized(); foreach (ShapeNode n2 in nl) { if (n2 != n) { for (int index2 = 0; index2 < n2.points.Count; index2++) { Vector2D edge2 = n2.GetAntiClockwiseEdge(index2); Vector2D norm2 = edge2.Normalized(); if (edge.a == edge2.a && norm1 == norm2) { NodeLink nodeLink = ShapeNode.ConnectEdges(n, index, n2, index2); if (edge.Length() > edge2.Length()) { n.AddPoint(index + 1, edge2.b); index--; } if (edge2.Length() > edge.Length()) { n2.AddPoint(index2 + 1, edge.b); n2.LinkList[index2 + 1] = n2.LinkList[index2]; n2.LinkList[index2] = null; ConnectEdge(n2, ref index2, nl); } return; } } } } }