void balazs::TransverseCurve::initIntervalsInOrder()
{
    std::vector<Mod1NumberIntExchange> collectionEndPoints = getEndpoints(m_sepSegmentCollection);

    std::size_t disjointIntervalIndex = m_disjointIntervals.wrapsAroundEnds() ?
                                        m_disjointIntervals.endpoints().size() - 1 : 0;

    Mod1NumberIntExchange currentPoint;

    m_intervalsInOrder.reserve(m_sepSegmentCollection.size());
    for(std::size_t i = 0; i < m_sepSegmentCollection.size(); i++) {
        currentPoint = m_disjointIntervals.endpoints()[disjointIntervalIndex];
        m_intervalsInOrder.push_back(currentPoint);
        if(i % 2 == 0) {
            disjointIntervalIndex = (disjointIntervalIndex + 1) % m_disjointIntervals.endpoints().size();
        } else {
            auto it = std::find(collectionEndPoints.begin(), collectionEndPoints.end(), currentPoint);
            std::size_t index = it - collectionEndPoints.begin();
            assert(index < collectionEndPoints.size());
            index = (index % 2 == 0) ? index + 1 : index - 1;
            auto it2 = std::lower_bound(m_disjointIntervals.endpoints().begin(),
                                        m_disjointIntervals.endpoints().end(),
                                        collectionEndPoints[index]);
            disjointIntervalIndex = it2 - m_disjointIntervals.endpoints().begin();
            assert(disjointIntervalIndex < m_disjointIntervals.endpoints().size());
        }
    }

}
balazs::TransverseCurve::TransverseCurve(const SepSegmentCollection &segments, bool wrapsAroundEnds, SepSegmentDatabase &ssDatabase) :
    m_sepSegmentCollection(segments),
    m_disjointIntervals(getEndpoints(m_sepSegmentCollection), wrapsAroundEnds),
    m_sepSegmentDatabase(ssDatabase)
{
    assert(&m_sepSegmentDatabase == &m_sepSegmentCollection.sepSegmentDatabase());

    initIntervalsInOrder();
    initTouchingSegments(); // might throw if touching segments cannot be initialized because of saddle connection

    m_topIntersections.reserve(foliation().numIntervals());
    for(std::size_t i = 0; i < foliation().numIntervals(); i++) {
        m_topIntersections.push_back(touchingSepSegment({HDirection::Right, VDirection::Down, i},
                                     SepSegmentDatabase::Centered).endpoint().shiftedTo(HDirection::Center));
    }

    m_bottomRightIntersections.reserve(foliation().numIntervals());
    for(std::size_t i = 0; i < foliation().numIntervals(); i++) {
        m_bottomRightIntersections.push_back(touchingSepSegment({HDirection::Right, VDirection::Up, i},
                                             SepSegmentDatabase::Centered).endpoint().shiftedTo(HDirection::Center));
    }

    m_bottomLeftIntersections.reserve(foliation().numIntervals());
    for(std::size_t i = 0; i < foliation().numIntervals(); i++) {
        m_bottomLeftIntersections.push_back(touchingSepSegment({HDirection::Left, VDirection::Up, i},
                                            SepSegmentDatabase::Centered).endpoint().shiftedTo(HDirection::Center));
    }
}
Exemple #3
0
void
SPConnEndPair::reroutePath(void)
{
    if (!isAutoRoutingConn()) {
        // Do nothing
        return;
    }

    SPCurve *curve = _path->curve;

    Geom::Point endPt[2];
    getEndpoints(endPt);

    Avoid::Point src(endPt[0][Geom::X], endPt[0][Geom::Y]);
    Avoid::Point dst(endPt[1][Geom::X], endPt[1][Geom::Y]);

    _connRef->updateEndPoint(Avoid::VertID::src, src);
    _connRef->updateEndPoint(Avoid::VertID::tar, dst);

    _connRef->generatePath(src, dst);

    Avoid::PolyLine route = _connRef->route();
    _connRef->calcRouteDist();

    curve->reset();
    curve->moveto(endPt[0]);

    for (int i = 1; i < route.pn; ++i) {
        Geom::Point p(route.ps[i].x, route.ps[i].y);
        curve->lineto(p);
    }
}
Exemple #4
0
uint Board::scoreAxis(const Cell* cell, AXIS::Axis axis, string prefix) {
    uint score = 0;
    uint wf = 1;
    uint incr = getIncrement(axis);
    Cell *from, *to;
    if (getEndpoints(cell, axis, from, to) && from != to) {
        //cout << "\n\n";
        for (const Cell* c = from; c <= to; c += incr) {
            uint lf = c->letterFactor;
            uint lwf = c->wordFactor;
            uint va = c->value;
            wf *= lwf;
            score += lf * va;
        }
        score *= wf;
    }
    return score;
}
// Called from sp_path_update to initialise the endpoints.
void
SPConnEndPair::update(void)
{
    if (_connType != SP_CONNECTOR_NOAVOID) {
        g_assert(_connRef != NULL);
        if (!(_connRef->isInitialised())) {
            Geom::Point endPt[2];
            getEndpoints(endPt);

            Avoid::Point src(endPt[0][Geom::X], endPt[0][Geom::Y]);
            Avoid::Point dst(endPt[1][Geom::X], endPt[1][Geom::Y]);

            _connRef->setEndpoints(src, dst);
            _connRef->setCallback(&redrawConnectorCallback, _path);
        }
        // Store the ID of the objects attached to the connector.
        storeIds();
    }
}
Exemple #6
0
uint Board::scoreMove(const Cell* cell, AXIS::Axis axis) {
    uint primaryScore = scoreAxis(cell, axis);
    uint dualScores = 0;
    uint numChanged = 0;
    Cell *from, *to;
    uint incr = getIncrement(axis);
    AXIS::Axis dual = getDual(axis);
    if (getEndpoints(cell, axis, from, to)) {
        for (const Cell* c = from; c <= to; c += incr) {
            if (changed(c)) {
                numChanged++;
                uint sec = scoreAxis(c, dual, "   ");
                dualScores += sec;
            }
        }
    }
    uint totalScore = primaryScore + dualScores;
    if(numChanged == Common::rackSize) totalScore+=Common::bingoValue;
    return totalScore;
}
void
SPConnEndPair::tellLibavoidNewEndpoints(const bool processTransaction)
{
    if (!isAutoRoutingConn()) {
        // Do nothing
        return;
    }
    makePathInvalid();

    Geom::Point endPt[2];
    getEndpoints(endPt);

    Avoid::Point src(endPt[0][Geom::X], endPt[0][Geom::Y]);
    Avoid::Point dst(endPt[1][Geom::X], endPt[1][Geom::Y]);

    _connRef->setEndpoints(src, dst);
    if (processTransaction)
    {
        _connRef->router()->processTransaction();
    }
    return;
}
Exemple #8
0
//---------------------------------------------------------------------------------
void NiceGraph::selfOrganize(float force, float min, float max)
{
	// this function only self organizes 1 step, must be called multiple times for continous updating
	// the force value ranges from [0,1] and is the fraction of the final step to take
	// min and max values are protected distances for the various edges

	if (force > 1)
		force = 1;
	else if (force <=0)
		force = 0.001;

		// iterate over edges, attract and check bounds, rearrange as necessary

	for (map<int,Edge*>::iterator iter = edgeList.begin(); iter != edgeList.end(); iter++)
	{
		int e = iter->first;
		vector<float> v1 (3), v2 (3);
		float attraction = 0, dx = 0, dy = 0, dz = 0;
		int id1 = edgeList[e]->from->vID;
		int id2 = edgeList[e]->to->vID;
		getEndpoints (e, v1, v2);

		float vx = v2[0] - v1[0];
		float vy = v2[1] - v1[1];
		float vz = v2[2] - v1[2];
		
		float dr = sqrt ( vx*vx + vy*vy + vz*vz );

		attraction = -1.0 * (max - dr) / (100 * (max - min)/2);

		dx += 0.5 * attraction * vx;
		dy += 0.5 * attraction * vy;
		dz += 0.5 * attraction * vz;

		float scale = 1.0;

		setXYZPos (id1, v1[0] + scale * dx, v1[1] + scale * dy, v1[2] + scale * dz);		
		setXYZPos (id2, v2[0] - scale * dx, v2[1] - scale * dy, v2[2] - scale * dz);

	}

	for (map<int,Vertex*>::iterator iter = vertexList.begin(); iter != vertexList.end(); iter++)
	{
		int self = iter->first;

		float dx = 0, dy = 0, dz = 0, repulsion = 0;
		float px = vertexList[self]->posX;
		float py = vertexList[self]->posY;
		float pz = vertexList[self]->posZ;

		// sum repulsion from other vertices
		for (map<int,Vertex*>::iterator iter2 = vertexList.begin(); iter2 != vertexList.end(); iter2++)
		{
			int other = iter2->first;
			if (self == other)		// don't need to repel self, too!
				continue;
			
			float vx = vertexList[other]->posX - px;
			float vy = vertexList[other]->posY - py;
			float vz = vertexList[other]->posZ - pz;

			float dr = sqrt (vx * vx + vy * vy + vz * vz);

			// let the repulsion go as 1/r^2, like the electrostatic force

			repulsion = -0.01 * force*force / (sqrt(dr) * dr);
			
			dx += repulsion * vx;
			dy += repulsion * vy;
			dz += repulsion * vz;
		}

		// update position
			setXYZPos (self, px + dx, py + dy, pz + dz);
	}
}
Exemple #9
0
// NB STILL GETS CAUGHT IN LOCAL MINIMA AND NODES OVERLAP!
void NiceGraph::fruchtermanReingoldLayout(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax)
{
	float volume = (xmax - xmin) * (ymax - ymin) * (zmax - zmin);
	float k = 1000 * pow( ( volume / getNumVertices()),1.0f/3.0f );
	if ((zmin == 0) && (zmax ==0))
		k = pow (k,3.0f/2.0f); // for a two dimensional constant

	int iterations = 100;	// this value is arbitrary


	// use FR "quadrant variation" on 1/5 largest axes in zone
	// ie only calculate repulsion within the zone
	float zone = max(xmax - xmin, ymax - ymin);
	zone = max(zone, zmax - zmin);
	zone = zone;
	float t = zone;		// arbitrary initial temperature
	
	// do some arbitrary number of iterations
	for (int i = 0; i < iterations; i++)
	{
		map<int,float> dx,dy,dz; // store displacements by vertex ID until the end
		
		//calculate repulsive forces
		for (map<int,Vertex*>::iterator pU = vertexList.begin(); pU != vertexList.end(); pU++)
		{	// initialize values
			int u_id = pU->first;
			vector<float> u_pos(3);
			getXYZPos (u_id, u_pos);
			for (map<int,Vertex*>::iterator pV = vertexList.begin(); pV != vertexList.end(); pV++)
			{
				vector<float> v_pos(3);
				getXYZPos(pV->first, v_pos);
				float diffx =	v_pos[0]-u_pos[0];
				float diffy =   v_pos[1]-u_pos[1];
				float diffz =   v_pos[2]-u_pos[2];
				float dr = sqrt (diffx*diffx+diffy*diffy+diffz*diffz);		
				if (dr < zone)	// only do the calculations if U is within the zone of V
				{
					float force_r = 0;
					float scale = 0;
					if (dr == 0)
					{
						force_r = -100;
						scale = 1;
					}
					else
					{
						force_r = -1.0*(k * k)/dr; 
						scale = dr;
					}
					dx[u_id] += force_r * diffx/scale ;
					dy[u_id] += force_r * diffy/scale ;
					dz[u_id] += force_r * diffz/scale ;
				}
			}
		}
		
		// calculate attractive forces
		for (map<int,Edge*>::iterator pE = edgeList.begin(); pE != edgeList.end(); pE++)
		{
			vector<float> u_pos(3), v_pos(3);
			getEndpoints(pE->first, u_pos, v_pos);
			float diffx =	v_pos[0]-u_pos[0];
			float diffy =   v_pos[1]-u_pos[1];
			float diffz =   v_pos[2]-u_pos[2];
			float dr = sqrt (diffx*diffx + diffy*diffy + diffz*diffz);	

			float force_a = (dr*dr)/k;
			float scale = dr;
			if (dr ==0) scale = -1.0;
			dx[pE->second->from->vID] += force_a * diffx/scale ;
			dy[pE->second->from->vID] += force_a * diffy/scale ;
			dz[pE->second->from->vID] += force_a * diffz/scale ;
			dx[pE->second->to->vID] += -1.0 * force_a * diffx/scale ;
			dy[pE->second->to->vID] += -1.0 * force_a * diffy/scale ;
			dz[pE->second->to->vID] += -1.0 * force_a * diffz/scale ;
		}
	
		// now do bounds checking and update all the positions
		for (map<int,Vertex*>::iterator V = vertexList.begin(); V != vertexList.end(); V++)
		{
			int id = V->first;
			vector<float> p(3);
			getXYZPos(id,p);
			p[0] += min (dx[id],t);
			p[1] += min (dy[id],t);			
			p[2] += min (dz[id],t);			
			// also do bounds checking on frame??
			p[0] = min(xmax,max(xmin,p[0]));
			p[1] = min(ymax,max(ymin,p[1]));
			p[2] = min(zmax,max(zmin,p[2]));
			
			setXYZPos(id, p[0], p[1], p[2]);
		}
		// now cool the temperature a bit
		t*=.98;
	}
}