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; }
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); }
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; }
//--------------------------------------------------------- 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 ); }