//returns true if the polygons passed as parameters intersect int PolyInPoly(const POLY * t1, const POLY * t2) { int i, j; LINE l1, l2; if(!t1 || !t2) return 0; if(PointInPoly(&t1->p[0], t2) || PointInPoly(&t1->p[1], t2) || PointInPoly(&t1->p[2], t2)) return 1; //if any of the points of t1 are in t2 for(i = 0; i < 3; i++) { l1.a.x = t1->p[i].x; l1.a.y = t1->p[i].y; l1.b.x = t1->p[(i + 1) % 3].x; l1.b.y = t1->p[(i + 1) % 3].y; for(j = 0; j < 3; j++) { l2.a.x = t2->p[j].x; l2.a.y = t2->p[j].y; l2.b.x = t2->p[(j + 1) % 3].x; l2.b.y = t2->p[(j + 1) % 3].y; if(LinesIntersect(&l1, &l2)) //if the line intersects any line in t2 return 1; } } return 0; //no intersection }
void cElHJaDroite::AddArcsInterieurInGraphe ( const std::vector<Pt2dr> & aEmprInit ) { cCmpPairSom aCmp; std::sort(mVPaires.begin(),mVPaires.end(),aCmp); for (INT aK=0 ; aK<INT(mVPaires.size()-1) ; aK++) { const cPaireSom & aPSA = mVPaires[aK]; const cPaireSom & aPSB = mVPaires[aK+1]; Pt2dr aPt = (aPSA.mPt+aPSB.mPt) / 2.0; if (PointInPoly(aEmprInit,aPt)) { ELISE_ASSERT((aPSA.mS1==aPSB.mS1)==(aPSA.mS2==aPSB.mS2),"cElHJaDroite::AddArcsInterieurInGraphe"); if (aPSA.mS1!=aPSB.mS1) { tArcGrPl * aArcPl1 = mP1->NewArcInterieur(aPSA.mS1,aPSB.mS1); tArcGrPl * aArcPl2 = mP2->NewArcInterieur(aPSA.mS2,aPSB.mS2); for (INT aK=0 ; aK<2 ; aK++) { aArcPl1->attr().SetArcHom(aArcPl2); aArcPl2->attr().SetArcHom(aArcPl1); // On swap aux arc reciproque aArcPl1 = &(aArcPl1->arc_rec()); aArcPl2 = &(aArcPl2->arc_rec()); } } } } }
bool HasInterOriente(const std::vector<Pt2dr> & f1,const std::vector<Pt2dr> & f2) { for (int aK=0; aK<int(f1.size()); aK++) if (PointInPoly(f2,f1[aK])) return true; return false; }
point2 poly2::RandInPoly() const { Double dx = xMax() - xMin(); Double dy = yMax() - yMin(); Double range = max(dx,dy); // VS2008 // rejection sampling logic point2 p0; do { Double x = xMin() + range*RandU(); Double y = yMin() + range*RandU(); p0 = point2(x,y); } while (!PointInPoly(p0)); return p0; }
REAL SquareDistPointPoly(const ElFifo<Pt2dr> & f,Pt2dr pt) { if ( PointInPoly(f,pt)) return 0; REAL d2 = 1e40; for (INT k=0; k<f.nb() ; k++) ElSetMin ( d2, SegComp(f[k],f[k+1]).square_dist_seg(pt) ); return d2; }
bool PointInterieurPoly(const ElFifo<Pt2dr> & f,Pt2dr pt,REAL d) { if (! PointInPoly(f,pt)) return false; REAL d2 = ElSquare(d); for (INT k=0; k<f.nb() ; k++) { Pt2dr q0 = f[k]; Pt2dr q1 = f[k+1]; if ((q0!=q1) && (SegComp(q0,q1).square_dist_seg(pt) < d2)) return false; } return true; }
void cElHJaArrangt::ConstruireAll() { mStats.push_back ( cStatistique ( 0.0, 0.0, mSurfEmpr * mNbPl ) ); bool toShoTime = false; ElTimer aChrono; ELISE_ASSERT(mNbPl>=0,"No Init int cElHJaArrangt"); // Construction de la geometrie 3D for (tItPl itPl = mPlans.begin() ; itPl!=mPlans.end() ; itPl++) { (*itPl)->SetNbPlansInter(mNbPl); } for (tItPl itPl1 = mPlans.begin() ; itPl1!=mPlans.end() ; itPl1++) { for (tItPl itPl2 = NextIter(itPl1) ; itPl2!=mPlans.end() ; itPl2++) { bool Ok; ElSeg3D aD3d = (*itPl1)->Plan().Inter((*itPl2)->Plan(),Ok); if (Ok) { mDroites.push_back(new cElHJaDroite(aD3d,**itPl1,**itPl2,mNbPl)); for (tItPl itPl3=NextIter(itPl2) ; itPl3!=mPlans.end() ; itPl3++) { Pt3dr aP = (*itPl1)->Plan().Inter((*itPl2)->Plan(),(*itPl3)->Plan(),Ok); if (Ok && PointInPoly(mEmprVPt2d,Proj(aP))) mPoints.push_back(new cElHJaPoint(aP,**itPl1,**itPl2,**itPl3)); } } } } for (tItPoint itPt = mPoints.begin() ; itPt!=mPoints.end() ; itPt++) (*itPt)->MakeDroites(); if (toShoTime) cout << "Time Geom3D : " << aChrono.ValAndInit() << "\n"; // Construction des Intersection Droites/emprise for (tItDr itD = mDroites.begin(); itD!=mDroites.end(); itD++) (*itD)->MakeIntersectionEmprise(mEmprPl); if (toShoTime) cout << "Time Inter Emprise : " << aChrono.ValAndInit() << "\n"; // Construction des facettes dans chaque plan for (tItPl itPl = mPlans.begin() ; itPl!=mPlans.end() ; itPl++) (*itPl)->AddArcEmpriseInGraphe(); for (tItDr itD = mDroites.begin(); itD!=mDroites.end(); itD++) (*itD)->AddArcsInterieurInGraphe(mEmprVPt2d); for (tItPl itPl = mPlans.begin() ; itPl!=mPlans.end() ; itPl++) (*itPl)->MakeFacettes(*this); if (toShoTime) cout << "Time Facette : " << aChrono.ValAndInit() << "\n"; // Construction des relations entre facettes for (tItFac itF = mFacettes.begin() ; itF!=mFacettes.end() ; itF++) (*itF)->MakeAdjacences(); for (tItFac itF1 = mFacettes.begin() ; itF1!=mFacettes.end() ; itF1++) for (tItFac itF2 = NextIter(itF1) ; itF2!=mFacettes.end() ; itF2++) (*itF1)->MakeRecouvrt(*itF2); TriTopologiqueFacette(); if (toShoTime) cout << "Time Relation F : " << aChrono.ValAndInit() << "\n"; }
/***** * Name: _XmHTMLGetImagemapAnchor * Return Type: XmHTMLAnchor* * Description: checks whether the given coordinates lie somewhere within * the given imagemap. * In: * html: XmHTMLWidget * x,y: point coordinates, relative to upper-left corner of the * html widget * image: current image data, required to make x and y coordinates * relative to upper-left corner of the image. * map: imagemap to check * Returns: * anchor data if successfull, NULL otherwise *****/ XmHTMLAnchor* _XmHTMLGetAnchorFromMap(XmHTMLWidget html, int x, int y, XmHTMLImage *image, XmHTMLImageMap *map) { int xs, ys; mapArea *area, *def_area; XmHTMLAnchor *anchor = NULL; Boolean found = False; /* map coordinates to upperleft corner of image */ xs = x + html->html.scroll_x - image->owner->x; ys = y + html->html.scroll_y - image->owner->y; _XmHTMLFullDebug(10, ("map.c: _XmHTMLGetAnchorFromMap, x = %i, y = %i, " "relative x = %i, relative y = %i\n", x, y, xs, ys)); area = map->areas; def_area = NULL; /* * We test against found instead of anchor becoming non-NULL: * areas with the NOHREF attribute set don't have an anchor but * should be taken into account as well. */ while(area && !found) { switch(area->shape) { case MAP_RECT: if(PointInRect(xs, ys, area->coords)) { anchor = area->anchor; found = True; } break; case MAP_CIRCLE: if(PointInCircle(xs, ys, area->coords[0], area->coords[1], area->coords[2])) { anchor = area->anchor; found = True; } break; case MAP_POLY: if(PointInPoly(xs, ys, area->region)) { anchor = area->anchor; found = True; } break; /* * just save default area info; it's only needed if nothing * else matches. */ case MAP_DEFAULT: def_area = area; break; } area = area->next; } if(!found && def_area) anchor = def_area->anchor; _XmHTMLFullDebug(10, ("map.c: _XmHTMLGetAnchorFromMap, %s anchor found\n", (anchor ? "an" : "no"))); return(anchor); }
// ------------------------------------------------------------------------------------------------ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result, const TempMesh& first_operand, ConversionData& conv) { ai_assert(hs != NULL); const IfcPlane* const plane = hs->BaseSurface->ToPtr<IfcPlane>(); if(!plane) { IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid"); return; } // extract plane base position vector and normal vector IfcVector3 p,n(0.f,0.f,1.f); if (plane->Position->Axis) { ConvertDirection(n,plane->Position->Axis.Get()); } ConvertCartesianPoint(p,plane->Position->Location); if(!IsTrue(hs->AgreementFlag)) { n *= -1.f; } n.Normalize(); // obtain the polygonal bounding volume boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh()); if(!ProcessCurve(hs->PolygonalBoundary, *profile.get(), conv)) { IFCImporter::LogError("expected valid polyline for boundary of boolean halfspace"); return; } IfcMatrix4 proj_inv; ConvertAxisPlacement(proj_inv,hs->Position); // and map everything into a plane coordinate space so all intersection // tests can be done in 2D space. IfcMatrix4 proj = proj_inv; proj.Inverse(); // clip the current contents of `meshout` against the plane we obtained from the second operand const std::vector<IfcVector3>& in = first_operand.verts; std::vector<IfcVector3>& outvert = result.verts; std::vector<unsigned int>::const_iterator begin = first_operand.vertcnt.begin(), end = first_operand.vertcnt.end(), iit; outvert.reserve(in.size()); result.vertcnt.reserve(first_operand.vertcnt.size()); std::vector<size_t> intersected_boundary_segments; std::vector<IfcVector3> intersected_boundary_points; // TODO: the following algorithm doesn't handle all cases. unsigned int vidx = 0; for(iit = begin; iit != end; vidx += *iit++) { if (!*iit) { continue; } unsigned int newcount = 0; bool was_outside_boundary = !PointInPoly(proj * in[vidx], profile->verts); // used any more? //size_t last_intersected_boundary_segment; IfcVector3 last_intersected_boundary_point; bool extra_point_flag = false; IfcVector3 extra_point; IfcVector3 enter_volume; bool entered_volume_flag = false; for(unsigned int i = 0; i < *iit; ++i) { // current segment: [i,i+1 mod size] or [*extra_point,i] if extra_point_flag is set const IfcVector3& e0 = extra_point_flag ? extra_point : in[vidx+i]; const IfcVector3& e1 = extra_point_flag ? in[vidx+i] : in[vidx+(i+1)%*iit]; // does the current segment intersect the polygonal boundary? const IfcVector3& e0_plane = proj * e0; const IfcVector3& e1_plane = proj * e1; intersected_boundary_segments.clear(); intersected_boundary_points.clear(); const bool is_outside_boundary = !PointInPoly(e1_plane, profile->verts); const bool is_boundary_intersection = is_outside_boundary != was_outside_boundary; IntersectsBoundaryProfile(e0_plane, e1_plane, profile->verts, intersected_boundary_segments, intersected_boundary_points); ai_assert(!is_boundary_intersection || !intersected_boundary_segments.empty()); // does the current segment intersect the plane? // (no extra check if this is an extra point) IfcVector3 isectpos; const Intersect isect = extra_point_flag ? Intersect_No : IntersectSegmentPlane(p,n,e0,e1,isectpos); #ifdef _DEBUG if (isect == Intersect_Yes) { const IfcFloat f = fabs((isectpos - p)*n); ai_assert(f < 1e-5); } #endif const bool is_white_side = (e0-p)*n >= -1e-6; // e0 on good side of plane? (i.e. we should keep all geometry on this side) if (is_white_side) { // but is there an intersection in e0-e1 and is e1 in the clipping // boundary? In this case, generate a line that only goes to the // intersection point. if (isect == Intersect_Yes && !is_outside_boundary) { outvert.push_back(e0); ++newcount; outvert.push_back(isectpos); ++newcount; /* // this is, however, only a line that goes to the plane, but not // necessarily to the point where the bounding volume on the // black side of the plane is hit. So basically, we need another // check for [isectpos-e1], which should yield an intersection // point. extra_point_flag = true; extra_point = isectpos; was_outside_boundary = true; continue; */ // [isectpos, enter_volume] potentially needs extra points. // For this, we determine the intersection point with the // bounding volume and project it onto the plane. /* const IfcVector3& enter_volume_proj = proj * enter_volume; const IfcVector3& enter_isectpos = proj * isectpos; intersected_boundary_segments.clear(); intersected_boundary_points.clear(); IntersectsBoundaryProfile(enter_volume_proj, enter_isectpos, profile->verts, intersected_boundary_segments, intersected_boundary_points); if(!intersected_boundary_segments.empty()) { vec = vec + ((p - vec) * n) * n; } */ //entered_volume_flag = true; } else { outvert.push_back(e0); ++newcount; } } // e0 on bad side of plane, e1 on good (i.e. we should remove geometry on this side, // but only if it is within the bounding volume). else if (isect == Intersect_Yes) { // is e0 within the clipping volume? Insert the intersection point // of [e0,e1] and the plane instead of e0. if(was_outside_boundary) { outvert.push_back(e0); } else { if(entered_volume_flag) { const IfcVector3& fix_point = enter_volume + ((p - enter_volume) * n) * n; outvert.push_back(fix_point); ++newcount; } outvert.push_back(isectpos); } entered_volume_flag = false; ++newcount; } else { // no intersection with plane or parallel; e0,e1 are on the bad side // did we just pass the boundary line to the poly bounding? if (is_boundary_intersection) { // and are now outside the clipping boundary? if (is_outside_boundary) { // in this case, get the point where the clipping boundary // was entered first. Then, get the point where the clipping // boundary volume was left! These two points with the plane // normal form another plane that intersects the clipping // volume. There are two ways to get from the first to the // second point along the intersection curve, try to pick the // one that lies within the current polygon. // TODO this approach doesn't handle all cases // ... IfcFloat d = 1e20; IfcVector3 vclosest; BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) { const IfcFloat dn = (v-e1_plane).SquareLength(); if (dn < d) { d = dn; vclosest = v; } } vclosest = proj_inv * vclosest; if(entered_volume_flag) { const IfcVector3& fix_point = vclosest + ((p - vclosest) * n) * n; outvert.push_back(fix_point); ++newcount; entered_volume_flag = false; } outvert.push_back(vclosest); ++newcount; //outvert.push_back(e1); //++newcount; } else { entered_volume_flag = true; // we just entered the clipping boundary. Record the point // and the segment where we entered and also generate this point. //last_intersected_boundary_segment = intersected_boundary_segments.front(); //last_intersected_boundary_point = intersected_boundary_points.front(); outvert.push_back(e0); ++newcount; IfcFloat d = 1e20; IfcVector3 vclosest; BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) { const IfcFloat dn = (v-e0_plane).SquareLength(); if (dn < d) { d = dn; vclosest = v; } } enter_volume = proj_inv * vclosest; outvert.push_back(enter_volume); ++newcount; } } // if not, we just keep the vertex else if (is_outside_boundary) { outvert.push_back(e0); ++newcount; entered_volume_flag = false; } } was_outside_boundary = is_outside_boundary; extra_point_flag = false; }
//performs clipping each frame void Clipping(void) { LIST * cur1; LIST * cur2; LIST * next; for(cur1 = g_asteroid_list; cur1; cur1 = next) { next = cur1->next; if(g_ships && !g_player.wait_time && (((ASTEROID *)cur1->d)->region & g_player.region) && PolyInCircle(&g_player.clip_poly, &(((ASTEROID *)cur1->d)->clip_circle))) //if the player hits the asteroid { PlayerHit(); AsteroidHit(cur1, 0); continue; } for(cur2 = g_alien_list; cur2; cur2 = cur2->next) { if((((ASTEROID *)cur1->d)->region & ((ALIEN *)cur2->d)->region) && (PolyInCircle(&(((ALIEN *)cur2->d)->clip_poly/*s[0]*/), &(((ASTEROID *)cur1->d)->clip_circle)) /*|| PolyInCircle(&(((ALIEN *)cur2->d)->clip_polys[1]), &(((ASTEROID *)cur1->d)->clip_circle)) || PolyInCircle(&(((ALIEN *)cur2->d)->clip_polys[2]), &(((ASTEROID *)cur1->d)->clip_circle))*/)) { AlienHit(cur2, 0); AsteroidHit(cur1, 0); break; } } if(cur2) //if we broke early from the loop continue; for(cur2 = g_shot_list; cur2; cur2 = cur2->next) { if((((ASTEROID *)cur1->d)->region & ((SHOT *)cur2->d)->region) && PointInCircle(&(((SHOT *)cur2->d)->pos), &(((ASTEROID *)cur1->d)->clip_circle))) //if any shot hits the asteroid { AsteroidHit(cur1, ((SHOT *)cur2->d)->player_owned); RemoveNode(cur2, &g_shot_list); break; } } if(cur2) //if we broke early from the loop continue; } for(cur1 = g_shot_list; cur1; cur1 = next) { next = cur1->next; if(!((SHOT *)cur1->d)->player_owned && g_ships && !g_player.wait_time && (g_player.region & ((SHOT *)cur1->d)->region) && PointInPoly(&(((SHOT *)cur1->d)->pos), &g_player.clip_poly)) //if the alien shot is inside player { RemoveNode(cur1, &g_shot_list); PlayerHit(); continue; } if(((SHOT *)cur1->d)->player_owned) { for(cur2 = g_alien_list; cur2; cur2 = cur2->next) { if((((SHOT *)cur1->d)->region & ((ALIEN *)cur2->d)->region) && (PointInPoly(&(((SHOT *)cur1->d)->pos), &(((ALIEN *)cur2->d)->clip_poly/*s[0]*/)) /*|| PointInPoly(&(((SHOT *)cur1->d)->pos), &(((ALIEN *)cur2->d)->clip_polys[1])) || PointInPoly(&(((SHOT *)cur1->d)->pos), &(((ALIEN *)cur2->d)->clip_polys[2]))*/)) { RemoveNode(cur1, &g_shot_list); AlienHit(cur2, 1); break; } } if(cur2) continue; } for(cur2 = g_powerup_list; cur2; cur2 = cur2->next) { if((((SHOT *)cur1->d)->region & ((POWERUP *)cur2->d)->region) && PointInCircle(&(((SHOT *)cur1->d)->pos), &(((POWERUP *)cur2->d)->clip_circle))) { PowerupHit(cur2, ((SHOT *)cur1->d)->player_owned); RemoveNode(cur1, &g_shot_list); break; } } if(cur2) continue; } if(g_ships && !g_player.wait_time) { for(cur1 = g_alien_list; cur1; cur1 = cur1->next) { if((g_player.region & ((ALIEN *)cur1->d)->region) && (PolyInPoly(&g_player.clip_poly, &(((ALIEN *)cur1->d)->clip_poly/*s[0]*/)) /*|| PolyInPoly(&g_player.clip_poly, &(((ALIEN *)cur1->d)->clip_polys[1])) || PolyInPoly(&g_player.clip_poly, &(((ALIEN *)cur1->d)->clip_polys[2]))*/)) { PlayerHit(); AlienHit(cur1, 0); break; } } } if(g_ships) { for(cur1 = g_powerup_list; cur1; cur1 = next) { next = cur1->next; if((g_player.region & ((POWERUP *)cur1->d)->region) && PolyInCircle(&g_player.clip_poly, &(((POWERUP *)cur1->d)->clip_circle))) { GetPowerup(cur1); continue; } } } }
void BotUpdateCorridor( int botClientNum, const botRouteTarget_t *target, botNavCmd_t *cmd ) { rVec spos; rVec epos; Bot_t *bot = &agents[ botClientNum ]; botRouteTargetInternal rtarget; if ( !cmd || !target ) { return; } GetEntPosition( botClientNum, spos ); rtarget = *target; epos = rtarget.pos; UpdatePathCorridor( bot, spos, rtarget ); if ( !bot->offMesh ) { if ( bot->needReplan ) { if ( FindRoute( bot, spos, rtarget, false ) ) { bot->needReplan = false; } } cmd->havePath = !bot->needReplan; if ( overOffMeshConnectionStart( bot, spos ) ) { dtPolyRef refs[ 2 ]; rVec start; rVec end; int corner = bot->numCorners - 1; dtPolyRef con = bot->cornerPolys[ corner ]; if ( bot->corridor.moveOverOffmeshConnection( con, refs, start, end, bot->nav->query ) ) { bot->offMesh = true; bot->offMeshPoly = con; bot->offMeshEnd = end; bot->offMeshStart = start; } } dtPolyRef firstPoly = bot->corridor.getFirstPoly(); dtPolyRef lastPoly = bot->corridor.getLastPoly(); if ( !PointInPoly( bot, firstPoly, spos ) ) { bot->needReplan = true; } if ( rtarget.type == BOT_TARGET_DYNAMIC ) { if ( !PointInPolyExtents( bot, lastPoly, epos, rtarget.polyExtents ) ) { bot->needReplan = true; } } rVec rdir; BotCalcSteerDir( bot, rdir ); VectorCopy( rdir, cmd->dir ); recast2quake( cmd->dir ); cmd->directPathToGoal = bot->numCorners <= 1; VectorCopy( bot->corridor.getPos(), cmd->pos ); recast2quake( cmd->pos ); // if there are no corners, we have reached the goal // FIXME: this must be done because of a weird bug where the target is not reachable even if // the path was checked for a partial path beforehand if ( bot->numCorners == 0 ) { VectorCopy( cmd->pos, cmd->tpos ); } else { VectorCopy( bot->corridor.getTarget(), cmd->tpos ); float height; if ( dtStatusSucceed( bot->nav->query->getPolyHeight( bot->corridor.getLastPoly(), cmd->tpos, &height ) ) ) { cmd->tpos[ 1 ] = height; } recast2quake( cmd->tpos ); } } if ( bot->offMesh ) { qVec pos, proj; qVec start = bot->offMeshStart; qVec end = bot->offMeshEnd; qVec dir; qVec pVec; GetEntPosition( botClientNum, pos ); start[ 2 ] = pos[ 2 ]; end[ 2 ] = pos[ 2 ]; ProjectPointOntoVectorBounded( pos, start, end, proj ); VectorCopy( proj, cmd->pos ); cmd->directPathToGoal = false; VectorSubtract( end, pos, cmd->dir ); VectorNormalize( cmd->dir ); VectorCopy( bot->corridor.getTarget(), cmd->tpos ); float height; if ( dtStatusSucceed( bot->nav->query->getPolyHeight( bot->corridor.getLastPoly(), cmd->tpos, &height ) ) ) { cmd->tpos[ 1 ] = height; } recast2quake( cmd->tpos ); cmd->havePath = true; if ( withinRadiusOfOffMeshConnection( bot, spos, bot->offMeshEnd, bot->offMeshPoly ) ) { bot->offMesh = false; } } }
bool cElHJaFacette::PointInFacette(Pt2dr aP) const { return PointInPoly(mVPt,aP); }
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"; } */ }