450352104a
- modifiche per utilizzare le funzioni di approssimazione lineare dei bisettori - migliorate funzioni aggiunte per gestire i bisettori.
387 lines
12 KiB
C++
387 lines
12 KiB
C++
/*****************************************************************************/
|
|
/* */
|
|
/* Funzioni aggiunte per integrare vroni con le nostre librerie */
|
|
/* Le funzioni modificate nel codice vengono individuate con il */
|
|
/* commento MODIF */
|
|
/*****************************************************************************/
|
|
|
|
#include "vroni_object.h"
|
|
#include "offset.h"
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
vroniObject::GetPointFromCoord( coord ptCoord, double p[3])
|
|
{
|
|
// trasformo vroni::coord in un array compatibile con il nostro Point3d
|
|
p[0] = ptCoord.x ;
|
|
p[1] = ptCoord.y ;
|
|
p[2] = 0.0 ;
|
|
|
|
// scalo
|
|
if ( unscaleXYZ) {
|
|
p[0] = UnscaleX( p[0]) ;
|
|
p[1] = UnscaleY( p[1]) ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
vroniObject::GetOffsetCurveCount( int i)
|
|
{
|
|
return GetOffsetListEnd(i) - GetOffsetListStart(i) + 1 ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vr_bool
|
|
vroniObject::GetOffsetCurve( int nOffs, int nCrv, int& nType, double ptS[3], double ptE[3], double ptC[3],
|
|
int& nOrigLoop, int& nOrigCrv, int& nOrigPnt)
|
|
{
|
|
// sito originale
|
|
nOrigLoop = -1 ;
|
|
nOrigCrv = -1 ;
|
|
nOrigPnt = -1 ;
|
|
|
|
if ( nOffs > num_offset_list)
|
|
return false ;
|
|
int k = GetOffsetListStart( nOffs) + nCrv ;
|
|
if ( k > GetOffsetListEnd( nOffs))
|
|
return false ;
|
|
|
|
assert( InOffsetData(k)) ;
|
|
// recupero il punto iniziale
|
|
coord start = GetOffsetPntCoords( k) ;
|
|
GetPointFromCoord( start, ptS) ;
|
|
|
|
// recupero punto finale
|
|
int m = k + 1 ;
|
|
if ( m > GetOffsetListEnd( nOffs))
|
|
m = GetOffsetListStart( nOffs) ;
|
|
coord end = GetOffsetPntCoords( m) ;
|
|
GetPointFromCoord( end, ptE) ;
|
|
|
|
if ( GetOffsetEleType( k) == PNT) {
|
|
int c = GetOffsetEleSite( k) ;
|
|
assert( InPntsList( c)) ;
|
|
coord center = GetPntCoords( c) ;
|
|
vr_bool ori = false ;
|
|
if ( ScrutinizeArc( start, end, center, &ori, ZERO_IO, HasIncidentSite( c))) {
|
|
nType = CW ;
|
|
// recupero le coordinate del centro
|
|
GetPointFromCoord( center, ptC) ;
|
|
}
|
|
else
|
|
nType = SEG ;
|
|
|
|
// recupero il sito
|
|
nOrigLoop = pnts[c].ext_appl.first ;
|
|
nOrigPnt = pnts[c].ext_appl.second ;
|
|
}
|
|
|
|
else if ( GetOffsetEleType( k) == SEG) {
|
|
nType = SEG ;
|
|
// recupero il sito
|
|
int c = GetOffsetEleSite( k) ;
|
|
nOrigLoop = segs[c].ext_appl.first ;
|
|
nOrigCrv = segs[c].ext_appl.second ;
|
|
}
|
|
|
|
else if ( GetOffsetEleType( k) == CCW || GetOffsetEleType( k) == CW) {
|
|
int c = GetOffsetEleSite( k) ;
|
|
assert( InArcsList( c)) ;
|
|
coord center = GetArcCenter( c) ;
|
|
vr_bool ori = ( GetOffsetEleType( k) == CCW ? true : false) ;
|
|
if ( ScrutinizeArc( start, end, center, &ori, ZERO_IO, true)) {
|
|
nType = ori ? CCW : CW ;
|
|
// recupero le coordinate del centro
|
|
GetPointFromCoord( center, ptC) ;
|
|
}
|
|
else
|
|
nType = SEG ;
|
|
|
|
// recupero il sito
|
|
nOrigLoop = arcs[c].ext_appl.first ;
|
|
nOrigCrv = arcs[c].ext_appl.second ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vroniObject::ResetVoronoiDiagram(void)
|
|
{
|
|
/* */
|
|
/* reset global and static data within individual files */
|
|
/* */
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
#if defined (OGL_GRAPHICS)
|
|
ResetGraphicsData();
|
|
#else
|
|
ExtApplResetGraphicsData;
|
|
#endif
|
|
ResetBufferData();
|
|
}
|
|
#endif
|
|
|
|
// sistemo i 4 punti estremi
|
|
SetXCoord( 0, -DBL_MAX) ;
|
|
SetYCoord( 0, -DBL_MAX) ;
|
|
SetXCoord( 1, -DBL_MAX) ;
|
|
SetYCoord( 1, DBL_MAX) ;
|
|
int i = num_pnts - 2 ;
|
|
SetXCoord( i, DBL_MAX) ;
|
|
SetYCoord( i, -DBL_MAX) ;
|
|
i = num_pnts - 1 ;
|
|
SetXCoord( i, DBL_MAX) ;
|
|
SetYCoord( i, DBL_MAX) ;
|
|
|
|
ResetVDData();
|
|
ResetVDConstructionData();
|
|
ResetEdgeData();
|
|
ResetOffsetData();
|
|
#ifdef MAT
|
|
ResetWMATStatus();
|
|
#endif
|
|
ResetIntersectionData();
|
|
ResetIntersectionStatus();
|
|
ResetCleanStatus();
|
|
|
|
isolated_pnts = false;
|
|
|
|
/* */
|
|
/* let the user call some application-specific function */
|
|
/* */
|
|
ExtApplFuncReset;
|
|
|
|
return;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
BisectorType
|
|
vroniObject::GetBisectorType( int i)
|
|
{
|
|
int lft, rgt ;
|
|
t_site t_lft, t_rgt ;
|
|
|
|
GetLftSiteData(i, &lft, &t_lft) ;
|
|
GetRgtSiteData(i, &rgt, &t_rgt) ;
|
|
|
|
BisectorType conic = NONE ;
|
|
if ( t_lft == UNKNOWN || t_rgt == UNKNOWN || lft == NIL || rgt == NIL)
|
|
return NONE ;
|
|
|
|
if (( t_lft == PNT) && ( t_rgt == PNT))
|
|
return HYPERBOLA ;
|
|
|
|
else if (( t_lft == PNT) || ( t_lft == ARC)) {
|
|
if (( t_rgt == PNT) || ( t_rgt == ARC)) {
|
|
|
|
if ( t_lft == PNT) {
|
|
assert( t_rgt == ARC) ;
|
|
assert( InArcsList( rgt)) ;
|
|
if ( IsArcStartPnt( rgt, lft) || IsArcEndPnt( rgt, lft))
|
|
return LINE ;
|
|
}
|
|
if ( t_rgt == PNT) {
|
|
assert( t_lft == ARC) ;
|
|
assert( InArcsList( lft)) ;
|
|
if ( IsArcStartPnt( lft, rgt) || IsArcEndPnt( lft, rgt))
|
|
return LINE ;
|
|
}
|
|
|
|
// verifico se degenere
|
|
e_formula coeff ;
|
|
if ( ! ComputeHyperbolaEllipseData( i, &coeff)) {
|
|
double r1 = t_lft == PNT ? 0.0 : GetArcRadius( lft) ;
|
|
coord p1 = t_lft == PNT ? GetPntCoords( lft) : GetArcCenter(lft) ;
|
|
double r2 = t_rgt == PNT ? 0.0 : GetArcRadius( rgt) ;
|
|
coord p2 = t_rgt == PNT ? GetPntCoords( rgt) : GetArcCenter(rgt) ;
|
|
double dx = p2.x - p1.x ;
|
|
double dy = p2.y - p1.y ;
|
|
double dist = dx * dx + dy * dy ;
|
|
if ( eq( dist, ZERO_MAX)) {
|
|
dist = r1 - r2;
|
|
if (! eq( dist, ZERO_MAX))
|
|
// degenerate elliptic edge
|
|
return DEGENERATE_HYPERELL ;
|
|
}
|
|
}
|
|
|
|
return HYPERELL ;
|
|
}
|
|
else {
|
|
assert( t_rgt == SEG);
|
|
assert( InSegsList( rgt));
|
|
if (( t_lft == PNT) &&
|
|
( IsSegStartPnt( rgt, lft) || IsSegEndPnt( rgt, lft)))
|
|
return LINE ;
|
|
else
|
|
return PARABOLA ;
|
|
}
|
|
}
|
|
else {
|
|
if (( t_rgt == PNT) || ( t_rgt == ARC)) {
|
|
assert( t_lft == SEG) ;
|
|
assert( InSegsList( lft)) ;
|
|
if (( t_rgt == PNT) &&
|
|
( IsSegStartPnt( lft, rgt) || IsSegEndPnt( lft, rgt)))
|
|
return LINE ;
|
|
else
|
|
return PARABOLA ;
|
|
}
|
|
else {
|
|
return LINE ;
|
|
}
|
|
}
|
|
|
|
return conic ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
vroniObject::GetApproxedBisectorPointsNbr( int nEdge)
|
|
{
|
|
// se il bisettore non è quello approssimato nel buffer devo calcolarlo
|
|
if ( nEdge != m_nBufferedVDEdge) {
|
|
ResetVDBuffer() ;
|
|
AddVDEdgeToBuffer( nEdge) ;
|
|
m_nBufferedVDEdge = nEdge ;
|
|
}
|
|
|
|
return num_vde_buf + 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vr_bool
|
|
vroniObject::GetApproxedBisectorPoint( int nEdge, int nIdx, double pt[3], double& dPar)
|
|
{
|
|
// se il bisettore non è quello approssimato nel buffer devo calcolarlo
|
|
if ( nEdge != m_nBufferedVDEdge) {
|
|
ResetVDBuffer() ;
|
|
AddVDEdgeToBuffer( nEdge) ;
|
|
m_nBufferedVDEdge = nEdge ;
|
|
}
|
|
|
|
// verifico validità dell'indice passato
|
|
int nPoints = GetApproxedBisectorPointsNbr( nEdge) ;
|
|
if ( nIdx < 0 || nIdx >= nPoints)
|
|
return false ;
|
|
|
|
if ( nIdx == 0) {
|
|
GetPointFromCoord( vde_buf[0].p1, pt) ;
|
|
dPar = UnscaleV( vde_buf[0].dPar1) ;
|
|
}
|
|
else {
|
|
GetPointFromCoord( vde_buf[nIdx-1].p2, pt) ;
|
|
dPar = UnscaleV( vde_buf[nIdx-1].dPar2) ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vr_bool
|
|
vroniObject::GetLinearBisectorData( int nEdge, double ptS[3], double ptE[3], double& dParS, double& dParE)
|
|
{
|
|
// verifico sia effettivamente bisettore lineare
|
|
if ( GetBisectorType( nEdge) != BisectorType::LINE)
|
|
return false ;
|
|
|
|
// calcolo i parametri
|
|
GetEdgeParam( nEdge, &dParS, &dParE) ;
|
|
dParS = UnscaleV( dParS) ;
|
|
dParE = UnscaleV( dParE) ;
|
|
|
|
// calcolo gli estremi
|
|
coord coordS = GetNodeCoord( edges[nEdge].n1) ;
|
|
GetPointFromCoord( coordS, ptS) ;
|
|
coord coordE = GetNodeCoord( edges[nEdge].n2) ;
|
|
GetPointFromCoord( coordE, ptE) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vr_bool
|
|
vroniObject::GetDegenerateHyperEllipticBisectorData( int nEdge, double ptS[3], double ptE[3], double ptC[3], double& dParS, double& dParE)
|
|
{
|
|
// verifico sia effettivamente del tipo corretto
|
|
if ( GetBisectorType( nEdge) != BisectorType::DEGENERATE_HYPERELL)
|
|
return false ;
|
|
|
|
// calcolo il centro
|
|
int i1, i2 ;
|
|
t_site ltype, rtype ;
|
|
GetLftSiteData( nEdge, &i1, <ype) ;
|
|
GetRgtSiteData( nEdge, &i2, &rtype) ;
|
|
coord p1 = ( ltype == PNT ? GetPntCoords( i1) : GetArcCenter( i1)) ;
|
|
coord p2 = ( rtype == PNT ? GetPntCoords( i2) : GetArcCenter( i2)) ;
|
|
coord p = MidPoint( p1, p2) ;
|
|
GetPointFromCoord( p, ptC) ;
|
|
|
|
// calcolo gli estremi
|
|
coord coordS = GetNodeCoord( edges[nEdge].n1) ;
|
|
GetPointFromCoord( coordS, ptS) ;
|
|
coord coordE = GetNodeCoord( edges[nEdge].n2) ;
|
|
GetPointFromCoord( coordE, ptE) ;
|
|
|
|
// calcolo i parametri
|
|
GetEdgeParam( nEdge, &dParS, &dParE) ;
|
|
dParS = UnscaleV( dParS) ;
|
|
dParE = UnscaleV( dParE) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vr_bool
|
|
vroniObject::IsWMATEdge( int nEdge)
|
|
{
|
|
return edges[nEdge].w_mat.in_w_mat ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
vroniObject::MyWriteVoronoiRegion( FILE *output)
|
|
{
|
|
fprintf(output, "\n\nEDGES DATA \n\n") ;
|
|
for ( int i = 0 ; i < num_edges ; i ++) {
|
|
fprintf(output, "\nVoronoi edge %i", i) ;
|
|
fprintf(output, "\n n1 = %i", edges[i].n1) ;
|
|
fprintf(output, "\n n2 = %i", edges[i].n2) ;
|
|
fprintf(output, "\n lft = %i", edges[i].lft) ;
|
|
fprintf(output, "\n rgt = %i", edges[i].rgt) ;
|
|
fprintf(output, "\n lft type = %i", edges[i].ltype) ;
|
|
fprintf(output, "\n rgt type = %i", edges[i].rtype) ;
|
|
fprintf(output, "\n s_ccw = %i", edges[i].s_ccw) ;
|
|
fprintf(output, "\n s_cw = %i", edges[i].s_cw) ;
|
|
fprintf(output, "\n e_ccw = %i", edges[i].e_ccw) ;
|
|
fprintf(output, "\n e_cw = %i", edges[i].e_cw) ;
|
|
if (IsWmatEdge(i)) {
|
|
fprintf(output, "\n wmat = %i", edges[i].w_mat.in_w_mat) ;
|
|
// fprintf(output, "\n-- wmat rmin = %f", UnscaleV( edges[i].w_mat.r_min)) ; // solo con WMAT
|
|
// fprintf(output, "\n-- wmat rmax= %f", UnscaleV( edges[i].w_mat.r_max)) ; // solo con WMAT
|
|
}
|
|
|
|
// BisectorType nType = EvaluateBisectorType( i) ;
|
|
// fprintf(output, "\n-- type = %i", nType) ;
|
|
// double p1, p2 ;
|
|
// GetEdgeParam( i, &p1, &p2) ;
|
|
// fprintf(output, "\n-- line param %f %f", UnscaleV( p1), UnscaleV( p2)) ;
|
|
}
|
|
|
|
fprintf(output, "\n\nNODES DATA\n\n") ;
|
|
for ( int i = 0 ; i < num_nodes ; i ++) {
|
|
fprintf(output, "\n Voronoi node %i", i) ;
|
|
auto p = GetNodeCoord(i) ;
|
|
fprintf(output, "\n pt = %f %f", UnscaleX(p.x), UnscaleY(p.y)) ;
|
|
fprintf(output, "\n r2 = %f", UnscaleV( nodes[i].r2)) ;
|
|
fprintf(output, "\n deg2 = %i", nodes[i].deg2) ;
|
|
fprintf(output, "\n edge = %i", nodes[i].edge) ;
|
|
fprintf(output, "\n site = %i", nodes[i].site) ;
|
|
}
|
|
|
|
return ;
|
|
|
|
}
|