From 68f0b9f73cc024b11b45e5f99a46caeec539414a Mon Sep 17 00:00:00 2001 From: SaraP Date: Mon, 15 Jun 2026 09:46:11 +0200 Subject: [PATCH] Vroni : - correzioni varie al calcolo dei bisettori approssimati. --- misc.cc | 87 +++++++++++++++++++++++++++++++++++++-- vd_basic.cc | 6 +-- vroni_added_functions.cpp | 23 +++++++---- 3 files changed, 101 insertions(+), 15 deletions(-) diff --git a/misc.cc b/misc.cc index 3e716ff..290a2e2 100644 --- a/misc.cc +++ b/misc.cc @@ -196,6 +196,9 @@ void vroniObject::AddParabolaToBuffer(int i, double t1, double t2, e_formula coeff; vr_bool increasing = true; + double t1Orig = t1 ; + double t2Orig = t2 ; + GetLftSiteData(i, &i1, &site_type); if (site_type == SEG) { GetRgtSiteData(i, &i2, &arc_type); @@ -238,6 +241,7 @@ void vroniObject::AddParabolaToBuffer(int i, double t1, double t2, if (t1 > t2) { VroniSwap(t1, t2, t); + VroniSwap( t1Orig, t2Orig, t) ; VroniSwap(u, v, w); } @@ -267,7 +271,7 @@ void vroniObject::AddParabolaToBuffer(int i, double t1, double t2, incr *= 1.1; t += incr; } - AddEdgeToBuffer(w.x, w.y, v.x, v.y, color, t - incr, t2); + AddEdgeToBuffer(w.x, w.y, v.x, v.y, color, t - incr, t2Orig); } else { t1 += (incr / 10.0); @@ -281,7 +285,7 @@ void vroniObject::AddParabolaToBuffer(int i, double t1, double t2, incr *= 1.1; t -= incr; } - AddEdgeToBuffer(w.x, w.y, u.x, u.y, color, t + incr, t1); + AddEdgeToBuffer(w.x, w.y, u.x, u.y, color, t + incr, t1Orig); } } @@ -316,6 +320,9 @@ void vroniObject::AddHyperbolaEllipseToBuffer(int i, double t1, double t2, double t, angle_s, angle_e, alpha, incr, radius, delta; vr_bool increasing = false; + double t1Orig = t1 ; + double t2Orig = t2 ; + GetLftSiteData(i, &i1, <ype); GetRgtSiteData(i, &i2, &rtype); assert((ltype == PNT) || (ltype == ARC)); @@ -385,6 +392,7 @@ void vroniObject::AddHyperbolaEllipseToBuffer(int i, double t1, double t2, if (VecDet(p, u, v) < 0.0) { VroniSwap(u, v, w); VroniSwap(t1, t2, t); + VroniSwap(t1Orig, t2Orig, t) ; } angle_s = atan2(u.y - p.y, u.x - p.x); angle_e = atan2(v.y - p.y, v.x - p.x); @@ -447,6 +455,7 @@ void vroniObject::AddHyperbolaEllipseToBuffer(int i, double t1, double t2, if (t1 > t2) { VroniSwap(t1, t2, t); + VroniSwap( t1Orig, t2Orig, t) ; VroniSwap(u, v, w); } @@ -482,7 +491,7 @@ void vroniObject::AddHyperbolaEllipseToBuffer(int i, double t1, double t2, incr *= 1.05; t += incr; } - AddEdgeToBuffer(w.x, w.y, v.x, v.y, color, t - incr, t2); + AddEdgeToBuffer(w.x, w.y, v.x, v.y, color, t - incr, t2Orig); } else { t1 += (incr / 10.0); @@ -498,7 +507,7 @@ void vroniObject::AddHyperbolaEllipseToBuffer(int i, double t1, double t2, incr *= 1.05; t -= incr; } - AddEdgeToBuffer(w.x, w.y, u.x, u.y, color, t + incr, t1); + AddEdgeToBuffer(w.x, w.y, u.x, u.y, color, t + incr, t1Orig); } } @@ -508,6 +517,76 @@ void vroniObject::AddHyperbolaEllipseToBuffer(int i, double t1, double t2, #endif +// ADD nel codice originale non prevista perchè il bisettore è una linea. La aggiungo per poter gestire meglio i parametri sul +// bisettore che, a differenza di un vero bisettore lineare, in questo caso non variano linearmente lungo la curva +void vroniObject::AddHyperbolaToBuffer(int i, double t1, double t2, + coord u, coord v, int color) +{ + e_formula coeff; + int i1, i2, i3; + t_site ltype, rtype; + coord w, w0; + double dist, incr, delta; + double t; + + GetLftSiteData(i, &i1, <ype); + GetRgtSiteData(i, &i2, &rtype); + assert((ltype == PNT) && (rtype == PNT)); + + if (i2 > i1) { + VroniSwap(i1, i2, i3); + } + + if (!ComputeHyperbolaData(i, &coeff)) { + /* */ + /* degenerate Voronoi edge */ + /* */ + AddEdgeToBuffer(u.x, u.y, v.x, v.y, color, t1, t2); + } + else { + + + if (t1 > t2) { + VroniSwap(t1, t2, t); + VroniSwap(u, v, w); + } + + t = PntPntDist(u, v) / misc_step_size; + if (t < 1.0) t = 1.0; + incr = (t2 - t1) / t; + + double tOld = t1 ; + t = t1 + incr ; + w = u; + while (t < t2) { + coord v0 ; + v0.x = coeff.A; + v0.y = coeff.B; + dist = coeff.d; + + delta = t1 * t1 - dist; + if (delta < 0.0) + delta = 0.0; + dist = t * t - dist; + if (dist < 0.0) + dist = 0.0; + double t0 = sqrt(dist) - sqrt(delta); + w0 = RayPnt(u, v0, t0); + + AddEdgeToBuffer(w.x, w.y, w0.x, w0.y, color, tOld, t); + w = w0; + tOld = t; + incr *= 1.05; + t += incr; + } + AddEdgeToBuffer(w.x, w.y, v.x, v.y, color, tOld, t2); + } + return; +} + + + + double vroniObject::NodeSegClassificator(int i, coord p) { coord u; diff --git a/vd_basic.cc b/vd_basic.cc index a9edb4a..01f096d 100644 --- a/vd_basic.cc +++ b/vd_basic.cc @@ -698,9 +698,9 @@ void vroniObject::AddVDEdgeToBuffer(int i) case(PNT): /* PNT-PNT: line bisector */ GetNodeData(n1, &u, &t1); GetNodeData(n2, &v, &t2); - AddEdgeToBuffer(nodes[n1].p.x, nodes[n1].p.y, - nodes[n2].p.x, nodes[n2].p.y, - VDColor, t1, t2); + // MODIF visto che degenera come linea nel codice originale veniva chiamato AddEdgeToBuffer, ma visto + // che il parametro non varia linearmente meglio gestirlo come hyperbola + AddHyperbolaToBuffer( i, t1, t2, u, v, VDColor) ; break; case(SEG): /* PNT-SEG: parabola bisector */ GetNodeData(n1, &u, &t1); diff --git a/vroni_added_functions.cpp b/vroni_added_functions.cpp index b75dd50..4afee44 100644 --- a/vroni_added_functions.cpp +++ b/vroni_added_functions.cpp @@ -171,11 +171,9 @@ vroniObject::GetBisectorType( int i) if ( t_lft == UNKNOWN || t_rgt == UNKNOWN || lft == NIL || rgt == NIL) return NONE ; - // Questo caso nel calcolo dei bisettori viene identificato come HYPERBOLA che degenera come linea. Visto che - // nel calcolo delle approssimazioni viene identificato come linea indico il tipo direttamente come LINE if (( t_lft == PNT) && ( t_rgt == PNT)) - return LINE ; - + return HYPERBOLA ; + else if (( t_lft == PNT) || ( t_lft == ARC)) { if (( t_rgt == PNT) || ( t_rgt == ARC)) { @@ -271,6 +269,12 @@ vroniObject::GetBisectorParams( int nEdge, double& dParS, double& dParE) vr_bool vroniObject::GetBisectorPointAtParam( int nEdge, double dPar, double pt[3]) { + // verifico se è necessario calcolare edges data + if ( num_edge_data == 0) { + int nTmp ; + InitializeEdgeData( false, false, false, &nTmp) ; + } + coord p ; EvaluateBisectorData( nEdge, ScaleV( dPar), &p) ; GetPointFromCoord( p, pt) ; @@ -280,7 +284,8 @@ vroniObject::GetBisectorPointAtParam( int nEdge, double dPar, double pt[3]) //---------------------------------------------------------------------------- vr_bool -vroniObject::GetBisectorSites( int nEdge, int& nOrigCrvL, int& nOrigSubCrvL, int& nOrigCrvR, int& nOrigSubCrvR) +vroniObject::GetBisectorSites( int nEdge, int& nOrigCrvL, int& nOrigSubCrvL, int& nOrigSubPntL, + int& nOrigCrvR, int& nOrigSubCrvR, int& nOrigSubPntR) { int nSiteL, nSiteR ; t_site typeL, typeR ; @@ -288,14 +293,16 @@ vroniObject::GetBisectorSites( int nEdge, int& nOrigCrvL, int& nOrigSubCrvL, int // resetto valori passati in input nOrigCrvL = -1 ; nOrigSubCrvL = -1 ; + nOrigSubPntL = -1 ; nOrigCrvR = -1 ; nOrigSubCrvR = -1 ; - + nOrigSubPntR = -1 ; + // sito a sinistra GetLftSiteData( nEdge, &nSiteL, &typeL) ; if ( typeL == PNT) { nOrigCrvL = pnts[nSiteL].ext_appl.first ; - nOrigSubCrvL = -1 ; + nOrigSubPntL = pnts[nSiteL].ext_appl.second ; } else if ( typeL == SEG) { nOrigCrvL = segs[nSiteL].ext_appl.first ; @@ -310,7 +317,7 @@ vroniObject::GetBisectorSites( int nEdge, int& nOrigCrvL, int& nOrigSubCrvL, int GetRgtSiteData( nEdge, &nSiteR, &typeR) ; if ( typeR == PNT) { nOrigCrvR = pnts[nSiteR].ext_appl.first ; - nOrigSubCrvR = -1 ; + nOrigSubPntR = pnts[nSiteR].ext_appl.second ; } else if ( typeR == SEG) { nOrigCrvR = segs[nSiteR].ext_appl.first ;