예제 #1
0
void CLineCrossings::RemoveAll(void)
{
    int nCrossings = Crossings();
    for (int nCrossing = 0; nCrossing < nCrossings; nCrossing++)
    {
        delete Crossing(nCrossing);
    }

    CPtrArray::RemoveAll();
}
/**
 * This is the main routine of "MonoCrosser", and implements a monotonic strategy on multiple curves.
 * Finds crossings between two sets of paths, yielding a CrossingSet.  [0, a.size()) of the return correspond
 * to the sorted crossings of a with paths of b.  The rest of the return, [a.size(), a.size() + b.size()],
 * corresponds to the sorted crossings of b with paths of a.
 *
 * This function does two sweeps, one on the bounds of each path, and after that cull, one on the curves within.
 * This leads to a certain amount of code complexity, however, most of that is factored into the above functions
 */
CrossingSet MonoCrosser::crossings(std::vector<Path> const &a, std::vector<Path> const &b) {
    if(b.empty()) return CrossingSet(a.size(), Crossings());
    CrossingSet results(a.size() + b.size(), Crossings());
    if(a.empty()) return results;
    
    std::vector<std::vector<double> > splits_a = paths_mono_splits(a), splits_b = paths_mono_splits(b);
    std::vector<std::vector<Rect> > bounds_a = split_bounds(a, splits_a), bounds_b = split_bounds(b, splits_b);
    
    std::vector<Rect> bounds_a_union, bounds_b_union; 
    for(unsigned i = 0; i < bounds_a.size(); i++) bounds_a_union.push_back(union_list(bounds_a[i]));
    for(unsigned i = 0; i < bounds_b.size(); i++) bounds_b_union.push_back(union_list(bounds_b[i]));
    
    std::vector<std::vector<unsigned> > cull = sweep_bounds(bounds_a_union, bounds_b_union);
    Crossings n;
    for(unsigned i = 0; i < cull.size(); i++) {
        for(unsigned jx = 0; jx < cull[i].size(); jx++) {
            unsigned j = cull[i][jx];
            unsigned jc = j + a.size();
            Crossings res;
            
            //Sweep of the monotonic portions
            std::vector<std::vector<unsigned> > cull2 = sweep_bounds(bounds_a[i], bounds_b[j]);
            for(unsigned k = 0; k < cull2.size(); k++) {
                for(unsigned lx = 0; lx < cull2[k].size(); lx++) {
                    unsigned l = cull2[k][lx];
                    mono_pair(a[i], splits_a[i][k-1], splits_a[i][k],
                              b[j], splits_b[j][l-1], splits_b[j][l],
                              res, .1);
                }
            }
            
            for(unsigned k = 0; k < res.size(); k++) { res[k].a = i; res[k].b = jc; }
            
            merge_crossings(results[i], res, i);
            merge_crossings(results[i], res, jc);
        }
    }

    return results;
}
예제 #3
0
void CLineCrossings::AddCrossing(CFixed lPosition, int nCount)
{
    int nCrossings = Crossings();
    int nCrossing;

    // Look for the crossing in the array.
    // This will also determine the place to insert if it is not found.
    for (nCrossing = 0; nCrossing < nCrossings; nCrossing++)
    {
        // Get the crossing to check where we are.
        CLineCrossing* pCrossing = Crossing(nCrossing);

        // If this crossing is at our position, merge the counts.
        if (pCrossing->m_lPosition == lPosition)
        {
            // Update the existing one.
            if ((pCrossing->m_nCount += nCount) == 0)
            {
                // The crossing went away! Get rid of it.
                delete pCrossing;
                RemoveAt(nCrossing);
            }
            return;
        }
        if (pCrossing->m_lPosition > lPosition)
        {
            // Insert here.
            break;
        }
    }

    // The crossing was not found. Create a new one.
    CLineCrossing* pCrossing = new CLineCrossing;

    // Fill in the values.
    pCrossing->m_lPosition = lPosition;
    pCrossing->m_nCount = nCount;

    // Insert it where we stopped searching.
    InsertAt(nCrossing, pCrossing);
}
예제 #4
0
void SiftMatrix::updateIns(DDModel::Node *v,DDModel::Node *x) {
	bool toLeft = gd<DDNode>(x).order<gd<DDNode>(v).order;
	for(DDModel::inedge_iter uxi = x->ins().begin(); uxi!=x->ins().end(); ++uxi) {
		DDModel::Node *ux = (*uxi)->other(x);
		for(DDModel::inedge_iter uvi = v->ins().begin(); uvi!=v->ins().end(); ++uvi) {
			DDModel::Node *uv = (*uvi)->other(v);
			if(gd<DDNode>(ux).order==gd<DDNode>(uv).order)
				continue;
			unsigned cost = weigh(Crossings(*uxi,*uvi));
			dgassert(cost>=0);
			if(toLeft) {
			  setCrossings(uv,ux,true,getCrossings(uv,ux,true) -cost);
			  setCrossings(ux,uv,true,getCrossings(ux,uv,true)+cost);
			}
			else {
			  setCrossings(ux,uv,true,getCrossings(ux,uv,true)-cost);
			  setCrossings(uv,ux,true,getCrossings(uv,ux,true)+cost);
			}
		}
	}
}
CrossingSet crossings_among(std::vector<Path> const &p) {
    CrossingSet results(p.size(), Crossings());
    if(p.empty()) return results;
    
    SimpleCrosser cc;
    
    std::vector<std::vector<unsigned> > cull = sweep_bounds(bounds(p));
    for(unsigned i = 0; i < cull.size(); i++) {
        Crossings res = self_crossings(p[i]);
        for(unsigned k = 0; k < res.size(); k++) { res[k].a = res[k].b = i; }
        merge_crossings(results[i], res, i);
        flip_crossings(res);
        merge_crossings(results[i], res, i);
        for(unsigned jx = 0; jx < cull[i].size(); jx++) {
            unsigned j = cull[i][jx];
            
            Crossings res = cc.crossings(p[i], p[j]);
            for(unsigned k = 0; k < res.size(); k++) { res[k].a = i; res[k].b = j; }
            merge_crossings(results[i], res, i);
            merge_crossings(results[j], res, j);
        }
    }
    return results;
}
예제 #6
0
//---------------------------------------------------------
bool CSG_Network::_Add_Line(CSG_Shape *pLine, int ID)
{
	int			iEdge, iPoint, iCrossing;
	CSG_Shape	*pEdge, *pCrossing;
	CSG_Shapes	Crossings(SHAPE_TYPE_Point);

	//-----------------------------------------------------
	// 1. find crossings

	Crossings.Add_Field(SG_T("LINE_POINT")	, SG_DATATYPE_Int);
	Crossings.Add_Field(SG_T("EDGE_ID")		, SG_DATATYPE_Int);
	Crossings.Add_Field(SG_T("EDGE_POINT")	, SG_DATATYPE_Int);
	Crossings.Add_Field(SG_T("EDGE_DIST")	, SG_DATATYPE_Double);

	for(iEdge=0; iEdge<m_Edges.Get_Count(); iEdge++)
	{
		pEdge	= m_Edges.Get_Shape(iEdge);

		if( pEdge->Intersects(pLine) )
		{
			TSG_Point	a	= pEdge->Get_Point(0);

			for(int iEdge_Point=1; iEdge_Point<pEdge->Get_Point_Count(0); iEdge_Point++)
			{
				TSG_Point	b	= a;	a	= pEdge->Get_Point(iEdge_Point);
				TSG_Point	A	= pLine->Get_Point(0);

				for(iPoint=1; iPoint<pLine->Get_Point_Count(0); iPoint++)
				{
					TSG_Point	C, B	= A;	A	= pLine->Get_Point(iPoint);

					if( SG_Get_Crossing(C, A, B, a, b) )
					{
						pCrossing	= Crossings.Add_Shape();
						pCrossing->Add_Point(C);
						pCrossing->Set_Value(0, iPoint);
						pCrossing->Set_Value(1, iEdge);
						pCrossing->Set_Value(2, iEdge_Point);
						pCrossing->Set_Value(3, SG_Get_Distance(C, b));
					}
				}
			}
		}
	}


	//-----------------------------------------------------
	// 2. add new line's vertices

	Crossings.Set_Index(0, TABLE_INDEX_Ascending);

	pEdge		= m_Edges.Add_Shape();
	pEdge		->Set_Value(3, ID);

	for(iCrossing=0, iPoint=0; iCrossing<Crossings.Get_Count(); iCrossing++)
	{
		pCrossing	= Crossings.Get_Shape_byIndex(iCrossing);

		while( iPoint < pCrossing->asInt(0) )
		{
			pEdge->Add_Point(pLine->Get_Point(iPoint++));
		}

		pEdge->Add_Point(pCrossing->Get_Point(0));

		pEdge		= m_Edges.Add_Shape();
		pEdge		->Set_Value(3, ID);
		pEdge		->Add_Point(pCrossing->Get_Point(0));
	}

	while( iPoint < pLine->Get_Point_Count(0) )
	{
		pEdge->Add_Point(pLine->Get_Point(iPoint++));
	}


	//-----------------------------------------------------
	// 3. split edges, if necessary

	Crossings.Set_Index(1, TABLE_INDEX_Descending, 2, TABLE_INDEX_Ascending, 3, TABLE_INDEX_Ascending);

	for(iCrossing=0; iCrossing<Crossings.Get_Count(); )
	{
		pCrossing	= Crossings.Get_Shape_byIndex(iCrossing);
		iEdge		= pCrossing->asInt(1);
		pLine		= m_Edges.Get_Shape(iEdge);
		ID			= pLine->asInt(0);
		iPoint		= 0;
		pEdge		= m_Edges.Add_Shape();
		pEdge		->Set_Value(3, pLine->asInt(3));

		while( 1 )
		{
			while( iPoint < pCrossing->asInt(2) )
			{
				pEdge->Add_Point(pLine->Get_Point(iPoint++));
			}

			pEdge->Add_Point(pCrossing->Get_Point(0));

			if( ++iCrossing < Crossings.Get_Count() && iEdge == Crossings.Get_Shape_byIndex(iCrossing)->asInt(1) )
			{
				pEdge		= m_Edges.Add_Shape();
				pEdge		->Set_Value(3, pLine->asInt(3));

				pEdge->Add_Point(pCrossing->Get_Point(0));

				pCrossing	= Crossings.Get_Shape_byIndex(iCrossing);
			}
			else
			{
				if( iPoint < pLine->Get_Point_Count() )
				{
					pEdge		= m_Edges.Add_Shape();
					pEdge		->Set_Value(3, pLine->asInt(3));
		
					pEdge->Add_Point(pCrossing->Get_Point(0));

					while( iPoint < pLine->Get_Point_Count() )
					{
						pEdge->Add_Point(pLine->Get_Point(iPoint++));
					}
				}

				break;
			}
		}

		m_Edges.Del_Shape(iEdge);
	}

	return( true );
}