segment_id AddSegName( const char *segname, const char *class_name, int segtype ) { struct spc_info *initfini; segment_id segid; initfini = InitFiniLookup( segname ); if( initfini != NULL ) { AddSeg( initfini[0].name, initfini[0].class_name, initfini[0].segtype ); AddSeg( initfini[1].name, initfini[1].class_name, initfini[1].segtype ); AddSeg( initfini[2].name, initfini[2].class_name, initfini[2].segtype ); } segid = AddSeg( segname, class_name, segtype ); return( segid ); }
void ISegChain::AddChain( ISegChain* B ) { deque< ISeg* >::iterator s; deque< ISeg* >::reverse_iterator r; ISeg* backSegA = m_ISegDeque.back(); ISeg* frontSegA = m_ISegDeque.front(); ISeg* backSegB = B->m_ISegDeque.back(); ISeg* frontSegB = B->m_ISegDeque.front(); double dBackBack = backSegA->MinDist( backSegB ); double dBackFront = backSegA->MinDist( frontSegB ); double dFrontBack = frontSegA->MinDist( backSegB ); double dFrontFront = frontSegA->MinDist( frontSegB ); if ( dBackBack < dBackFront && dBackBack < dFrontBack && dBackBack < dFrontFront ) { for ( r = B->m_ISegDeque.rbegin() ; r != B->m_ISegDeque.rend() ; r++ ) { AddSeg( (*r) ); } } else if ( dBackFront < dFrontBack && dBackFront < dFrontFront ) { for ( s = B->m_ISegDeque.begin() ; s != B->m_ISegDeque.end() ; s++ ) { AddSeg( (*s) ); } } else if ( dFrontBack < dFrontFront ) { for ( r = B->m_ISegDeque.rbegin() ; r != B->m_ISegDeque.rend() ; r++ ) { AddSeg( (*r) ); } } else { for ( s = B->m_ISegDeque.begin() ; s != B->m_ISegDeque.end() ; s++ ) { AddSeg( (*s) ); } } B->m_ISegDeque.clear(); }
void Line::ClipEndpoints(Line &source,const Coord offsetTail,const Region *tl, const Coord offsetHead, const Region *hd) { if(!tl&&!hd) { *(Line*)this = source; return; } Clear(); degree = source.degree; if(source.Empty()) return; /* find terminal sections */ int firstI,lastI; if(tl) { for(firstI = 0; firstI < int(source.size())-1; firstI += degree) if(!tl->Hit(source[firstI + degree]-offsetTail)) break; } else firstI = 0; if(hd) { for(lastI = source.size() - degree - 1; lastI >= 0; lastI -= degree) if(!hd->Hit(source[lastI]-offsetHead)) break; } else lastI = source.size() - degree - 1; /* if(firstI>lastI) { reports[dgr::bug] << "<?xml version=\"1.0\" standalone=\"no\"?>" << endl << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"" << endl << "\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">" << endl; reports[dgr::bug] << "<svg width=\"100%%\" height=\"100%%\">" << endl; const PolylineRegion *pr = static_cast<const PolylineRegion*>(tl); Coord ul = offsetTail; // (offsetTail.x - pr->boundary.Width()/2,offsetTail.y + pr->boundary.Height()/2); showshape(pr->shape,ul,offsetTail); pr = static_cast<const PolylineRegion*>(hd); showshape(pr->shape,ul,offsetHead); showshape(source,ul); reports[dgr::bug] << "</svg>" << endl; } */ Coord temp[4]; for(int i = firstI; i <= lastI; i += degree) { Coord *section = &source[i]; if(i==firstI && tl) section = clip(&*section,offsetTail,*tl,temp); if(i==lastI && hd) section = clip(&*section,offsetHead,*hd,temp); AddSeg(section); } }
/* 1.8 Close completes the cycle if this is not already the case and pre-calculates the convex hull. */ void Face::Close() { if (v.size() < 2) // Cannot close a face with only one (or even no) segment return; int i = v.size() - 1; if (!(v[i].e == v[0].s)) { // The cycle is not closed yet, we do that now. Seg s(v[i].e, v[0].s); AddSeg(s); } Sort(); ConvexHull(); Check(); }
void Reg::Close() { int i = v.size() - 1; if ((v[i].x2 != v[0].x1) || (v[i].y2 != v[0].y1)) { Seg s = Seg(v[i].x2, v[i].y2, v[0].x1, v[0].y1); AddSeg(s); } v = sortSegs(v); cerr << "Dumping Reg\n" << ToString() << "Dumping Reg End\n"; ConvexHull(); }
Reg::Reg(ListExpr le) { le = nl->First(le); while (nl->ListLength(le) > 1) { ListExpr pa = nl->First(le); ListExpr pb = nl->First(nl->Rest(le)); // cerr << nl->ToString(pa) << " " << nl->ToString(pb) << "\n"; int p1 = nl->RealValue(nl->First(pa)); pa = nl->Rest(pa); int p2 = nl->RealValue(nl->First(pa)); pa = nl->Rest(pa); int p3 = nl->RealValue(nl->First(pb)); pb = nl->Rest(pb); int p4 = nl->RealValue(nl->First(pb)); pb = nl->Rest(pb); le = nl->Rest(le); Seg s = Seg(p1, p2, p3, p4); AddSeg(s); } Close(); }
/* 1.1 Constructs a face from a region-listexpression. */ Face::Face(ListExpr tle, bool withHoles) : cur(0), parent(NULL), ishole(false) { ListExpr le = nl->First(tle); // Construct segments from the points while (nl->ListLength(le) > 1) { ListExpr pa = nl->First(le); ListExpr pb = nl->First(nl->Rest(le)); double p1 = nl->RealValue(nl->First(pa)) * SCALEIN; pa = nl->Rest(pa); double p2 = nl->RealValue(nl->First(pa)) * SCALEIN; pa = nl->Rest(pa); double p3 = nl->RealValue(nl->First(pb)) * SCALEIN; pb = nl->Rest(pb); double p4 = nl->RealValue(nl->First(pb)) * SCALEIN; pb = nl->Rest(pb); le = nl->Rest(le); Seg s = Seg(Pt(p1, p2), Pt(p3, p4)); AddSeg(s); } if (v.size() < 2) { // Only one segment yet, this cannot be valid. Return an empty region. v.clear(); } Close(); // Close and sort the cycle // Construct the holes while (withHoles && nl->ListLength(tle) > 1) { tle = nl->Rest(tle); Face hole(tle, false); if (hole.v.size() < 3) // Invalid hole continue; hole.ishole = true; holes.push_back(hole); } Check(); }
//========================================================================== // // returns the seg whose partner seg determines where this // section continues // //========================================================================== bool AddSubSector(subsector_t *subsec, vertex_t *startpt, seg_t **pNextSeg) { unsigned i = 0; if (startpt != NULL) { // find the seg in this subsector that starts at the given vertex for(i = 0; i < subsec->numlines; i++) { if (subsec->firstline[i].v1 == startpt) break; } if (i == subsec->numlines) { DPrintf("Vertex not found in subsector %d. Cannot create Sections.\n", subsec-subsectors); return false; // Nodes are bad } } else { // Find the first unprocessed non-miniseg for(i = 0; i < subsec->numlines; i++) { seg_t *seg = subsec->firstline + i; if (seg->sidedef == NULL) continue; if (IntraSectorSeg(seg)) continue; if (ISDONE(seg-segs, processed_segs)) continue; break; } if (i == subsec->numlines) { DPrintf("Unable to find a start seg. Cannot create Sections.\n"); return false; // Nodes are bad } startpt = subsec->firstline[i].v1; } seg_t *thisseg = subsec->firstline + i; if (IntraSectorSeg(thisseg)) { SETDONE(thisseg-segs, processed_segs); // continue with the loop in the adjoining subsector *pNextSeg = thisseg; return true; } while(1) { if (loop->numlines > 0 && thisseg->v1 == v1_l1 && thisseg->v2 == v2_l1) { // This loop is complete *pNextSeg = NULL; return true; } if (!AddSeg(thisseg)) return NULL; i = (i+1) % subsec->numlines; seg_t *nextseg = subsec->firstline + i; if (thisseg->v2 != nextseg->v1) { DPrintf("Segs in subsector %d are not continuous. Cannot create Sections.\n", subsec-subsectors); return false; // Nodes are bad } if (IntraSectorSeg(nextseg)) { SETDONE(nextseg-segs, processed_segs); // continue with the loop in the adjoining subsector *pNextSeg = nextseg; return true; } thisseg = nextseg; } }
void cICL_Courbe::DoAll(const std::vector<Pt2dr> & VPtsInit) { mVPts = VPtsInit; if (surf_or_poly(mVPts) < 0) std::reverse(mVPts.begin(),mVPts.end()); INT aNbPts = (INT) mVPts.size(); mVArcs.clear(); for (INT aK=0 ; aK < aNbPts ; aK++) { Pt2dr aP1 = mVPts[aK]; Pt2dr aP2 = mVPts[(aK+1)%aNbPts]; bool isP1Inside = (square_euclid(aP1) < 1.0); bool isP2Inside = (square_euclid(aP2) < 1.0); if (isP1Inside && isP2Inside) { AddSeg(aP1,false,aP2,false); } else { Pt2dr aQ1,aQ2; SegComp aS12(aP1,aP2); REAL D = IntersecSegCercle(aS12,aQ1,aQ2); if ((! isP1Inside) && (! isP2Inside)) { if (D>0) { Pt2dr Mil = (aQ1+aQ2)/2.0; if (aS12.in_bande(Mil,SegComp::seg)) AddSeg(aQ1,true,aQ2,true); } } else if (isP1Inside && (! isP2Inside)) AddSeg(aP1,false,aQ2,true); else AddSeg(aQ1,true,aP2,false); } } mSurf = 0; if (mVArcs.empty()) { mDerivNulles = true; if (PointInPoly(mVPts,Pt2dr(0,0))) mSurf = PI; else mSurf = 0.0; } else { mDerivNulles = false; INT aNbA = (INT) mVArcs.size() ; for (INT aK=0 ; aK< aNbA ; aK++) { cICL_Arc & anA = mVArcs[aK]; mSurf += (anA.P0() ^ anA.P1()) / 2.0; if (anA.IsP1OnCercle()) { cICL_Arc & nextA = mVArcs[(aK+1)%aNbA]; if (nextA.IsP0OnCercle()) { REAL Ang = angle(anA.P1(),nextA.P0()); if (Ang <0) Ang += 2 * PI; mSurf += Ang/2.0; } } } } /* if (true) { INT aNbPts = mVPts.size(); ElList<Pt2di> lPts; REAL scale = 1000.0; for (int aK=0 ; aK<aNbPts ; aK++) lPts = lPts + Pt2di(mVPts[aK]*scale); INT Ok; ELISE_COPY ( polygone(lPts), (FX*FX+FY*FY) < scale*scale, sigma(Ok) ); cout << " SURF = " << mSurf << " SDig = " << Ok/ElSquare(scale) << "\n"; } */ }