blob: e34d93451cf057744fa8b43d05611ebba4fc9671 [file] [log] [blame]
#include "geo.h"
extern void tinsert( TNODEPTR *root , int value , int property );
extern void tpop( TNODEPTR *root , TNODEPTR *node , int *value ,
int *property );
void reduceg(void)
{
int i , j , min , minc , WCcount , guideline , twoTimes ;
int c , count , c1 , c2 , hit , flag , k ;
int length , index1 , index2 , i1 , i2 , c2i1 , vertical ;
int xmin , xmax , ymin , ymax , end , start , edge ;
TNODEPTR node , Qroot ;
WCPTR ptr , *WCarray ;
Qroot = (TNODEPTR) NULL ;
WCarray = (WCPTR *) malloc( 101 * sizeof( WCPTR ) ) ;
WCcount = 0 ;
for( i = 1 ; i <= eNum ; i++ ) {
eArray[i].notActive = 0 ;
}
for( i = 1 ; i <= numRects ; i++ ) {
rectArray[i].ur = 0 ;
rectArray[i].lr = 0 ;
rectArray[i].ul = 0 ;
rectArray[i].ll = 0 ;
}
for( i = 1 ; i <= numXnodes ; i++ ) {
for( ptr = xNodeArray[i] ; ptr != (WCPTR) NULL ; ptr = ptr->next ){
if( ptr->fixedWidth == 1 ) {
continue ;
}
count = ptr->channels[0] ;
WCcount++ ;
if( WCcount % 100 == 0 ) {
WCarray = (WCPTR *) realloc( WCarray , (WCcount + 100) *
sizeof( WCPTR ) ) ;
}
length = 0 ;
for( c = 1 ; c <= count ; c++ ) {
length += eArray[ ptr->channels[c] ].length ;
}
length /= count ;
WCarray[WCcount] = ptr ;
tinsert( &Qroot , -length , WCcount ) ;
index1 = eArray[ ptr->channels[1] ].index1 ;
index2 = eArray[ ptr->channels[1] ].index2 ;
rectArray[index2].ll = 1 ;
rectArray[index1].ul = 1 ;
index1 = eArray[ ptr->channels[count] ].index1 ;
index2 = eArray[ ptr->channels[count] ].index2 ;
rectArray[index2].lr = 1 ;
rectArray[index1].ur = 1 ;
}
}
for( i = 1 ; i <= numYnodes ; i++ ) {
for( ptr = yNodeArray[i] ; ptr != (WCPTR) NULL ; ptr = ptr->next ){
if( ptr->fixedWidth == 1 ) {
continue ;
}
count = ptr->channels[0] ;
WCcount++ ;
if( WCcount % 100 == 0 ) {
WCarray = (WCPTR *) realloc( WCarray , (WCcount + 100) *
sizeof( WCPTR ) ) ;
}
length = 0 ;
for( c = 1 ; c <= count ; c++ ) {
length += eArray[ ptr->channels[c] ].length ;
}
length /= count ;
WCarray[WCcount] = ptr ;
tinsert( &Qroot , -length , WCcount ) ;
index1 = eArray[ ptr->channels[1] ].index1 ;
index2 = eArray[ ptr->channels[1] ].index2 ;
rectArray[index2].ll = 1 ;
rectArray[index1].lr = 1 ;
index1 = eArray[ ptr->channels[count] ].index1 ;
index2 = eArray[ ptr->channels[count] ].index2 ;
rectArray[index2].ul = 1 ;
rectArray[index1].ur = 1 ;
}
}
for( ; ; ) {
tpop( &Qroot , &node , &length , &WCcount ) ;
if( node == (TNODEPTR) NULL ) {
break ;
}
ptr = WCarray[WCcount] ;
count = ptr->channels[0] ;
if( count == 1 ) {
continue ;
}
vertical = (ptr->channels[1] <= edgeTransition) ? 1 : 0 ;
c1 = 1 ;
c2 = 1 ;
do {
c2i1 = eArray[ ptr->channels[c2] ].index1 ;
if( rectArray[c2i1].ur == 0 ) {
c2++ ;
continue ;
}
guideline = (eArray[ ptr->channels[c2] ].rtside +
eArray[ ptr->channels[c1] ].lbside) / 2 ;
min = 10000000 ;
if( vertical ) {
ymin = 10000000 ;
ymax = 0 ;
for( c = c1 ; c <= c2 ; c++ ) {
i1 = eArray[ ptr->channels[c] ].index1 ;
i2 = eArray[ ptr->channels[c] ].index2 ;
if( ABS( rectArray[i1].xc - guideline) < min ) {
min = ABS( rectArray[i1].xc - guideline) ;
minc = c ;
}
if( ABS( rectArray[i2].xc - guideline) < min ) {
min = ABS( rectArray[i2].xc - guideline) ;
minc = c ;
}
}
} else {
xmin = 10000000 ;
xmax = 0 ;
for( c = c1 ; c <= c2 ; c++ ) {
i1 = eArray[ ptr->channels[c] ].index1 ;
i2 = eArray[ ptr->channels[c] ].index2 ;
if( ABS( rectArray[i1].yc - guideline) < min ) {
min = ABS( rectArray[i1].yc - guideline) ;
minc = c ;
}
if( ABS( rectArray[i2].yc - guideline) < min ) {
min = ABS( rectArray[i2].yc - guideline) ;
minc = c ;
}
}
}
for( c = c1 ; c <= c2 ; c++ ) {
i1 = eArray[ ptr->channels[c] ].index1 ;
i2 = eArray[ ptr->channels[c] ].index2 ;
if( c != minc ) {
eArray[ ptr->channels[c] ].notActive = 1 ;
} else {
eArray[ ptr->channels[c] ].rtside =
eArray[ ptr->channels[c2] ].rtside ;
eArray[ ptr->channels[c] ].lbside =
eArray[ ptr->channels[c1] ].lbside ;
}
if( c == c1 ) {
if( vertical == 1 ) {
rectArray[i1].ur = 1 ;
rectArray[i2].lr = 1 ;
} else {
rectArray[i1].ur = 1 ;
rectArray[i2].ul = 1 ;
}
}
if( c == c2 ) {
if( vertical == 1 ) {
rectArray[i1].ul = 1 ;
rectArray[i2].ll = 1 ;
} else {
rectArray[i1].lr = 1 ;
rectArray[i2].ll = 1 ;
}
}
if( c > c1 && c < c2 ) {
if( vertical == 1 ) {
rectArray[i1].ul = 1 ;
rectArray[i1].ur = 1 ;
rectArray[i2].ll = 1 ;
rectArray[i2].lr = 1 ;
} else {
rectArray[i1].ur = 1 ;
rectArray[i1].lr = 1 ;
rectArray[i2].ul = 1 ;
rectArray[i2].ll = 1 ;
}
}
}
c1 = ++c2 ;
} while( c2 <= count ) ;
}
for( i = 1 ; i <= numRects ; i++ ) {
rectArray[i].nedges = 0 ;
}
for( i = 1 ; i <= numXnodes ; i++ ) {
for( ptr = xNodeArray[i] ; ptr != (WCPTR) NULL ; ptr = ptr->next ){
if( ptr->fixedWidth == 1 ) {
continue ;
}
count = ptr->channels[0] ;
for( c = 1 ; c <= count ; c++ ) {
if( eArray[ ptr->channels[c] ].notActive == 1 ) {
continue ;
}
index1 = eArray[ ptr->channels[c] ].index1 ;
index2 = eArray[ ptr->channels[c] ].index2 ;
rectArray[index2].nedges++ ;
rectArray[index1].nedges++ ;
}
}
}
for( i = 1 ; i <= numYnodes ; i++ ) {
for( ptr = yNodeArray[i] ; ptr != (WCPTR) NULL ; ptr = ptr->next ){
if( ptr->fixedWidth == 1 ) {
continue ;
}
count = ptr->channels[0] ;
for( c = 1 ; c <= count ; c++ ) {
if( eArray[ ptr->channels[c] ].notActive == 1 ) {
continue ;
}
index1 = eArray[ ptr->channels[c] ].index1 ;
index2 = eArray[ ptr->channels[c] ].index2 ;
rectArray[index2].nedges++ ;
rectArray[index1].nedges++ ;
}
}
}
hit = 1 ;
while( hit ) {
hit = 0 ;
for( i = 1 ; i <= numXnodes ; i++ ) {
for( ptr = xNodeArray[i]; ptr != (WCPTR) NULL; ptr = ptr->next ){
if( ptr->fixedWidth == 1 ) {
continue ;
}
count = ptr->channels[0] ;
for( c = 1 ; c <= count ; c++ ) {
if( eArray[ ptr->channels[c] ].notActive == 1 ) {
continue ;
}
index1 = eArray[ ptr->channels[c] ].index1 ;
index2 = eArray[ ptr->channels[c] ].index2 ;
if( rectArray[index2].nedges == 1 ||
rectArray[index1].nedges == 1 ) {
eArray[ ptr->channels[c] ].notActive = 1 ;
rectArray[index2].nedges-- ;
rectArray[index1].nedges-- ;
hit = 1 ;
flag = 0 ;
for( k = 1 ; ; k++ ) {
if( c + k <= count ) {
if( eArray[ ptr->channels[c + k] ].
notActive == 0) {
flag = 1 ;
eArray[ptr->channels[c + k]].lbside -=
eArray[ ptr->channels[c] ].rtside -
eArray[ ptr->channels[c] ].lbside ;
}
}
if( flag ) {
break ;
}
if( c - k >= 1 ) {
if( eArray[ ptr->channels[c - k] ].
notActive == 0){
flag = 1 ;
eArray[ptr->channels[c - k]].rtside +=
eArray[ ptr->channels[c] ].rtside -
eArray[ ptr->channels[c] ].lbside ;
}
}
if( flag ) {
break ;
}
}
}
}
}
}
for( i = 1 ; i <= numYnodes ; i++ ) {
for( ptr = yNodeArray[i]; ptr != (WCPTR) NULL; ptr = ptr->next ){
if( ptr->fixedWidth == 1 ) {
continue ;
}
count = ptr->channels[0] ;
for( c = 1 ; c <= count ; c++ ) {
if( eArray[ ptr->channels[c] ].notActive == 1 ) {
continue ;
}
index1 = eArray[ ptr->channels[c] ].index1 ;
index2 = eArray[ ptr->channels[c] ].index2 ;
if( rectArray[index2].nedges == 1 ||
rectArray[index1].nedges == 1 ) {
eArray[ ptr->channels[c] ].notActive = 1 ;
rectArray[index2].nedges-- ;
rectArray[index1].nedges-- ;
hit = 1 ;
flag = 0 ;
for( k = 1 ; ; k++ ) {
if( c + k <= count ) {
if( eArray[ ptr->channels[c + k] ].
notActive == 0) {
flag = 1 ;
eArray[ptr->channels[c + k]].lbside -=
eArray[ ptr->channels[c] ].rtside -
eArray[ ptr->channels[c] ].lbside ;
}
}
if( flag ) {
break ;
}
if( c - k >= 1 ) {
if( eArray[ ptr->channels[c - k] ].
notActive == 0){
flag = 1 ;
eArray[ptr->channels[c - k]].rtside +=
eArray[ ptr->channels[c] ].rtside -
eArray[ ptr->channels[c] ].lbside ;
}
}
if( flag ) {
break ;
}
}
}
}
}
}
}
for( twoTimes = 1 ; twoTimes <= 2 ; twoTimes++ ) {
for( i = 1 ; i <= numXnodes ; i++ ) {
for( ptr = xNodeArray[i] ; ptr != (WCPTR) NULL ;
ptr = ptr->next ){
if( ptr->fixedWidth == 1 ) {
continue ;
}
count = ptr->channels[0] ;
if( count <= 1 ) {
continue ;
}
if( eArray[ ptr->channels[1] ].notActive == 1 ) {
i2 = eArray[ ptr->channels[1] ].index2 ;
i1 = eArray[ ptr->channels[1] ].index1 ;
edge = eArray[ ptr->channels[1] ].edge1 ;
start = edgeList[edge].start ;
end = edgeList[edge].end ;
ymax = rectArray[i2].yc ;
ymin = rectArray[i1].yc ;
for( c = 2 ; c <= count ; c++ ) {
if( eArray[ ptr->channels[c] ].notActive == 0 ) {
i1 = eArray[ ptr->channels[c] ].index1 ;
i2 = eArray[ ptr->channels[c] ].index2 ;
if( rectArray[i2].yc < ymax ) {
j = eArray[ ptr->channels[1] ].index2 ;
if( rectArray[j].t < end &&
rectArray[j].yreset == 0 ) {
rectArray[j].yc = rectArray[i2].yc ;
rectArray[j].yreset = 1 ;
} else if( rectArray[i2].yc < end ) {
rectArray[i2].yc = end ;
}
}
if( rectArray[i1].yc > ymin ) {
j = eArray[ ptr->channels[1] ].index1 ;
if( start < rectArray[j].b &&
rectArray[j].yreset == 0 ) {
rectArray[j].yc = rectArray[i1].yc ;
rectArray[j].yreset = 1 ;
} else if( start < rectArray[i1].yc ) {
rectArray[i1].yc = start ;
}
}
break ;
}
}
}
if( eArray[ ptr->channels[count] ].notActive == 1 ) {
i2 = eArray[ ptr->channels[count] ].index2 ;
i1 = eArray[ ptr->channels[count] ].index1 ;
edge = eArray[ ptr->channels[count] ].edge2 ;
start = edgeList[edge].start ;
end = edgeList[edge].end ;
ymax = rectArray[i2].yc ;
ymin = rectArray[i1].yc ;
for( c = count - 1 ; c >= 1 ; c-- ) {
if( eArray[ ptr->channels[c] ].notActive == 0 ) {
i1 = eArray[ ptr->channels[c] ].index1 ;
i2 = eArray[ ptr->channels[c] ].index2 ;
if( rectArray[i2].yc < ymax ) {
j = eArray[ ptr->channels[count] ].index2 ;
if( rectArray[j].t < end &&
rectArray[j].yreset == 0 ) {
rectArray[j].yc = rectArray[i2].yc ;
rectArray[j].yreset = 1 ;
} else if( rectArray[i2].yc < end ) {
rectArray[i2].yc = end ;
}
}
if( rectArray[i1].yc > ymin ) {
j = eArray[ ptr->channels[count] ].index1 ;
if( start < rectArray[j].b &&
rectArray[j].yreset == 0 ) {
rectArray[j].yc = rectArray[i1].yc ;
rectArray[j].yreset = 1 ;
} else if( start < rectArray[i1].yc ) {
rectArray[i1].yc = start ;
}
}
break ;
}
}
}
}
}
for( i = 1 ; i <= numYnodes ; i++ ) {
for( ptr = yNodeArray[i] ; ptr != (WCPTR) NULL ;
ptr = ptr->next ){
if( ptr->fixedWidth == 1 ) {
continue ;
}
count = ptr->channels[0] ;
if( count <= 1 ) {
continue ;
}
if( eArray[ ptr->channels[1] ].notActive == 1 ) {
i2 = eArray[ ptr->channels[1] ].index2 ;
i1 = eArray[ ptr->channels[1] ].index1 ;
edge = eArray[ ptr->channels[1] ].edge1 ;
start = edgeList[edge].start ;
end = edgeList[edge].end ;
xmax = rectArray[i2].xc ;
xmin = rectArray[i1].xc ;
for( c = 2 ; c <= count ; c++ ) {
if( eArray[ ptr->channels[c] ].notActive == 0 ) {
i1 = eArray[ ptr->channels[c] ].index1 ;
i2 = eArray[ ptr->channels[c] ].index2 ;
if( rectArray[i2].xc < xmax ) {
j = eArray[ ptr->channels[1] ].index2 ;
if( rectArray[j].r < end &&
rectArray[j].xreset == 0 ) {
rectArray[j].xc = rectArray[i2].xc ;
rectArray[j].xreset = 1 ;
} else if( rectArray[i2].xc < end ) {
rectArray[i2].xc = end ;
}
}
if( rectArray[i1].xc > xmin ) {
j = eArray[ ptr->channels[1] ].index1 ;
if( start < rectArray[j].l &&
rectArray[j].xreset == 0 ) {
rectArray[j].xc = rectArray[i1].xc ;
rectArray[j].xreset = 1 ;
} else if( start < rectArray[i1].xc ) {
rectArray[i1].xc = start ;
}
}
break ;
}
}
}
if( eArray[ ptr->channels[count] ].notActive == 1 ) {
i2 = eArray[ ptr->channels[count] ].index2 ;
i1 = eArray[ ptr->channels[count] ].index1 ;
edge = eArray[ ptr->channels[count] ].edge2 ;
start = edgeList[edge].start ;
end = edgeList[edge].end ;
xmax = rectArray[i2].xc ;
xmin = rectArray[i1].xc ;
for( c = count - 1 ; c >= 1 ; c-- ) {
if( eArray[ ptr->channels[c] ].notActive == 0 ) {
i1 = eArray[ ptr->channels[c] ].index1 ;
i2 = eArray[ ptr->channels[c] ].index2 ;
if( rectArray[i2].xc < xmax ) {
j = eArray[ ptr->channels[count] ].index2 ;
if( rectArray[j].r < end &&
rectArray[j].xreset == 0 ) {
rectArray[j].xc = rectArray[i2].xc ;
rectArray[j].xreset = 1 ;
} else if( rectArray[i2].xc < end ) {
rectArray[i2].xc = end ;
}
}
if( rectArray[i1].xc > xmin ) {
j = eArray[ ptr->channels[count] ].index1 ;
if( start < rectArray[j].l &&
rectArray[j].xreset == 0 ) {
rectArray[j].xc = rectArray[i1].xc ;
rectArray[j].xreset = 1 ;
} else if( start < rectArray[i1].xc ) {
rectArray[i1].xc = start ;
}
}
break ;
}
}
}
}
}
}
return ;
}