/**
 * 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;
}
Esempio n. 2
0
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);

    }
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
    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;
}
Esempio n. 7
0
// 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;
    }
}
Esempio n. 8
0
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);
    }
  }