void CPlanarGraph::RandomInitGraph() { ClearGraph(); int minSkeletonSize = 5; int additionalSkeletonSize = Random2(5); int mainSkeletonSize = minSkeletonSize + additionalSkeletonSize; AddGraphNodes(mainSkeletonSize); // Add blue key branch: don't let this happen in the main room int blueLoop = Random2(minSkeletonSize-1) + 1; // add red key branch: don't let this happen in the main room int redLoop = Random2(minSkeletonSize-1) + 1; int blueSectionLength = 4 + Random2(4); int redSectionLength = 4 + Random2(4); if ( blueLoop < mainSkeletonSize ) { AddGraphNodes(blueSectionLength, blueLoop); if ( CoinFlip() ) { int idx0 = GetNumOfNodes() - 1; int idx1 = Random2(minSkeletonSize); AddGraphEdge(CGraphEdge(idx0, idx1)); } } if ( redLoop < mainSkeletonSize ) { AddGraphNodes(redSectionLength, redLoop); if ( CoinFlip() ) { int idx0 = GetNumOfNodes() - 1; int idx1 = Random2(minSkeletonSize); AddGraphEdge(CGraphEdge(idx0, idx1)); } } // Add decoration int numStubs = Random2(5); for ( int i=0; i<numStubs; i++ ) { int offset = Random2(mainSkeletonSize); AddGraphNodes(1+Random2(2), offset); } }
void CPlanarGraph::RandomInitPositions() { for ( int i=0; i<GetNumOfNodes(); i++ ) { GetNode(i).RandomlyInitPos(); } }
std::vector<int> CPlanarGraph::ExtractDeepestChainNew() { int chainLengthMin = std::numeric_limits<int>::max(); int chainLengthMax = 0; int chainLengthMinC = 0; int chainLengthMaxC = 0; std::vector<int> chainMin; std::vector<int> chainMax; for ( int i=0; i<GetNumOfNodes(); i++ ) { if ( GetNode(i).GetFlagVisited() == true ) { continue; } std::vector<int> chainIndices; int idx = i; chainIndices.push_back(idx); GetNode(idx).SetFlagVisited(true); // Grow the chain with unvisited nodes... bool flagInserted = true; while ( flagInserted ) { flagInserted = false; std::vector<int>& neighbors = GetNode(idx).GetNeighbors(); for ( int j=0; j<int(neighbors.size()); j++ ) { int idxTmp = neighbors[j]; if ( GetNode(idxTmp).GetFlagVisited() == false ) { idx = idxTmp; chainIndices.push_back(idx); GetNode(idx).SetFlagVisited(true); flagInserted = true; break; } } } int chainLengthTmp = int(chainIndices.size()); // Set the visited flags back to false... for ( int j=0; j<chainLengthTmp; j++ ) { GetNode(chainIndices[j]).SetFlagVisited(false); } int chainConstraintCount = CountConstraints(chainIndices); if ( chainConstraintCount>= chainLengthMinC && chainLengthTmp < chainLengthMin ) { chainLengthMinC = chainConstraintCount; chainLengthMin = chainLengthTmp; chainMin = chainIndices; } if ( chainConstraintCount>= chainLengthMaxC && chainLengthTmp > chainLengthMax ) { chainLengthMaxC = chainConstraintCount; chainLengthMax = chainLengthTmp; chainMax = chainIndices; } } return chainMin; }
void CPlanarGraph::RandomInitTypes() { for ( int i=0; i<GetNumOfNodes(); i++ ) { int type = int(rand() / float(RAND_MAX) * m_numOfTypes); GetNode(i).SetType(type); } }
/** * @brief * Draws the hierarchy node (for debugging) */ void SceneHierarchyNode::Draw(Renderer &cRenderer, const Color4 &cColor, const Matrix4x4 &mWorldViewProjection, float fLineWidth) const { // Draw the bounding box of this node cRenderer.GetDrawHelpers().DrawBox(cColor, m_cAABoundingBox.vMin, m_cAABoundingBox.vMax, mWorldViewProjection, fLineWidth); // Draw the child nodes for (uint32 i=0; i<GetNumOfNodes(); i++) GetNode(i)->Draw(cRenderer, cColor, mWorldViewProjection, fLineWidth); }
void CPlanarGraph::AddGraphNodes(int numOfNodes, int parent /* = -1 */) { int current = parent; for ( int i=0; i<numOfNodes; i++ ) { CGraphNode node; std::ostringstream os; os << GetNumOfNodes(); std::string name = "node" + os.str(); node.SetName(name); AddGraphNode(node); int curId = GetNumOfNodes() - 1; if ( current >= 0 ) { AddGraphEdge(CGraphEdge(current, curId)); } current = curId; } }
bool CPlanarGraph::HasFixedNode() { for ( int i=0; i<GetNumOfNodes(); i++ ) { if ( GetNode(i).GetFlagFixed() == true ) { return true; } } return false; }
bool CPlanarGraph::VisitedAllNodes() { for ( int i=0; i<GetNumOfNodes(); i++ ) { if ( GetNode(i).GetFlagVisited() == false ) { return false; } } return true; }
int CPlanarGraph::FindNodeAccordingToName(const char* str) { for ( int i=0; i<GetNumOfNodes(); i++ ) { if ( GetNode(i).GetName() == std::string(str) ) { return i; } } std::cout << "Cannot find a node named " << str << "!\n"; return -1; }
void CPlanarGraph::MoveGraphToSceneCenter() { v2f posMin, posMax; GetGraphBoundingBox(posMin, posMax); v2f posCen = (posMin + posMax) * 0.5f; for ( int i=0; i<GetNumOfNodes(); i++ ) { v2f pi = GetNode(i).GetPos(); pi = pi - posCen; GetNode(i).SetPos(pi); } }
std::vector<int> CPlanarGraph::GetUnfixedNodes() { std::vector<int> indices; for ( int i=0; i<GetNumOfNodes(); i++ ) { if ( GetNode(i).GetFlagFixed() == false ) { indices.push_back(i); } } return indices; }
void CPlanarGraph::ScaleGraphNodePositions(float scaling) { if ( scaling <= 0.f ) { return; } for ( int i=0; i<GetNumOfNodes(); i++ ) { v2f pi = GetNode(i).GetPos(); pi = pi * scaling; GetNode(i).SetPos(pi); } }
void CPlanarGraph::GetGraphBoundingBox(v2f& posMin, v2f& posMax) { v2f pMin(1e10); v2f pMax(-1e10); for ( int i=0; i<GetNumOfNodes(); i++ ) { v2f pi = GetNode(i).GetPos(); for ( int j=0; j<2; j++ ) { pMin[j] = min(pMin[j], pi[j]); pMax[j] = max(pMax[j], pi[j]); } } posMin = pMin; posMax = pMax; }
std::vector<int> CPlanarGraph::ExtractDeepestChain() { std::vector<int> chainIndices; // Almost randomly pick an unvisited node as the start of the chain... int idx = -1; for ( int i=0; i<GetNumOfNodes(); i++ ) { if ( GetNode(i).GetFlagVisited() == false ) { idx = i; chainIndices.push_back(idx); GetNode(idx).SetFlagVisited(true); break; } } // Grow the chain with unvisited nodes... bool flagInserted = true; while ( flagInserted ) { flagInserted = false; std::vector<int>& neighbors = GetNode(idx).GetNeighbors(); for ( int i=0; i<int(neighbors.size()); i++ ) { int idxTmp = neighbors[i]; if ( GetNode(idxTmp).GetFlagVisited() == false ) { idx = idxTmp; chainIndices.push_back(idx); GetNode(idx).SetFlagVisited(true); flagInserted = true; break; } } } // Set the visited flags back to false... for ( int i=0; i<int(chainIndices.size()); i++ ) { GetNode(chainIndices[i]).SetFlagVisited(false); } return chainIndices; }
void CPlanarGraph::RemoveIndividualNodes() { int numOfNodes = GetNumOfNodes(); std::vector<bool> vecKeepFlags(numOfNodes, false); std::vector<int> vecNewIndices(numOfNodes, -1); std::vector<CGraphNode> nodesToKeep; int keepCount = 0; for ( int i=0; i<numOfNodes; i++ ) { CGraphNode& node = GetNode(i); if ( node.GetNeighbors().empty() == false ) { nodesToKeep.push_back(node); vecKeepFlags[i] = true; vecNewIndices[i] = keepCount; keepCount ++; } } if ( keepCount == numOfNodes ) { return; } m_nodes = nodesToKeep; for ( int i=0; i<GetNumOfEdges(); i++ ) { CGraphEdge& edge = GetEdge(i); int idx0 = edge.GetIdx0(); int idx1 = edge.GetIdx1(); idx0 = vecNewIndices[idx0]; idx1 = vecNewIndices[idx1]; edge.SetIdx0(idx0); edge.SetIdx1(idx1); } SetNodeNeighbors(); }
void CPlanarGraph::DetectFaces() { // Based on the example in (http://www.boost.org/doc/libs/1_47_0/libs/graph/example/planar_face_traversal.cpp) int numOfNodes = GetNumOfNodes(); Graph g(numOfNodes); int numOfEdges = GetNumOfEdges(); for ( int i=0; i<numOfEdges; i++ ) { int idx0 = GetEdge(i).GetIdx0(); int idx1 = GetEdge(i).GetIdx1(); add_edge(idx0, idx1, g); } // Initialize the interior edge index property_map<Graph, edge_index_t>::type e_index = get(edge_index, g); graph_traits<Graph>::edges_size_type edge_count = 0; graph_traits<Graph>::edge_iterator ei, ei_end; for ( boost::tuples::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei ) { put(e_index, *ei, edge_count++); } typedef std::vector< graph_traits<Graph>::edge_descriptor > vec_t; std::vector<vec_t> embedding(num_vertices(g)); #if 0 // Test for planarity - we know it is planar, we just want to // compute the planar embedding as a side-effect if ( boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, boyer_myrvold_params::embedding = &embedding[0] ) ) { std::cout << "Input graph is planar" << std::endl; } else { std::cout << "Input graph is not planar" << std::endl; } #else // Compute the planar embedding based on node positions... VertexIterator vi, vi_end; for ( boost::tie(vi, vi_end) = boost::vertices(g); vi != vi_end; ++vi ) { OutEdgeIterator ei, ei_end; std::vector<EdgeDescriptor> adjacentEdges; for ( boost::tie(ei, ei_end) = boost::out_edges(*vi, g); ei != ei_end; ++ei ) { VertexDescriptor v1 = boost::source(*ei, g); VertexDescriptor v2 = boost::target(*ei, g); adjacentEdges.push_back(*ei); } SortAdjacentVertices(g, *vi, adjacentEdges); for(int i = 0; i < adjacentEdges.size(); ++i) { std::cout << *vi << " -> " << adjacentEdges[i] << std::endl; } if(adjacentEdges.size()>0) std::cout << std::endl; embedding[*vi] = adjacentEdges; } #endif std::cout << std::endl << "Vertices on the faces: " << std::endl; vertex_output_visitor v_vis; planar_face_traversal(g, &embedding[0], v_vis); std::cout << std::endl << "Edges on the faces: " << std::endl; edge_output_visitor e_vis; planar_face_traversal(g, &embedding[0], e_vis); RemoveTheOutsideFace(); }