REAL IntersecSegCercle(const SegComp &aSeg,Pt2dr & Q0,Pt2dr & Q1) { Pt2dr T = aSeg.tangente(); Pt2dr p0 = aSeg.p0(); REAL a = square_euclid(T); REAL b = 2 * scal(T,p0); REAL c = square_euclid(p0) - 1; REAL delta = ElSquare(b) - 4 * a * c; REAL SqDelta = sqrt(ElMax(0.0,delta)); Q0 = p0 + T*((-b-SqDelta)/(2*a)); Q1 = p0 + T*((-b+SqDelta)/(2*a)); return delta; }
NS_RHH_BEGIN /*************************************************/ /* */ /* cImagH */ /* */ /*************************************************/ double cAppliReduc::ErrorSolLoc() { double aSomEr = 0.0; double aSomP = 0.0; for (int aKIm1=0 ; aKIm1<int(mIms.size()) ; aKIm1++) { cImagH * anI1 = mIms[aKIm1]; cElHomographie aCurH1 = anI1->HF()->HomCur(); if (anI1->C2CI()) { double aPdsE = 1 / anI1->PdsEchant(); const std::vector<cLink2Img*> & aVL = anI1->VLink(); for (int aKL=0 ; aKL<int(aVL.size()) ; aKL++) { cLink2Img * aLnk = aVL[aKL]; cImagH* anI2 = aLnk->Dest(); cElHomographie aCurH2 = anI2->HF()->HomCur(); cElHomographie aCurH2Inv = aCurH2.Inverse(); if (anI2->C2CI()) { cElHomographie aH12 = aLnk->Hom12(); const std::vector<Pt3dr> & anEch = aLnk->EchantP1(); for (int aKEch = 0 ; aKEch< int(anEch.size()) ; aKEch++) { Pt3dr aP3d = anEch[aKEch]; Pt2dr aP1(aP3d.x,aP3d.y); Pt2dr aP2 = aH12.Direct(aP1); double aPds = aP3d.z * aPdsE; Pt2dr aRes = aCurH2Inv.Direct(aCurH1.Direct(aP1)) - aP2; double anEr = square_euclid(aRes); aSomEr+= anEr * aPds; aSomP+= aPds; } } } } } return sqrt(aSomEr/aSomP); }
double cElPolygone::DiamSimple() const { tContour aC = ContSMax(); double aD2Max = 0.0; for (int aK1 = 0 ; aK1 <int(aC.size()); aK1++) for (int aK2 = aK1+1 ; aK2 <int(aC.size()); aK2++) { ElSetMax(aD2Max,square_euclid(aC[aK1],aC[aK2])); } return sqrt(aD2Max); }
void cMEPCoCentrik::OneItereRotPur(ElMatrix<REAL> & aMat,double & anErrStd) { L2SysSurResol aSysLin3(3); aSysLin3.GSSR_Reset(false); std::vector<double> aVRes; double aSomP=0; double aSomErr=0; for (ElPackHomologue::const_iterator itP=mPack.begin() ; itP!=mPack.end() ; itP++) { Pt3dr aQ1 = vunit(PZ1(itP->P1())); Pt3dr aQ2 = aMat * vunit(PZ1(itP->P2())); double aVQ2[3],aVQ1[3]; aQ2.to_tab(aVQ2); aQ1.to_tab(aVQ1); double anEcart = euclid(aQ1-aQ2); aVRes.push_back(anEcart); double aPds = itP->Pds() / (1 + ElSquare(anEcart / (2*anErrStd))); aSomP += aPds; aSomErr += aPds * square_euclid(aQ1-aQ2);; ElMatrix<REAL> aMQ2 = MatProVect(aQ2); for (int aY=0 ; aY< 3 ; aY++) { double aCoeff[3]; for (int aX=0 ; aX< 3 ; aX++) aCoeff[aX] = aMQ2(aX,aY); aSysLin3.GSSR_AddNewEquation(aPds,aCoeff,aVQ2[aY]-aVQ1[aY],0); } } double anErrRobut = MoyKPPVal(aVRes,NbForEcart(aVRes.size())); double anErrQuad = sqrt(aSomErr/aSomP); if (0) { std::cout << "ERR QUAD " << anErrQuad * mFoc << " Robust " << anErrRobut * mFoc << "\n"; } anErrStd = anErrQuad; Im1D_REAL8 aSol = aSysLin3.GSSR_Solve (0); double * aData = aSol.data(); ElMatrix<double> aMPV = MatProVect(Pt3dr(aData[0],aData[1],aData[2])); // std::cout << " aData " << aData[0] << " " << aData[1] << " " << aData[2] << "\n"; // aMat = NearestRotation(aMat * (ElMatrix<double>(3,true) +aMPV)); aMat = NearestRotation((ElMatrix<double>(3,true) +aMPV) * aMat); }
void NewtonAmel( REAL A0,REAL A1,REAL A2,REAL A3,REAL A4,Pt2dr & aP1) { for (INT aK=0 ; aK < 10 ; aK++) { Pt2dr aP2 = aP1 * aP1; Pt2dr aP3 = aP2 * aP1; Pt2dr aP4 = aP3 * aP1; Pt2dr F = aP4 * A0 + aP3 *A1 + aP2 * A2 + aP1 * A3 + Pt2dr(A4,0); if (square_euclid(F) > 0.9e-10) { Pt2dr D = aP3 * (A0*4) + aP2 *(A1*3) + aP1 * (A2 * 2) + Pt2dr(A3,0); if (square_euclid(D) > 1e-15) { aP1 -= F/D; } else return; } else return; } }
REAL SegComp::square_dist ( ModePrim m0, const SegComp & s1, ModePrim m1 ) const { bool got; inter(m0,s1,m1,got); if (got) return 0.0; if ((m0== droite) && (m1 == droite)) return square_euclid(p0()-s1.proj_ortho_droite(p0())); return std::min ( _square_dist(m0,s1,m1), s1._square_dist(m1,*this,m0) ); }
void cAppliReduc::AmelioHomLocal(cImagH & anIm) { double aPdsLVMStd = 0.1; double aPdsFreezC = 100; double aPdsEvol = 10;; int aNbIterSupl = 3; int aMaxIterProgr = 6; const std::vector<cLink2Img*> & aVLImC = mImCAmel->VLink(); for (int aKIm=0 ; aKIm<int(mIms.size()) ; aKIm++) { mIms[aKIm]->HF()->ReinitHom(cElHomographie::Id()); mIms[aKIm]->GainLoc() = 0; mIms[aKIm]->InitLoc() = false; } std::vector<cImagH *> aVIms ; for (int aKL=0 ; aKL<int(aVLImC.size()) ; aKL++) { cLink2Img * aLnK = aVLImC[aKL]; cImagH * anIm = aLnK->Dest(); anIm->GainLoc() = aLnK->PdsEchant() + 1e-7; anIm->C2CI() = true; aVIms.push_back(anIm); anIm->HF()->ReinitHom(aLnK->Hom12().Inverse()); } mImCAmel->GainLoc() = 1e10; mImCAmel->InitLoc() = true; mImCAmel->C2CI() = true; int aNbIm2Init = aVIms.size(); cCmpPtrImOnGain aCmpPtrIm; std::sort(aVIms.begin(),aVIms.end(),aCmpPtrIm); int aNbIterProgr = std::min(aMaxIterProgr,round_up(aVIms.size()/3.0)); int aNbIterTot = aNbIterProgr + aNbIterSupl; double aErrorIn = ErrorSolLoc(); if (Show(eShowGlob)) std::cout << "ERROR IN " << aErrorIn << "\n"; for (int aNbIter =0 ; aNbIter < aNbIterTot ; aNbIter ++) { if (aNbIter < aNbIterProgr) { int aK0 = (aNbIter *aNbIm2Init) / aNbIterProgr; int aK1 = ((aNbIter+1) *aNbIm2Init) / aNbIterProgr; for (int aKIm=aK0; aKIm<aK1 ; aKIm++) { ElPackHomologue aPack; cImagH * anIm = aVIms[aKIm]; const std::vector<cLink2Img*> & aVL = anIm->VLink(); int aNbInit=0; for (int aKL=0 ; aKL<int(aVL.size()) ; aKL++) { cLink2Img * aLnK = aVL[aKL]; cImagH * anI2 = aLnK->Dest(); if (anI2->InitLoc()) { const std::vector<Pt3dr> & anEch = aLnK->EchantP1(); cElHomographie aH = anI2->HF()->HomCur() * aLnK->Hom12(); for (int aKP=0 ; aKP<int(anEch.size()) ; aKP++) { const Pt3dr & aP3d = anEch[aKP]; Pt2dr aP1 (aP3d.x,aP3d.y); double aPds = aP3d.z; Pt2dr aP2 = aH.Direct(aP1); aPack.Cple_Add(ElCplePtsHomologues(aP1,aP2,aPds)); } aNbInit++; } } cElHomographie aNewH(aPack,true); anIm->HF()->ReinitHom(aNewH); if (Show(eShowDetail)) std::cout << anIm->Name() << " : " << aNbInit << "\n"; } for (int aKIm=aK0; aKIm<aK1 ; aKIm++) { aVIms[aKIm]->InitLoc() = true; } if (Show(eShowDetail)) std::cout << "==============================\n"; } if (mDoCompensLoc) { mSetEq.SetPhaseEquation(); double aSomEr=0; double aSomP=0; for (int aKIm1=0 ; aKIm1<int(mIms.size()) ; aKIm1++) { cImagH * anI1 = mIms[aKIm1]; anI1->AddViscositty((anI1== mImCAmel) ? aPdsFreezC : aPdsLVMStd); cElHomographie aCurH1 = anI1->HF()->HomCur(); if (anI1->InitLoc()) { double aPdsE = aPdsEvol / anI1->PdsEchant(); const std::vector<cLink2Img*> & aVL = anI1->VLink(); for (int aKL=0 ; aKL<int(aVL.size()) ; aKL++) { cLink2Img * aLnk = aVL[aKL]; cImagH* anI2 = aLnk->Dest(); cElHomographie aCurH2 = anI2->HF()->HomCur(); cElHomographie aCurH2Inv = aCurH2.Inverse(); if (anI2->InitLoc()) { double aSomRes = 0; double aSomCtrl = 0; cElHomographie aH12 = aLnk->Hom12(); const std::vector<Pt3dr> & anEch = aLnk->EchantP1(); cEqHomogFormelle * anEq = aLnk->EqHF(); int aNbPts = anEch.size(); for (int aKEch = 0 ; aKEch<int(aNbPts) ; aKEch++) { Pt3dr aP3d = anEch[aKEch]; Pt2dr aP1(aP3d.x,aP3d.y); Pt2dr aP2 = aH12.Direct(aP1); double aPds = aP3d.z * aPdsE; Pt2dr aRes = anEq->StdAddLiaisonP1P2(aP1,aP2,aPds,false); Pt2dr aCtrl = aCurH2Inv.Direct(aCurH1.Direct(aP1)) - aP2; aSomRes += euclid(aRes); aSomCtrl += euclid(aCtrl); double anEr = square_euclid(aRes); aSomEr+= anEr * aPds; aSomP+= aPds; } /* std::cout << anEq << " N12=" << anI1->Name() << " " << anI2->Name() << " ; RES = " << aSomRes/aNbPts << " Ctrl=" << aSomCtrl/aNbPts << "\n"; */ } } } // getchar(); // anI->HF()->SetModeCtrl(cNameSpaceEqF::eHomFigee); } if (Show(eShowDetail)) std::cout << "ERR = " << sqrt(aSomEr/aSomP) << "\n"; mSetEq.SolveResetUpdate(); } } for (int aKIm1=0 ; aKIm1<int(mIms.size()) ; aKIm1++) { cImagH * anI1 = mIms[aKIm1]; anI1->H2ImC() = anI1->HF()->HomCur(); } double aErrorOut = ErrorSolLoc(); if (Show(eShowGlob)) std::cout << "ERROR OUT " << aErrorOut << " DELTA=" << aErrorOut - aErrorIn << "\n"; }
double cObservLiaison_1Cple::AddObs ( const cPonderationPackMesure & aPPM, const cPonderationPackMesure * aPPMSurf ) { if (mEqS) { ELISE_ASSERT(aPPMSurf!=0,"No Pond for contrainte-surface"); } cPonderateur aPdrtIm(aPPM,mPack.size()); cPonderateur aPdrtSurf = aPdrtIm; // Pb d'init if (mEqS) { aPdrtSurf = cPonderateur(*aPPMSurf,mPack.size()); } double aS1=0; double aSEr2=0; double aSomPdsSurf = 0; mEcMax = 0.0; for ( ElPackHomologue::tCstIter itL=mPack.begin(); itL!=mPack.end(); itL++ ) { if (true) { double aNb = itL->Pds() * mMultPds; std::vector<double> aVPds; aVPds.push_back(1.0); aVPds.push_back(1.0); //const std::vector<Pt2dr> & aPTers = mPLiaisTer->ResiduPointLiaison(*itL,&aPInter); const cResiduP3Inc & aRes = mPLiaisTer->UsePointLiaison(cArg_UPL(0),-1,-1,0.0,*itL,aVPds,false); double aResidu = (square_euclid(aRes.mEcIm[0])+square_euclid(aRes.mEcIm[1])); ElSetMax(mEcMax,sqrt(aResidu)); double aPdsIm = aPdrtIm.PdsOfError(sqrt(aResidu)); aVPds[0]= (aPdsIm*aNb); aVPds[1]= (aPdsIm*aNb); double aPdsSurf = 0; if (mEqS) { aPdsSurf = aPdrtSurf.PdsOfError(ElAbs(aRes.mEcSurf)) *aNb; } aSomPdsSurf += aPdsSurf; mPLiaisTer->UsePointLiaison(cArg_UPL(0),-1,-1,aPdsSurf,*itL,aVPds,true); aSEr2 += aResidu * aNb; aS1 += aNb; if (int(aPPM.Show().Val()) >= int(eNSM_Indiv)) std::cout << "RLiais = " << sqrt(aResidu) << " pour P1 " << itL->P1() << "\n"; mPose1->AddPMoy(itL->P1(),aRes.mPTer,aRes.mBSurH); mPose2->AddPMoy(itL->P2(),aRes.mPTer,aRes.mBSurH); } } aSEr2 /= aS1; if (int(aPPM.Show().Val()) >= int(eNSM_Paquet)) { if (mEqS) std::cout << "PDS Surf = " << aSomPdsSurf << "\n"; std::cout << "| | | RESIDU LIAISON (pixel) = Ter-Im :" << sqrt(aSEr2) << " pour [" << mIm1 << "/" << mIm2 << "]" << " Max = " << mEcMax << "\n"; } // getchar(); return aSEr2 ; }
void bench_dist_point_seg_droite() /* On tire un segment vertical V et un point p, le calcul de d0 = D2(V,p) est trivial ; On tire une rotation affine r, soit d1 la distance r(V), r(p), elle doit etre invariante par rotation. Ce processus donne des pointe te sgement quelconuq on verifie d1=d0 */ { INT f; for (f =0; f< 1000; f++) { ElFifo<Pt2dr> poly; poly.set_circ(NRrandom3() > 0.5); random_polyl(poly,(INT)(2+20*NRrandom3())); SegComp s = random_seg(true); SegComp::ModePrim mode = ran_prim_seg(); ElFifo<Pt2dr> inters; ElFifo<INT > index; s.inter_polyline(mode,poly,index,inters); for (INT k=0; k<index.nb(); k++) { INT ind = index[k]; Pt2dr inter = inters[k]; Pt2dr p0 = poly[ind]; Pt2dr p1 = poly[ind+1]; BENCH_ASSERT ( (s.square_dist(mode,inter)<epsilon) && (SegComp(p0,p1).square_dist_seg(inter) < epsilon) ); } if ((mode==SegComp::droite) && poly.circ()) BENCH_ASSERT((inters.nb()%2)==0); } for ( f = 0; f<10000 ; f++) { bool ok; SegComp::ModePrim m0 = ran_prim_seg(); SegComp::ModePrim m1 = ran_prim_seg(); SegComp s0 = random_seg(true); SegComp s1 = SegNotPar(s0); Pt2dr i = s0.inter(m0,s1,m1,ok); BENCH_ASSERT ( (s0.square_dist_droite(i) < BIG_epsilon) && (s1.square_dist_droite(i) < BIG_epsilon) ); if ( pt_loin_from_bande(s0,i) && pt_loin_from_bande(s1,i) ) { BENCH_ASSERT ( ok == ( seg_prim_inside(s0,i,m0) && seg_prim_inside(s1,i,m1) ) ); } } for ( f = 0; f<10000 ; f++) { Pt2dr p1 = Pt2dr(0,NRrandom3()*1e3); Pt2dr p2 = Pt2dr(0,p1.y +10+1e3*NRrandom3()); Pt2dr q = Pt2dr((NRrandom3()-0.5)*1e4,(NRrandom3()-0.5)*1e4); SegComp::ModePrim mode = ran_prim_seg(); Pt2dr proj_q = Pt2dr(0,q.y); Pt2dr projP_q = proj_q; double d0 = ElSquare(q.x); double dp0 = d0; if (proj_q.y>p2.y) { if (mode == SegComp::seg) { dp0 += ElSquare(proj_q.y-p2.y); projP_q.y = p2.y; } } else if (proj_q.y<p1.y) { if (mode != SegComp::droite) { dp0 += ElSquare(proj_q.y-p1.y); projP_q.y = p1.y; } } Pt2dr tr = Pt2dr((NRrandom3()-0.5)*1e5,(NRrandom3()-0.5)*1e5); REAL teta = NRrandom3() *100; Pt2dr rot(cos(teta),sin(teta)); p1 = tr + p1 * rot; p2 = tr + p2 * rot; q = tr + q * rot; proj_q = tr + proj_q * rot; projP_q = tr + projP_q * rot; SegComp s(p1,p2); REAL d1 = s.square_dist_droite(q); REAL dp1 = s.square_dist(mode,q); BENCH_ASSERT(std::abs(d0 -d1) < BIG_epsilon); BENCH_ASSERT(std::abs(dp0 -dp1) < BIG_epsilon); Pt2dr proj_q_2 = s.proj_ortho_droite(q); BENCH_ASSERT( euclid(proj_q-proj_q_2) < BIG_epsilon); BENCH_ASSERT(euclid(projP_q,s.proj_ortho(mode,q))<BIG_epsilon); } for ( f = 0; f<10000 ; f++) { REAL rho = 1+NRrandom3()*1e3; REAL teta = (NRrandom3()-0.5)*1.9999*PI; Pt2dr p1 = Pt2dr::FromPolar(rho,teta); REAL teta2 = angle(p1); Pt2dr p2 = Pt2dr::FromPolar(1+NRrandom3()*1e3,NRrandom3()*1e3); REAL teta3 = angle(p2,p1*p2); BENCH_ASSERT(std::abs(teta2-teta)<epsilon); BENCH_ASSERT(std::abs(teta3-teta)<epsilon); } for ( f =0; f< 2000; f++) { SegComp::ModePrim m0 = ran_prim_seg(); SegComp::ModePrim m1 = ran_prim_seg(); SegComp s0 = random_seg(true); SegComp s1 = SegNotPar(s0); Seg2d proj = s0.proj_ortho(m0,s1,m1); BENCH_ASSERT ( std::abs ( square_euclid(proj.p0()-proj.p1()) -s0.square_dist(m0,s1,m1) ) < epsilon ); BENCH_ASSERT ( (s0.square_dist(m0,proj.p0())<epsilon) && (s1.square_dist(m1,proj.p1())<epsilon) ); for (INT k=0; k< 8*(2+(INT)m0)*(2+(INT)m1) ; k++) { Pt2dr q0 = proj.p0() + s0.tangente()*((NRrandom3()-0.5) * (1<<(k%10))) ; Pt2dr q1 = proj.p1() + s1.tangente()*((NRrandom3()-0.5) * (1<<(k%10))) ; q0 = s0.proj_ortho(m0,q0); q1 = s1.proj_ortho(m1,q1); BENCH_ASSERT ( euclid(proj.p0(),proj.p1()) < (euclid(q0,q1)+epsilon) ); } } cout << "OK OK OK DIIIIIIST \n"; }
REAL ElQTRegPt::D2(const Pt2dr & pt) const { return square_euclid(_pt,pt); }
void cMesh::setGraph(int img_idx, RGraph &aGraph, vector <int> &aTriInGraph, vector <unsigned int> const &aVisTriIdx) { int id1, id2, pos1, pos2; float E0, E1, E2; //parcours des aretes du graphe d'adjacence for (unsigned int aK=0; aK < mEdges.size(); aK++) { id1 = mEdges[aK].n1(); id2 = mEdges[aK].n2(); //on recherche id1 et id2 parmi les triangles visibles if ((find(aVisTriIdx.begin(), aVisTriIdx.end(), id1)!=aVisTriIdx.end()) && (find(aVisTriIdx.begin(), aVisTriIdx.end(), id2)!=aVisTriIdx.end())) { //on ajoute seulement les triangles qui ne sont pas encore presents dans le graphe if (find(aTriInGraph.begin(), aTriInGraph.end(), id1) == aTriInGraph.end()) { aTriInGraph.push_back(id1); aGraph.add_node(); } if (find(aTriInGraph.begin(), aTriInGraph.end(), id2) == aTriInGraph.end()) { aTriInGraph.push_back(id2); aGraph.add_node(); } } } cEdge elEdge; //creation des aretes et calcul de leur energie for (unsigned int aK=0; aK < mEdges.size(); aK++) { elEdge = mEdges[aK]; id1 = elEdge.n1(); id2 = elEdge.n2(); vector<int>::iterator it1 = find(aTriInGraph.begin(), aTriInGraph.end(), id1); vector<int>::iterator it2 = find(aTriInGraph.begin(), aTriInGraph.end(), id2); if ( (it1 != aTriInGraph.end()) && (it2 != aTriInGraph.end()) ) { //pos1 = (int) (it1 - aTriInGraph.begin()); //pos2 = (int) (it2 - aTriInGraph.begin()); pos1 = (int) distance(aTriInGraph.begin(), it1); pos2 = (int) distance(aTriInGraph.begin(), it2); //energies de l'arete triangle-source et de l'arete triangle-puit cTriangle *Tri1 = getTriangle(id1); cTriangle *Tri2 = getTriangle(id2); E1 = (float)Tri1->computeEnergy(img_idx); E2 = (float)Tri2->computeEnergy(img_idx); //if (E1 == 0.f) // aGraph.add_tweights( pos1, 0.f, 1.f ); //else //{ aGraph.add_tweights( pos1, (float)(mLambda*E1), 0.f ); //} //if (E2 == 0.f) // aGraph.add_tweights( pos2, 0.f, 1.f ); //else //{ aGraph.add_tweights( pos2, (float)(mLambda*E2), 0.f ); //} //energie de l'arete inter-triangles //longueur^2 de l'arete coupee par elEdge E0 = (float)square_euclid( getVertex( elEdge.v1() ), getVertex( elEdge.v2() ) ); aGraph.add_edge(pos1, pos2, E0, E0); //aGraph.add_edge(pos1, pos2, 1, 1); } } #ifdef oldoldold for (unsigned int aK=0; aK < aTriInGraph.size(); aK++) { cTriangle *Tri = getTriangle(aTriInGraph[aK]); E = Tri->computeEnergy(img_idx); if (E == 0.f) aGraph.add_tweights( aK, 1.f, 0.f ); else { aGraph.add_tweights( aK, mLambda*E, 0.f ); //aGraph.add_tweights( aK, 1.f, 0.f ); /*if (Tri->isInside()) aGraph.add_tweights( aK, 0.f, 1.f ); else aGraph.add_tweights( aK, 1.f, 0.f );*/ } } #endif }
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"; } */ }