private static void markAsStem(YaoNode n, YaoGraph g, int iteration) { n.isStem = iteration; if (n.parentID != -1 && g[n.parentID].isStem == -1) // mark parent as stem as well, if it is nor already { markAsStem(g[n.parentID], g, iteration); } }
public YaoNode dequeue() { if (!isEmpty()) { YaoNode n = queue.First.Value; queue.RemoveFirst(); return(n); } else { throw new System.Exception("Queue is empty"); } }
void fixGuidingVector(YaoNode node, YaoNode parent) { //Stopwatch profiler = new Stopwatch(); //profiler.Start(); Vector3 rotationAxis = Vector3.Cross(Vector3.up, parent.guidingVector); //UnityEngine.Debug.Log("rotationAxis:" + profiler.ElapsedMilliseconds + "ms"); profiler.Start(); float rotationAngle = getRotationAngle(node.hopsFromSource); //UnityEngine.Debug.Log("rotationAngle:" + profiler.ElapsedMilliseconds + "ms"); profiler.Start(); node.guidingVector = Quaternion.AngleAxis(rotationAngle, rotationAxis) * parent.guidingVector; //UnityEngine.Debug.Log("guidingVector:" + profiler.ElapsedMilliseconds + "ms"); profiler.Start(); //node.guidingVector = node.guidingVector.normalized; }
private void visit() { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // preallocate memory //int nodeIDIdx = -1; //int nodeID = -1; YaoNode currentNode = null; float connectionDistance = 0.0f; while (!unvisitedNodes.isEmpty()) //unvisited.Count > 0) { //Stopwatch iterationWatch = new Stopwatch(); //iterationWatch.Start(); // find greedy shortest path for next iteration //Stopwatch profiler = new Stopwatch(); //profiler.Start(); //nodeIDIdx = findSmallestUnvisitedIdx(); //nodeID = unvisited[nodeIDIdx]; currentNode = unvisitedNodes.dequeue(); //Debug.Log("Visiting " + nodeID + " left:" + unvisited.Count); //UnityEngine.Debug.Log("findSmallestUnvisited:" + profiler.ElapsedMilliseconds + "ms"); // Recalculate distances foreach (int neighborID in currentNode.outgoingEdges) { //Assert.IsTrue(unvisited.Contains(neighborID)); if (neighborID != -1) { connectionDistance = currentNode.distanceFromSource + distance(currentNode, graph[neighborID]); if (connectionDistance < graph[neighborID].distanceFromSource) { graph[neighborID].distanceFromSource = connectionDistance; graph[neighborID].hopsFromSource = currentNode.hopsFromSource + 1; graph[neighborID].parentID = currentNode.ID; unvisitedNodes.update(graph[neighborID]); } } } //UnityEngine.Debug.Log("foreach.neighbor:" + profiler.ElapsedMilliseconds + "ms"); finalize(currentNode.ID); //UnityEngine.Debug.Log("finalize:" + profiler.ElapsedMilliseconds + "ms"); //UnityEngine.Debug.Log("Iteration:" + iterationWatch.ElapsedMilliseconds + "ms"); } UnityEngine.Debug.Log("Dijkstra total:" + stopWatch.ElapsedMilliseconds + "ms"); }
private int setStemNodes(Vector3 stem) { int stemNodeId = graph.rootNodeId; Assert.AreNotEqual(stemNodeId, -1); //Debug.Log("Stem Node: " + stemNodeId); graph[stemNodeId] = new YaoNode(stemNodeId, -1, 0.0f, 0, Vector3.up, graph.getNeighborhoodSize()); graph.data.samples[stemNodeId] = stem; unvisitedNodes = new PriorityQueueYao(); // all non-stem nodes foreach (YaoNode node in graph) { Assert.AreNotEqual(node.ID, -1); unvisitedNodes.enqueue(node); } return(stemNodeId); }
public void update(YaoNode node) { bubbleUp(queue.Find(node)); }
public void enqueue(YaoNode node) { queue.AddLast(node); bubbleUp(queue.Last); }
// From n1 to n2 (this is not symmetric due to the guiding vector!) private float distance(YaoNode n1, YaoNode n2) { Vector3 vectorAlongEdge = graph.data.samples[n1.ID] - graph.data.samples[n2.ID]; return((vectorAlongEdge).magnitude * (1 - Vector3.Dot(n1.guidingVector, vectorAlongEdge.normalized))); }
private void generateBranchNode(YaoNode n1, YaoNode n2) { float thickness_radius = n1.isStem; // TODO do circular angle iterations }