/** * Prepares constraints in order to apply VPSC vertically to remove ALL overlap. */ int generateYConstraints(const int n, Rectangle** rs, Variable** vars, Constraint** &cs) { events=new Event*[2*n]; int ctr=0,i,m; for(i=0;i<n;i++) { vars[i]->desiredPosition=rs[i]->getCentreY(); Node *v = new Node(vars[i],rs[i],rs[i]->getCentreY()); events[ctr++]=new Event(Open,v,rs[i]->getMinX()); events[ctr++]=new Event(Close,v,rs[i]->getMaxX()); } qsort((Event*)events, (size_t)2*n, sizeof(Event*), compare_events ); NodeSet scanline; vector<Constraint*> constraints; for(i=0;i<2*n;i++) { Event *e=events[i]; Node *v=e->v; if(e->type==Open) { scanline.insert(v); NodeSet::iterator i=scanline.find(v); if(i--!=scanline.begin()) { Node *u=*i; v->firstAbove=u; u->firstBelow=v; } i=scanline.find(v); if(++i!=scanline.end()) { Node *u=*i; v->firstBelow=u; u->firstAbove=v; } } else { // Close event Node *l=v->firstAbove, *r=v->firstBelow; if(l!=NULL) { double sep = (v->r->height()+l->r->height())/2.0; constraints.push_back(new Constraint(l->v,v->v,sep)); l->firstBelow=v->firstBelow; } if(r!=NULL) { double sep = (v->r->height()+r->r->height())/2.0; constraints.push_back(new Constraint(v->v,r->v,sep)); r->firstAbove=v->firstAbove; } scanline.erase(v); delete v; } delete e; } delete [] events; cs=new Constraint*[m=constraints.size()]; for(i=0;i<m;i++) cs[i]=constraints[i]; return m; }
void GraphicsContext::removeCamera(osg::Camera* camera) { Cameras::iterator itr = std::find(_cameras.begin(), _cameras.end(), camera); if (itr != _cameras.end()) { // find a set of nodes attached the camera that we are removing that isn't // shared by any other cameras on this GraphicsContext typedef std::set<Node*> NodeSet; NodeSet nodes; for(unsigned int i=0; i<camera->getNumChildren(); ++i) { nodes.insert(camera->getChild(i)); } for(Cameras::iterator citr = _cameras.begin(); citr != _cameras.end(); ++citr) { if (citr != itr) { osg::Camera* otherCamera = *citr; for(unsigned int i=0; i<otherCamera->getNumChildren(); ++i) { NodeSet::iterator nitr = nodes.find(otherCamera->getChild(i)); if (nitr != nodes.end()) nodes.erase(nitr); } } } // now release the GLobjects associated with these non shared nodes for(NodeSet::iterator nitr = nodes.begin(); nitr != nodes.end(); ++nitr) { const_cast<osg::Node*>(*nitr)->releaseGLObjects(_state.get()); } // release the context of the any RenderingCache that the Camera has. if (camera->getRenderingCache()) { camera->getRenderingCache()->releaseGLObjects(_state.get()); } _cameras.erase(itr); } }
void State::divideTrees(const State& a_other, NodePairSet& a_commonRoots, NodeSet& a_myUniqueRoots, NodeSet& a_otherUniqueRoots) { NodeSet otherRootSet = a_other.getRootSet(); // Copy the entire set a_commonRoots.clear(); a_myUniqueRoots.clear(); a_otherUniqueRoots.clear(); for (NodeSetIter iter = m_rootSet.begin(); iter != m_rootSet.end(); iter++) { bool isUnique = true; string rootName; if (!((*iter)->getUniqueName(rootName))) { error("State::divideTrees - Multiple roots (in this state) with the same name " + rootName + " exist! " + string(*this), true); } for (NodeSetIter otherIter = otherRootSet.begin(); otherIter != otherRootSet.end(); otherIter++) { string otherRootName; if (!((*otherIter)->getUniqueName(otherRootName))) { error("State::divideTrees - Multiple roots (in joined state) with the same name " + otherRootName + " exist! " + string(a_other), true); } if (rootName == otherRootName) { a_commonRoots.insert(make_pair((*iter), (*otherIter))); otherRootSet.erase(otherIter); isUnique = false; break; } } if (isUnique) { a_myUniqueRoots.insert(*iter); } } a_otherUniqueRoots = otherRootSet; }
void part_1() { // topological sort with an ordered set NodeSet roots; Graph children, parents; get_graphs("input.txt", children, parents, roots); stringstream res; while (!roots.empty()) { char n = *roots.begin(); roots.erase(roots.begin()); res << n; for (char m : children[n]) { parents[m].erase(n); if (parents[m].empty()) { roots.insert(m); } } children.erase(n); } cout << res.str() << endl; }
void generateConstraints(vector<Node*>& nodes, vector<Edge*>& edges,vector<SimpleConstraint*>& cs,Dim dim) { unsigned nevents=2*nodes.size()+2*edges.size(); events=new Event*[nevents]; unsigned ctr=0; if(dim==HORIZONTAL) { //cout << "Scanning top to bottom..." << endl; for(unsigned i=0;i<nodes.size();i++) { Node *v=nodes[i]; v->scanpos=v->x; events[ctr++]=new Event(Open,v,v->ymin+0.01); events[ctr++]=new Event(Close,v,v->ymax-0.01); } for(unsigned i=0;i<edges.size();i++) { Edge *e=edges[i]; events[ctr++]=new Event(Open,e,e->ymin-1); events[ctr++]=new Event(Close,e,e->ymax+1); } } else { //cout << "Scanning left to right..." << endl; for(unsigned i=0;i<nodes.size();i++) { Node *v=nodes[i]; v->scanpos=v->y; events[ctr++]=new Event(Open,v,v->xmin+0.01); events[ctr++]=new Event(Close,v,v->xmax-0.01); } for(unsigned i=0;i<edges.size();i++) { Edge *e=edges[i]; events[ctr++]=new Event(Open,e,e->xmin-1); events[ctr++]=new Event(Close,e,e->xmax+1); } } qsort((Event*)events, (size_t)nevents, sizeof(Event*), compare_events ); NodeSet openNodes; vector<Edge*> openEdges; for(unsigned i=0;i<nevents;i++) { Event *e=events[i]; Node *v=e->v; if(v!=NULL) { v->open = true; //printf("NEvent@%f,nid=%d,(%f,%f),w=%f,h=%f,openn=%d,opene=%d\n",e->pos,v->id,v->x,v->y,v->width,v->height,(int)openNodes.size(),(int)openEdges.size()); Node *l=NULL, *r=NULL; if(!openNodes.empty()) { // it points to the first node to the right of v NodeSet::iterator it=openNodes.lower_bound(v); // step left to find the first node to the left of v if(it--!=openNodes.begin()) { l=*it; //printf("l=%d\n",l->id); } it=openNodes.upper_bound(v); if(it!=openNodes.end()) { r=*it; } } vector<Node*> L; sortNeighbours(v,l,r,e->pos,openEdges,L,nodes,dim); //printf("L=["); for(unsigned i=0;i<L.size();i++) { //printf("%d ",L[i]->id); } //printf("]\n"); // Case A: create constraints between adjacent edges skipping edges joined // to l,v or r. Node* lastNode=NULL; for(vector<Node*>::iterator i=L.begin();i!=L.end();i++) { if((*i)->dummy) { // node is on an edge Edge *edge=(*i)->edge; if(!edge->isEnd(v->id) &&((l!=NULL&&!edge->isEnd(l->id))||l==NULL) &&((r!=NULL&&!edge->isEnd(r->id))||r==NULL)) { if(lastNode!=NULL) { //printf(" Rule A: Constraint: v%d +g <= v%d\n",lastNode->id,(*i)->id); cs.push_back(createConstraint(lastNode,*i,dim)); } lastNode=*i; } } else { // is an actual node lastNode=NULL; } } // Case B: create constraints for all the edges connected to the right of // their own end, also in the scan line vector<Node*> skipList; lastNode=NULL; for(vector<Node*>::iterator i=L.begin();i!=L.end();i++) { if((*i)->dummy) { // node is on an edge if(lastNode!=NULL) { if((*i)->edge->isEnd(lastNode->id)) { skipList.push_back(*i); } else { for(vector<Node*>::iterator j=skipList.begin(); j!=skipList.end();j++) { //printf(" Rule B: Constraint: v%d +g <= v%d\n",(*j)->id,(*i)->id); cs.push_back(createConstraint(*j,*i,dim)); } skipList.clear(); } } } else { // is an actual node skipList.clear(); skipList.push_back(*i); lastNode=*i; } } skipList.clear(); // Case C: reverse of B lastNode=NULL; for(vector<Node*>::reverse_iterator i=L.rbegin();i!=L.rend();i++) { if((*i)->dummy) { // node is on an edge if(lastNode!=NULL) { if((*i)->edge->isEnd(lastNode->id)) { skipList.push_back(*i); } else { for(vector<Node*>::iterator j=skipList.begin(); j!=skipList.end();j++) { //printf(" Rule C: Constraint: v%d +g <= v%d\n",(*i)->id,(*j)->id); cs.push_back(createConstraint(*i,*j,dim)); } skipList.clear(); } } } else { // is an actual node skipList.clear(); skipList.push_back(*i); lastNode=*i; } } if(e->type==Close) { if(l!=NULL) cs.push_back(createConstraint(l,v,dim)); if(r!=NULL) cs.push_back(createConstraint(v,r,dim)); } } if(e->type==Open) { if(v!=NULL) { openNodes.insert(v); } else { //printf("EdgeOpen@%f,eid=%d,(u,v)=(%d,%d)\n", e->pos,e->e->id,e->e->startNode,e->e->endNode); e->e->openInd=openEdges.size(); openEdges.push_back(e->e); } } else { // Close if(v!=NULL) { openNodes.erase(v); v->open=false; } else { //printf("EdgeClose@%f,eid=%d,(u,v)=(%d,%d)\n", e->pos,e->e->id,e->e->startNode,e->e->endNode); unsigned i=e->e->openInd; openEdges[i]=openEdges[openEdges.size()-1]; openEdges[i]->openInd=i; openEdges.resize(openEdges.size()-1); } } delete e; } delete [] events; }
/** * Prepares constraints in order to apply VPSC horizontally. Assumes variables have already been created. * useNeighbourLists determines whether or not a heuristic is used to deciding whether to resolve * all overlap in the x pass, or leave some overlaps for the y pass. */ int generateXConstraints(const int n, Rectangle** rs, Variable** vars, Constraint** &cs, const bool useNeighbourLists) { events=new Event*[2*n]; int i,m,ctr=0; for(i=0;i<n;i++) { vars[i]->desiredPosition=rs[i]->getCentreX(); Node *v = new Node(vars[i],rs[i],rs[i]->getCentreX()); events[ctr++]=new Event(Open,v,rs[i]->getMinY()); events[ctr++]=new Event(Close,v,rs[i]->getMaxY()); } qsort((Event*)events, (size_t)2*n, sizeof(Event*), compare_events ); NodeSet scanline; vector<Constraint*> constraints; for(i=0;i<2*n;i++) { Event *e=events[i]; Node *v=e->v; if(e->type==Open) { scanline.insert(v); if(useNeighbourLists) { v->setNeighbours( getLeftNeighbours(scanline,v), getRightNeighbours(scanline,v) ); } else { NodeSet::iterator it=scanline.find(v); if(it--!=scanline.begin()) { Node *u=*it; v->firstAbove=u; u->firstBelow=v; } it=scanline.find(v); if(++it!=scanline.end()) { Node *u=*it; v->firstBelow=u; u->firstAbove=v; } } } else { // Close event int r; if(useNeighbourLists) { for(NodeSet::iterator i=v->leftNeighbours->begin(); i!=v->leftNeighbours->end();i++ ) { Node *u=*i; double sep = (v->r->width()+u->r->width())/2.0; constraints.push_back(new Constraint(u->v,v->v,sep)); r=u->rightNeighbours->erase(v); } for(NodeSet::iterator i=v->rightNeighbours->begin(); i!=v->rightNeighbours->end();i++ ) { Node *u=*i; double sep = (v->r->width()+u->r->width())/2.0; constraints.push_back(new Constraint(v->v,u->v,sep)); r=u->leftNeighbours->erase(v); } } else { Node *l=v->firstAbove, *r=v->firstBelow; if(l!=NULL) { double sep = (v->r->width()+l->r->width())/2.0; constraints.push_back(new Constraint(l->v,v->v,sep)); l->firstBelow=v->firstBelow; } if(r!=NULL) { double sep = (v->r->width()+r->r->width())/2.0; constraints.push_back(new Constraint(v->v,r->v,sep)); r->firstAbove=v->firstAbove; } } r=scanline.erase(v); delete v; } delete e; } delete [] events; cs=new Constraint*[m=constraints.size()]; for(i=0;i<m;i++) cs[i]=constraints[i]; return m; }
// Processes sweep events used to determine each horizontal and vertical // line segment in a connector's channel of visibility. // Four calls to this function are made at each position by the scanline: // 1) Handle all Close event processing. // 2) Remove Close event objects from the scanline. // 3) Add Open event objects to the scanline. // 4) Handle all Open event processing. // static void processShiftEvent(NodeSet& scanline, Event *e, size_t dim, unsigned int pass) { Node *v = e->v; if ( ((pass == 3) && (e->type == Open)) || ((pass == 3) && (e->type == SegOpen)) ) { std::pair<NodeSet::iterator, bool> result = scanline.insert(v); v->iter = result.first; COLA_ASSERT(result.second); NodeSet::iterator it = v->iter; // Work out neighbours if (it != scanline.begin()) { Node *u = *(--it); v->firstAbove = u; u->firstBelow = v; } it = v->iter; if (++it != scanline.end()) { Node *u = *it; v->firstBelow = u; u->firstAbove = v; } } if ( ((pass == 4) && (e->type == Open)) || ((pass == 4) && (e->type == SegOpen)) || ((pass == 1) && (e->type == SegClose)) || ((pass == 1) && (e->type == Close)) ) { if (v->ss) { // As far as we can see. double minLimit = v->firstObstacleAbove(dim); double maxLimit = v->firstObstacleBelow(dim); v->ss->minSpaceLimit = std::max(minLimit, v->ss->minSpaceLimit); v->ss->maxSpaceLimit = std::min(maxLimit, v->ss->maxSpaceLimit); } else { v->markShiftSegmentsAbove(dim); v->markShiftSegmentsBelow(dim); } } if ( ((pass == 2) && (e->type == SegClose)) || ((pass == 2) && (e->type == Close)) ) { // Clean up neighbour pointers. Node *l = v->firstAbove, *r = v->firstBelow; if (l != NULL) { l->firstBelow = v->firstBelow; } if (r != NULL) { r->firstAbove = v->firstAbove; } size_t result; result = scanline.erase(v); COLA_ASSERT(result == 1); COLA_UNUSED(result); // Avoid warning. delete v; } }
bool Path::find(const Grid &g, const Tile &start, const Tile &goal) { Format f = "Finding path from cell {} to {}"; info(f.bind(start, goal)); Timer t; t.start(); NodePool p; Node *n = new (p) Node(start, 0.0f); const Heuristic &h = m_heuristic; n->remaining = h.estimate(n->tile, goal); n->total = n->cost + n->remaining; NodeQueue q; q.push(n); NodeSet frontier; frontier.insert(n); NodeSet interior; Node *b; Nodes v; while (!q.empty()) { n = q.top(); q.pop(); if (n->was_replaced()) { p.discard(n); continue; } if (n->tile == goal) { trace(n, tiles); report_stats(t, p); return true; } frontier.erase(n); interior.insert(n); neighbors(n, v, p, g); foreach (Node *a, v) { a->cost += n->cost; if ((b = lookup(a, frontier))) { if (b->cost <= a->cost) { p.discard(a); continue; } frontier.erase(b); b->mark_as_replaced(); } if ((b = lookup(a, interior))) { if (b->cost <= a->cost) { p.discard(a); continue; } interior.erase(b); p.discard(b); } a->remaining = h.estimate(a->tile, goal); a->total = a->cost + a->remaining; a->next = n; q.push(a); frontier.insert(a); } }