mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1048 lines
38 KiB
1048 lines
38 KiB
#ifndef LSTRIP
|
|
/**************************************************************************/
|
|
|
|
#include "hwr_sys.h"
|
|
#include "ams_mg.h"
|
|
#include "lowlevel.h"
|
|
#include "calcmacr.h"
|
|
#include "low_dbg.h"
|
|
#include "def.h"
|
|
|
|
#ifdef FORMULA
|
|
#include "frm_con.h"
|
|
|
|
#ifdef FRM_WINDOWS
|
|
#include "edit.h"
|
|
#undef PG_DEBUG
|
|
#define PG_DEBUG (FRM_DEBUG && !FOR_EDIT)
|
|
#endif
|
|
|
|
#endif /*FORMULA*/
|
|
|
|
#if PG_DEBUG
|
|
#include "pg_debug.h"
|
|
#endif
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
extern const CONSTS const1 ;
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
typedef struct
|
|
{
|
|
_SHORT iBeg ;
|
|
_SHORT iEnd ;
|
|
_SHORT eps ;
|
|
_SHORT wX ;
|
|
_SHORT wY ;
|
|
_SHORT wXY ;
|
|
_UCHAR MaxName ;
|
|
_UCHAR MinName ;
|
|
}
|
|
_ENVIRONS ;
|
|
|
|
typedef _ENVIRONS _PTR p_ENV ;
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
_SHORT BigExtr( low_type _PTR low_data, _SHORT begin, _SHORT end,
|
|
_SHORT extr_axis , _SHORT eps_fy ) ;
|
|
|
|
void RedrawExtr( p_LowData low_data, p_SPECL pTmp , _UCHAR mark ) ;
|
|
|
|
_SHORT DirectExtr( low_type _PTR pLowData , p_ENV pEnvExtr ,
|
|
SPECL _PTR pTmpSpecl , _SHORT k ) ;
|
|
|
|
_SHORT ArcsKern ( p_LowData low_data, _SHORT ibeg, _SHORT iend ) ;
|
|
|
|
p_SPECL LastElemAnyKindFor ( p_SPECL pSpecl , _UCHAR kind_of_mark ) ;
|
|
|
|
p_SPECL FirstElemAnyKindFor ( p_SPECL pSpecl , _UCHAR kind_of_mark ) ;
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
|
|
_SHORT InitSpecl( low_type _PTR pLowData , _SHORT n )
|
|
{
|
|
p_SPECL pSpecl = pLowData->specl ;
|
|
_SHORT flag_init ;
|
|
|
|
flag_init = SUCCESS ;
|
|
|
|
HWRMemSet( (p_VOID)pSpecl , 0 , sizeof(SPECL)*n ) ;
|
|
HWRMemSet( (p_VOID)pLowData->pAbsnum, 0 ,
|
|
sizeof(_SHORT)*(pLowData->rmAbsnum) ) ;
|
|
|
|
pLowData->len_specl = 1 ;
|
|
pLowData->lenabs = 0 ;
|
|
pSpecl->prev = _NULL ;
|
|
pSpecl->next = pSpecl + 1 ;
|
|
pSpecl->mark = EMPTY ;
|
|
pSpecl->ipoint0 = UNDEF ;
|
|
pSpecl->ipoint1 = UNDEF ;
|
|
pLowData->LastSpeclIndex = 0 ;
|
|
|
|
return( flag_init) ;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
_SHORT InitSpeclElement( SPECL _PTR pSpecl )
|
|
{
|
|
_SHORT flag_Init ;
|
|
|
|
flag_Init = SUCCESS ;
|
|
|
|
if ( pSpecl != _NULL )
|
|
{
|
|
HWRMemSet( (p_VOID)pSpecl , 0 , sizeof(SPECL) ) ;
|
|
pSpecl->prev = _NULL ;
|
|
pSpecl->next = _NULL ;
|
|
pSpecl->mark = EMPTY ;
|
|
pSpecl->ipoint0 = UNDEF ;
|
|
pSpecl->ipoint1 = UNDEF ;
|
|
}
|
|
else
|
|
{
|
|
flag_Init = UNSUCCESS ;
|
|
err_msg ( " InitSpeclElement : Try to init emty SPECL element ..." ) ;
|
|
}
|
|
|
|
return( flag_Init) ;
|
|
}
|
|
/**************************************************************************/
|
|
|
|
#define LIM_RED_EPS_Y 1
|
|
#define MIN_RED_EPS_Y 2
|
|
|
|
_SHORT Extr( low_type _PTR pLowData , _SHORT eps_fy , _SHORT eps_fx ,
|
|
_SHORT eps_fxy , _SHORT eps_fyx ,
|
|
_SHORT nMaxReduct , _SHORT extr_axis )
|
|
{
|
|
p_POINTS_GROUP pGroupsBorder = pLowData->pGroupsBorder ;
|
|
_INT lenGrBord = pLowData->lenGrBord ;
|
|
p_SHORT pAbsnum = pLowData->pAbsnum ;
|
|
_INT lenAbs = pLowData->lenabs ;
|
|
p_SPECL pSpecl = pLowData->specl ;
|
|
_INT old_lenSpecl = pLowData->len_specl ;
|
|
|
|
p_SPECL tmpSpecl ;
|
|
_INT il , im ;
|
|
_INT stAbsnum ;
|
|
_INT iBeg, iEnd ;
|
|
|
|
_BOOL fl0 ;
|
|
|
|
if ( lenGrBord <= 0 )
|
|
{
|
|
err_msg( " Extr : GroupsBorder EMPTY ! " ) ;
|
|
il = 0 ;
|
|
goto ERR ;
|
|
}
|
|
|
|
for ( il = 0 , stAbsnum = 0 ; il < lenGrBord ; il++ )
|
|
{
|
|
iBeg = ( pGroupsBorder + il )->iBeg ;
|
|
iEnd = ( pGroupsBorder + il )->iEnd ;
|
|
fl0 = _TRUE ;
|
|
|
|
for ( im = stAbsnum ; im < lenAbs ; im++ )
|
|
{
|
|
tmpSpecl = pSpecl + *(pAbsnum + im) ;
|
|
|
|
if ( ( iBeg == tmpSpecl->ibeg ) &&
|
|
( iEnd == tmpSpecl->iend ) )
|
|
{
|
|
stAbsnum = im ;
|
|
fl0 = _FALSE ; break ;
|
|
}
|
|
}
|
|
|
|
if ( fl0 == _FALSE )
|
|
continue ;
|
|
|
|
if ( Mark( pLowData , BEG , 0, 0, 0,
|
|
(_SHORT)iBeg , (_SHORT)iBeg, (_SHORT)iBeg, (_SHORT)iBeg ) == UNSUCCESS )
|
|
goto ERR ;
|
|
|
|
if ( extr_axis & Y_DIR )
|
|
{
|
|
_INT epsred ;
|
|
_INT nReduct = 0 ;
|
|
|
|
p_SHORT pLenSpecl = &(pLowData->len_specl) ;
|
|
_INT old_lenSpeclLocal = *pLenSpecl ;
|
|
|
|
while ( ( old_lenSpeclLocal == *pLenSpecl )
|
|
&& ( nReduct <= nMaxReduct ) )
|
|
{
|
|
nReduct++ ;
|
|
epsred = eps_fy / nReduct ;
|
|
|
|
if ( epsred <= LIM_RED_EPS_Y )
|
|
{
|
|
epsred = MIN_RED_EPS_Y ;
|
|
nReduct = nMaxReduct + 1 ;
|
|
}
|
|
|
|
if ( BigExtr( pLowData, (_SHORT)iBeg, (_SHORT)iEnd,
|
|
Y_DIR, (_SHORT)epsred )
|
|
== UNSUCCESS )
|
|
goto ERR ;
|
|
}
|
|
}
|
|
|
|
if ( extr_axis & X_DIR )
|
|
{
|
|
if ( BigExtr( pLowData, (_SHORT)iBeg, (_SHORT)iEnd,
|
|
X_DIR, eps_fx ) == UNSUCCESS )
|
|
goto ERR ;
|
|
}
|
|
|
|
if ( extr_axis & XY_DIR )
|
|
{
|
|
if ( BigExtr( pLowData, (_SHORT)iBeg, (_SHORT)iEnd,
|
|
XY_DIR , eps_fxy ) == UNSUCCESS )
|
|
goto ERR ;
|
|
}
|
|
|
|
if ( extr_axis & ( XY_DIR | YX_DIR ) )
|
|
{
|
|
if ( BigExtr( pLowData, (_SHORT)iBeg, (_SHORT)iEnd,
|
|
YX_DIR , eps_fyx ) == UNSUCCESS )
|
|
goto ERR ;
|
|
}
|
|
|
|
if ( Mark( pLowData, END , 0, 0 , 0,
|
|
(_SHORT)iEnd , (_SHORT)iEnd , (_SHORT)iEnd , (_SHORT)iEnd ) == UNSUCCESS )
|
|
goto ERR ;
|
|
}
|
|
|
|
// QUIT:
|
|
return SUCCESS ;
|
|
|
|
ERR :
|
|
|
|
pLowData->iBegBlankGroups = (_SHORT)il ;
|
|
pLowData->len_specl = (_SHORT)old_lenSpecl ;
|
|
err_msg( " Extr : SPECL overflow , part of LowLevel info lost ..." ) ;
|
|
|
|
return UNSUCCESS ;
|
|
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
#define WX0 2 /* Weights corresponding */
|
|
/* by two directions of YX */
|
|
#define WX1 1 /* scanning . */
|
|
|
|
/* This "define" in the same time the meaning of the next "define" */
|
|
|
|
#define Z(i) ( wx * x[i] + wy * y[i] ) / wxy
|
|
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
|
|
/* That "define" is the way of calculation of the previous "define" */
|
|
/* when wx and wy are either 0 or +-1 : */
|
|
|
|
#define V(i) ( ( ((wx==0)? 0:((wx>0)? x[(i)]:(-x[(i)]))) \
|
|
+ ((wy==0)? 0:((wy>0)? y[(i)]:(-y[(i)]))) ) / wxy \
|
|
)
|
|
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
|
|
_SHORT BigExtr( low_type _PTR pLowData , _SHORT iBeg , _SHORT iEnd ,
|
|
_SHORT extr_axis , _SHORT eps )
|
|
{
|
|
p_SPECL pSpecl = pLowData->specl ;
|
|
p_SPECL maxTmp , minTmp , pLastElement ;
|
|
SPECL tmpSpecl ;
|
|
|
|
_SHORT flagExtr = SUCCESS ;
|
|
_INT k ;
|
|
|
|
_ENVIRONS envExtr ;
|
|
p_ENV pEnvExtr = &envExtr ;
|
|
|
|
|
|
envExtr.iBeg = iBeg ;
|
|
envExtr.iEnd = iEnd ;
|
|
envExtr.eps = eps ;
|
|
|
|
|
|
if ( extr_axis == Y_DIR )
|
|
{
|
|
envExtr.MaxName = MAXW ; envExtr.wX = 0 ;
|
|
envExtr.MinName = MINW ; envExtr.wY = 1 ;
|
|
}
|
|
else if ( extr_axis == X_DIR )
|
|
{
|
|
envExtr.MaxName = _MAXX ; envExtr.wX = 1 ;
|
|
envExtr.MinName = _MINX ; envExtr.wY = 0 ;
|
|
}
|
|
else if ( extr_axis == XY_DIR )
|
|
{
|
|
envExtr.MaxName = MAXXY ; envExtr.wX = 1 ;
|
|
envExtr.MinName = MINXY ; envExtr.wY = 1 ;
|
|
}
|
|
|
|
else if ( extr_axis != YX_DIR )
|
|
{
|
|
err_msg( " BigExtr : Illegal extremum flag ... " ) ;
|
|
flagExtr = UNSUCCESS ;
|
|
goto QUIT ;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
/* Search for big extremums */
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
if ( extr_axis != YX_DIR )
|
|
{
|
|
p_SHORT x = pLowData->x ;
|
|
p_SHORT y = pLowData->y ;
|
|
_INT epsLocal = pEnvExtr->eps ;
|
|
_INT wx = pEnvExtr->wX ;
|
|
_INT wy = pEnvExtr->wY ;
|
|
_INT wxy ;
|
|
_UCHAR MaxName = pEnvExtr->MaxName ;
|
|
_UCHAR MinName = pEnvExtr->MinName ;
|
|
|
|
SPECL _PTR pTmpSpecl = &tmpSpecl ;
|
|
_UCHAR prevMark = EMPTY ;
|
|
|
|
_INT extV , maxV , minV ;
|
|
_INT iOpen , iClose ;
|
|
_INT jMax , jMin ;
|
|
_INT j ;
|
|
|
|
|
|
envExtr.wXY = HWRAbs( envExtr.wX ) + HWRAbs( envExtr.wY ) ;
|
|
|
|
if ( envExtr.wXY == 0 )
|
|
{
|
|
err_msg( " BigExtr : Wrong XY-weights ... " ) ;
|
|
flagExtr = UNSUCCESS ;
|
|
goto QUIT ;
|
|
}
|
|
|
|
InitSpeclElement( pTmpSpecl ) ;
|
|
wxy = pEnvExtr->wXY ;
|
|
prevMark = ( pLowData->specl + pLowData->len_specl - 1 )->mark ;
|
|
|
|
for ( k = iBeg ; k <= iEnd ; k++ )
|
|
{
|
|
/*---------------------------------------------------------------------*/
|
|
/* Preliminary search of extremums */
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
if ( ( ( V(k) >= V(k+1) ) && ( V(k) >= V(k-1) ) )
|
|
|| ( ( V(k) <= V(k+1) ) && ( V(k) <= V(k-1) ) )
|
|
|| ( k == iBeg ) || ( k == iEnd ) )
|
|
{
|
|
extV = V(k) ;
|
|
|
|
j = k ;
|
|
while ( (HWRAbs(extV - V(j)) < epsLocal) && (j >= iBeg) ) j-- ;
|
|
iOpen = j+1 ;
|
|
|
|
j = k ;
|
|
while ( (HWRAbs(extV - V(j)) < epsLocal) && (j <= iEnd) ) j++ ;
|
|
iClose = j-1 ;
|
|
}
|
|
else
|
|
{
|
|
continue ;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
/* Search for maximums */
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
if ( ( ( ( iOpen != iBeg )
|
|
&& ( V(iOpen-1) < extV )
|
|
&& ( ( V(iClose+1) < extV ) || (iClose == iEnd) ) )
|
|
||
|
|
( ( iClose != iEnd)
|
|
&& ( V(iClose+1) < extV )
|
|
&& ( ( V(iOpen-1) < extV ) || (iOpen == iBeg) ) ) )
|
|
&&
|
|
( prevMark != MaxName ) )
|
|
{
|
|
maxV = extV ; jMax = k ;
|
|
for ( j = iOpen ; j <= iClose ; j++ )
|
|
{
|
|
if ( V(j) > maxV )
|
|
{ jMax = j ; maxV = V(j) ; }
|
|
}
|
|
|
|
for ( j = jMax ;
|
|
V(j) == maxV && j <= iEnd ;
|
|
j++ ) ;
|
|
jMax = MEAN_OF( jMax , (j-1) ) ;
|
|
|
|
if ( jMax != k )
|
|
{
|
|
j = jMax ;
|
|
while ( ( maxV-V(j) < epsLocal ) && (j >= iBeg) ) j-- ;
|
|
iOpen = j+1 ;
|
|
|
|
j = jMax ;
|
|
while ( ( maxV-V(j) < epsLocal ) && (j <= iEnd) ) j++ ;
|
|
iClose = j-1 ;
|
|
}
|
|
|
|
InitSpeclElement( pTmpSpecl ) ;
|
|
pTmpSpecl->ibeg = (_SHORT)iOpen ;
|
|
pTmpSpecl->iend = (_SHORT)iClose ;
|
|
pTmpSpecl->ipoint0 = (_SHORT)jMax ;
|
|
pTmpSpecl->ipoint1 = UNDEF ;
|
|
pTmpSpecl->mark = MaxName ;
|
|
prevMark = MaxName ;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
/* Search for minimums */
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
else if
|
|
( ( ( ( iOpen != iBeg )
|
|
&& ( V(iOpen-1) > extV )
|
|
&& ( ( V(iClose+1) > extV ) || (iClose == iEnd) ) )
|
|
||
|
|
( ( iClose != iEnd)
|
|
&& ( V(iClose+1) > extV )
|
|
&& ( ( V(iOpen-1) > extV ) || (iOpen == iBeg) ) ) )
|
|
&&
|
|
( prevMark != MinName ) )
|
|
{
|
|
minV = extV ; jMin = k ;
|
|
for ( j = iOpen ; j <= iClose ; j++ )
|
|
{
|
|
if ( V(j) < minV )
|
|
{ jMin = j ; minV = V(j) ; }
|
|
}
|
|
|
|
for ( j = jMin ;
|
|
V(j) == minV && j <= iEnd ;
|
|
j++ ) ;
|
|
jMin = MEAN_OF( jMin , (j-1) ) ;
|
|
|
|
if ( jMin != k )
|
|
{
|
|
j = jMin ;
|
|
while ( ( V(j)-minV < epsLocal ) && (j <= iEnd) ) j++ ;
|
|
iClose = j-1 ;
|
|
|
|
j = jMin ;
|
|
while ( ( V(j)-minV < epsLocal ) && (j >= iBeg) ) j-- ;
|
|
iOpen = j+1 ;
|
|
}
|
|
|
|
InitSpeclElement( pTmpSpecl ) ;
|
|
pTmpSpecl->ibeg = (_SHORT)iOpen ;
|
|
pTmpSpecl->iend = (_SHORT)iClose ;
|
|
pTmpSpecl->ipoint0 = (_SHORT)jMin ;
|
|
pTmpSpecl->ipoint1 = UNDEF ;
|
|
pTmpSpecl->mark = MinName ;
|
|
prevMark = MinName ;
|
|
}
|
|
|
|
|
|
if ( tmpSpecl.mark != EMPTY )
|
|
{
|
|
if ( MarkSpecl( pLowData, &tmpSpecl )
|
|
== UNSUCCESS )
|
|
{ flagExtr = UNSUCCESS ; goto QUIT ; }
|
|
|
|
k = tmpSpecl.iend ;
|
|
InitSpeclElement( pTmpSpecl ) ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
envExtr.MaxName = MAXYX ;
|
|
envExtr.MinName = MINYX ; envExtr.wY = -1 ;
|
|
|
|
for ( k = iBeg ; k <= iEnd ; k++ )
|
|
{
|
|
envExtr.wX = WX1 ;
|
|
envExtr.wXY = HWRAbs( envExtr.wX ) + HWRAbs( envExtr.wY );
|
|
|
|
DirectExtr( pLowData , pEnvExtr , &tmpSpecl , (_SHORT)k ) ;
|
|
|
|
if ( tmpSpecl.mark == EMPTY )
|
|
{
|
|
envExtr.wX = WX0 ;
|
|
envExtr.wXY = HWRAbs( envExtr.wX ) +
|
|
HWRAbs( envExtr.wY ) ;
|
|
DirectExtr( pLowData, pEnvExtr, &tmpSpecl, (_SHORT)k ) ;
|
|
}
|
|
|
|
if ( ( tmpSpecl.mark != EMPTY )
|
|
&&
|
|
( tmpSpecl.iend >= k ) )
|
|
{
|
|
if ( MarkSpecl( pLowData, &tmpSpecl )
|
|
== UNSUCCESS )
|
|
{ flagExtr = UNSUCCESS ; goto QUIT ; }
|
|
|
|
if ( tmpSpecl.iend >= k )
|
|
k = tmpSpecl.iend ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
/* Increasing extremums borders */
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
pLastElement = pSpecl + pLowData->len_specl - 1 ;
|
|
|
|
maxTmp = LastElemAnyKindFor( pLastElement , envExtr.MaxName ) ;
|
|
minTmp = LastElemAnyKindFor( pLastElement , envExtr.MinName ) ;
|
|
|
|
if ( ( maxTmp != _NULL && maxTmp->iend < iEnd ) &&
|
|
( minTmp != _NULL && minTmp->iend < iEnd ) )
|
|
{
|
|
if ( maxTmp->iend > minTmp->iend )
|
|
{
|
|
maxTmp->iend = (_SHORT)iEnd ;
|
|
#if PG_DEBUG
|
|
RedrawExtr( pLowData , maxTmp , envExtr.MaxName ) ;
|
|
#endif
|
|
}
|
|
|
|
else
|
|
{
|
|
minTmp->iend = (_SHORT)iEnd ;
|
|
#if PG_DEBUG
|
|
RedrawExtr( pLowData , minTmp , envExtr.MinName ) ;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
maxTmp = FirstElemAnyKindFor( pLastElement , envExtr.MaxName ) ;
|
|
minTmp = FirstElemAnyKindFor( pLastElement , envExtr.MinName ) ;
|
|
|
|
if ( ( maxTmp != _NULL && maxTmp->ibeg > iBeg ) &&
|
|
( minTmp != _NULL && minTmp->ibeg > iBeg ) )
|
|
{
|
|
if ( maxTmp->ibeg < minTmp->ibeg )
|
|
{
|
|
maxTmp->ibeg = (_SHORT)iBeg ;
|
|
#if PG_DEBUG
|
|
RedrawExtr( pLowData , maxTmp , envExtr.MaxName ) ;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
minTmp->ibeg = (_SHORT)iBeg ;
|
|
#if PG_DEBUG
|
|
RedrawExtr( pLowData , minTmp , envExtr.MinName ) ;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
QUIT: return( flagExtr ) ;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
_SHORT DirectExtr( low_type _PTR pLowData , p_ENV pEnvExtr ,
|
|
SPECL _PTR pTmpSpecl, _SHORT k )
|
|
{
|
|
p_SHORT x = pLowData->x ;
|
|
p_SHORT y = pLowData->y ;
|
|
|
|
_INT iBeg = pEnvExtr->iBeg ;
|
|
_INT iEnd = pEnvExtr->iEnd ;
|
|
_INT eps = pEnvExtr->eps ;
|
|
_INT wx = pEnvExtr->wX ;
|
|
_INT wy = pEnvExtr->wY ;
|
|
_INT wxy = pEnvExtr->wXY ;
|
|
_UCHAR MaxName = pEnvExtr->MaxName ;
|
|
_UCHAR MinName = pEnvExtr->MinName ;
|
|
|
|
_UCHAR prevMark ;
|
|
_SHORT flagDirExtr = SUCCESS ;
|
|
|
|
_INT extZ , maxZ , minZ ;
|
|
_INT iOpen , iClose ;
|
|
_INT jMax , jMin ;
|
|
_INT j ;
|
|
|
|
|
|
prevMark = ( pLowData->specl + pLowData->len_specl - 1 )->mark ;
|
|
InitSpeclElement( pTmpSpecl ) ;
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
/* Preliminary search of extremums */
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
if ( ( ( Z(k) >= Z(k+1) ) && ( Z(k) >= Z(k-1) ) )
|
|
|| ( ( Z(k) <= Z(k+1) ) && ( Z(k) <= Z(k-1) ) )
|
|
|| ( k == iBeg ) || ( k == iEnd ) )
|
|
{
|
|
extZ = Z(k) ;
|
|
|
|
j = k ;
|
|
while ( (HWRAbs(extZ - Z(j)) < eps) && (j >= iBeg) ) j-- ;
|
|
iOpen = j+1 ;
|
|
|
|
j = k ;
|
|
while ( (HWRAbs(extZ - Z(j)) < eps) && (j <= iEnd) ) j++ ;
|
|
iClose = j-1 ;
|
|
}
|
|
else
|
|
{
|
|
goto QUIT ;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
/* Search for maximums */
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
if ( ( ( ( iOpen != iBeg )
|
|
&& ( Z(iOpen-1) < extZ )
|
|
&& ( ( Z(iClose+1) < extZ ) || (iClose == iEnd) ) )
|
|
||
|
|
( ( iClose != iEnd)
|
|
&& ( Z(iClose+1) < extZ )
|
|
&& ( ( Z(iOpen-1) < extZ ) || (iOpen == iBeg) ) ) )
|
|
&&
|
|
( prevMark != MaxName ) )
|
|
{
|
|
maxZ = extZ ; jMax = k ;
|
|
for ( j = iOpen ; j <= iClose ; j++ )
|
|
{
|
|
if ( Z(j) > maxZ )
|
|
{ jMax = j ; maxZ = Z(j) ; }
|
|
}
|
|
|
|
for ( j = jMax ; Z(j) == maxZ && j <= iEnd ; j++ ) ;
|
|
jMax = MEAN_OF( jMax , (j-1) ) ;
|
|
|
|
if ( jMax != k )
|
|
{
|
|
j = jMax ;
|
|
while ( ( maxZ-Z(j) < eps ) && (j >= iBeg) ) j-- ;
|
|
iOpen = j+1 ;
|
|
|
|
j = jMax ;
|
|
while ( ( maxZ-Z(j) < eps ) && (j <= iEnd) ) j++ ;
|
|
iClose = j-1 ;
|
|
}
|
|
|
|
pTmpSpecl->ibeg = (_SHORT)iOpen ;
|
|
pTmpSpecl->iend = (_SHORT)iClose ;
|
|
pTmpSpecl->ipoint0 = (_SHORT)jMax ;
|
|
pTmpSpecl->ipoint1 = UNDEF ;
|
|
pTmpSpecl->mark = MaxName ;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
/* Search for minimums */
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
else
|
|
if ( ( ( ( iOpen != iBeg )
|
|
&& ( Z(iOpen-1) > extZ )
|
|
&& ( ( Z(iClose+1) > extZ ) || (iClose == iEnd) ) )
|
|
||
|
|
( ( iClose != iEnd)
|
|
&& ( Z(iClose+1) > extZ )
|
|
&& ( ( Z(iOpen-1) > extZ ) || (iOpen == iBeg) ) ) )
|
|
&&
|
|
( prevMark != MinName ) )
|
|
{
|
|
minZ = extZ ; jMin = k ;
|
|
for ( j = iOpen ; j <= iClose ; j++ )
|
|
{
|
|
if ( Z(j) < minZ )
|
|
{ jMin = j ; minZ = Z(j) ; }
|
|
}
|
|
|
|
for ( j = jMin ; Z(j) == minZ && j <= iEnd ; j++ ) ;
|
|
jMin = MEAN_OF( jMin , (j-1) ) ;
|
|
|
|
if ( jMin != k )
|
|
{
|
|
j = jMin ;
|
|
while ( ( Z(j)-minZ < eps ) && (j <= iEnd) ) j++ ;
|
|
iClose = j-1 ;
|
|
|
|
j = jMin ;
|
|
while ( ( Z(j)-minZ < eps ) && (j >= iBeg) ) j-- ;
|
|
iOpen = j+1 ;
|
|
}
|
|
|
|
pTmpSpecl->ibeg = (_SHORT)iOpen ;
|
|
pTmpSpecl->iend = (_SHORT)iClose ;
|
|
pTmpSpecl->ipoint0 = (_SHORT)jMin ;
|
|
pTmpSpecl->ipoint1 = UNDEF ;
|
|
pTmpSpecl->mark = MinName ;
|
|
}
|
|
|
|
|
|
QUIT: return( flagDirExtr ) ;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
#if PG_DEBUG
|
|
void RedrawExtr( p_LowData low_data, p_SPECL pTmp , _UCHAR mark )
|
|
{
|
|
p_SHORT x = low_data->x ;
|
|
p_SHORT y = low_data->y ;
|
|
|
|
if (mpr > 0)
|
|
{
|
|
_SHORT color ;
|
|
|
|
switch( mark )
|
|
{
|
|
case MINW : color = COLORMIN ; break ;
|
|
case MAXW : color = COLORMAX ; break ;
|
|
case _MINX : color = COLORT ; break ;
|
|
case _MAXX : color = COLORMAXN ; break ;
|
|
case MINXY : color = COLORMIN ; break ;
|
|
case MAXXY : color = COLORMAX ; break ;
|
|
case MINYX : color = COLORT ; break ;
|
|
case MAXYX : color = COLORMAXN ; break ;
|
|
}
|
|
draw_arc( color, x,y, pTmp->ibeg, pTmp->iend );
|
|
}
|
|
return ;
|
|
}
|
|
#endif
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
p_SPECL LastElemAnyKindFor ( p_SPECL pSpecl , _UCHAR kind_of_mark )
|
|
{
|
|
DBG_CHK_err_msg( pSpecl == _NULL, "LastAnyK: BAD pSpecl");
|
|
|
|
for ( ;
|
|
pSpecl!=_NULL ;
|
|
pSpecl=pSpecl->prev )
|
|
{
|
|
if ( pSpecl->mark == BEG )
|
|
{
|
|
pSpecl = _NULL;
|
|
break;
|
|
}
|
|
if ( pSpecl->mark == kind_of_mark )
|
|
break;
|
|
}
|
|
|
|
return ( pSpecl ) ;
|
|
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
p_SPECL FirstElemAnyKindFor ( p_SPECL pSpecl , _UCHAR kind_of_mark )
|
|
{
|
|
p_SPECL pTmp , pFirst ;
|
|
|
|
DBG_CHK_err_msg( pSpecl == _NULL, "1stAnyK: BAD pSpecl");
|
|
|
|
pTmp = pSpecl ; pFirst = _NULL ;
|
|
while ( pTmp->mark != BEG )
|
|
{
|
|
if ( pTmp->mark == kind_of_mark )
|
|
{ pFirst = pTmp ; }
|
|
|
|
pTmp = pTmp->prev ;
|
|
}
|
|
|
|
return ( pFirst ) ;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
_SHORT Mark( low_type _PTR pLowData,
|
|
_UCHAR mark , _UCHAR code, _UCHAR attr , _UCHAR other,
|
|
_SHORT begin , _SHORT end , _SHORT ipoint0, _SHORT ipoint1 )
|
|
{
|
|
_SHORT _PTR pLspecl = &(pLowData->len_specl) ;
|
|
_SHORT _PTR pLenAbs = &(pLowData->lenabs) ;
|
|
p_SPECL pSpecl = pLowData->specl ;
|
|
_INT iMarked = *pLspecl ;
|
|
p_SPECL pMrkSpecl = pSpecl + iMarked ;
|
|
SPECL tmpSpecl ;
|
|
|
|
|
|
tmpSpecl.mark = mark ;
|
|
tmpSpecl.code = code ;
|
|
tmpSpecl.attr = attr ;
|
|
tmpSpecl.other = other ;
|
|
tmpSpecl.ibeg = begin ;
|
|
tmpSpecl.iend = end ;
|
|
tmpSpecl.ipoint0 = ipoint0 ;
|
|
tmpSpecl.ipoint1 = ipoint1 ;
|
|
|
|
if ( NoteSpecl( pLowData , &tmpSpecl ,
|
|
( SPECL _PTR ) pSpecl ,
|
|
pLspecl , SPECVAL ) == _FALSE )
|
|
goto RET_UNSUCC ;
|
|
|
|
pMrkSpecl->prev = pSpecl + pLowData->LastSpeclIndex ;
|
|
pMrkSpecl->next = (p_SPECL) _NULL ;
|
|
( pSpecl+pLowData->LastSpeclIndex )->next = pMrkSpecl ;
|
|
pLowData->LastSpeclIndex = (_SHORT)iMarked ;
|
|
|
|
switch( mark )
|
|
{
|
|
case DOT :
|
|
case STROKE :
|
|
case SHELF :
|
|
|
|
if ( (*pLenAbs) < ( pLowData->rmAbsnum - 1 ) )
|
|
{
|
|
*( pLowData->pAbsnum + *pLenAbs ) = (_SHORT)iMarked ;
|
|
(*pLenAbs)++ ;
|
|
}
|
|
else
|
|
{
|
|
err_msg( "Absnum is full , nowhere to write..." ) ;
|
|
goto RET_UNSUCC;
|
|
}
|
|
|
|
default : break ;
|
|
}
|
|
|
|
return SUCCESS ;
|
|
|
|
RET_UNSUCC:
|
|
return UNSUCCESS ;
|
|
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
_SHORT MarkSpecl( low_type _PTR pLowData, SPECL _PTR p_tmpSpecl )
|
|
{
|
|
_SHORT _PTR pLspecl = &(pLowData->len_specl) ;
|
|
_SHORT _PTR pLenAbs = &(pLowData->lenabs) ;
|
|
_SHORT iMarked = *pLspecl ;
|
|
p_SPECL pSpecl = pLowData->specl ;
|
|
p_SPECL pMrkSpecl = pSpecl + iMarked ;
|
|
|
|
|
|
if ( NoteSpecl( pLowData , p_tmpSpecl ,
|
|
( SPECL _PTR ) pSpecl ,
|
|
pLspecl , SPECVAL ) == _FALSE )
|
|
goto RET_UNSUCC ;
|
|
|
|
pMrkSpecl->prev = pSpecl + pLowData->LastSpeclIndex ;
|
|
pMrkSpecl->next = (p_SPECL) _NULL ;
|
|
(pSpecl+pLowData->LastSpeclIndex)->next = pMrkSpecl ;
|
|
pLowData->LastSpeclIndex = (_SHORT)iMarked ;
|
|
|
|
switch( p_tmpSpecl->mark )
|
|
{
|
|
case DOT :
|
|
case STROKE :
|
|
case SHELF :
|
|
|
|
if ( (*pLenAbs) < ( pLowData->rmAbsnum - 1 ) )
|
|
{
|
|
*( pLowData->pAbsnum + *pLenAbs ) = (_SHORT)iMarked ;
|
|
(*pLenAbs)++ ;
|
|
}
|
|
else
|
|
{
|
|
err_msg( "Absnum is full , nowhere to write..." ) ;
|
|
goto RET_UNSUCC;
|
|
}
|
|
|
|
default : break ;
|
|
}
|
|
|
|
return SUCCESS ;
|
|
|
|
RET_UNSUCC:
|
|
return UNSUCCESS ;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
_BOOL NoteSpecl( low_type _PTR pLowData , SPECL _PTR pTmpSpecl ,
|
|
SPECL _PTR pSpecl , _SHORT _PTR pLspecl ,
|
|
_SHORT limSpecl )
|
|
{
|
|
p_SHORT ind_Back = pLowData->buffers[2].ptr ;
|
|
SPECL _PTR pNew = ( SPECL _PTR ) (pSpecl + *pLspecl ) ;
|
|
_UCHAR mark = pTmpSpecl->mark ;
|
|
_INT iPoint0 = pTmpSpecl->ipoint0 ;
|
|
_INT iPoint1 = pTmpSpecl->ipoint1 ;
|
|
_BOOL flagNote = _TRUE ;
|
|
|
|
if ( *pLspecl < limSpecl-1 )
|
|
{
|
|
pNew->mark = mark ;
|
|
pNew->code = pTmpSpecl->code ;
|
|
pNew->attr = pTmpSpecl->attr ;
|
|
pNew->other = pTmpSpecl->other ;
|
|
|
|
if ( ( mark == SHELF ) ||
|
|
( mark == DOT ) ||
|
|
( mark == STROKE ) )
|
|
{
|
|
pNew->ibeg = ind_Back[pTmpSpecl->ibeg] ;
|
|
pNew->iend = ind_Back[pTmpSpecl->iend] ;
|
|
|
|
if ( iPoint0 != UNDEF )
|
|
pNew->ipoint0 = ind_Back[iPoint0] ;
|
|
else
|
|
pNew->ipoint0 = (_SHORT)iPoint0 ;
|
|
|
|
if ( iPoint1 != UNDEF )
|
|
pNew->ipoint1 = ind_Back[iPoint1] ;
|
|
else
|
|
pNew->ipoint1 = (_SHORT)iPoint1 ;
|
|
}
|
|
else
|
|
{
|
|
pNew->ibeg = pTmpSpecl->ibeg ;
|
|
pNew->iend = pTmpSpecl->iend ;
|
|
pNew->ipoint0 = (_SHORT)iPoint0 ;
|
|
pNew->ipoint1 = (_SHORT)iPoint1 ;
|
|
}
|
|
|
|
(*pLspecl)++ ;
|
|
#if PG_DEBUG
|
|
if ( mpr > 0 )
|
|
PaintSpeclElement( pLowData , pTmpSpecl ,
|
|
pSpecl , pLspecl ) ;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
flagNote = _FALSE ;
|
|
err_msg( " NoteSpecl: SPECL is full, nowhere to write...") ;
|
|
}
|
|
|
|
return( flagNote ) ;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
#if PG_DEBUG
|
|
_VOID PaintSpeclElement( low_type _PTR pLowData, SPECL _PTR pNewSpecl,
|
|
SPECL _PTR specl , _SHORT _PTR pLspecl )
|
|
{
|
|
_SHORT _PTR x = pLowData->x ;
|
|
_SHORT _PTR y = pLowData->y ;
|
|
_SHORT begin = pNewSpecl->ibeg ;
|
|
_SHORT end = pNewSpecl->iend ;
|
|
_SHORT ipoint0 = pNewSpecl->ipoint0 ;
|
|
_SHORT ipoint1 = pNewSpecl->ipoint1 ;
|
|
_UCHAR mark = pNewSpecl->mark ;
|
|
_SHORT start , stop ;
|
|
_SHORT color ;
|
|
|
|
if ( mpr != 3 )
|
|
{
|
|
switch( mark )
|
|
{
|
|
case MINW : color = COLORMIN ; break ;
|
|
case MAXW : color = COLORMAX ; break ;
|
|
case _MINX : color = COLORT ; break ;
|
|
case _MAXX : color = COLORMAXN ; break ;
|
|
|
|
case SHELF : color = COLORSH ;
|
|
if ( ( ipoint0 != UNDEF ) && ( ipoint1 != UNDEF ) )
|
|
draw_line( x[ipoint0] , y[ipoint0] ,
|
|
x[ipoint1] , y[ipoint1] ,
|
|
EGA_LIGHTBLUE , SOLID_LINE , 3 );
|
|
break ;
|
|
|
|
case STROKE : color = COLORT ;
|
|
if ( ( ipoint0 != UNDEF ) && ( ipoint1 != UNDEF ) )
|
|
draw_line( x[ipoint0], y[ipoint0] ,
|
|
x[ipoint1], y[ipoint1] ,
|
|
EGA_LIGHTBLUE, SOLID_LINE , 3 );
|
|
break ;
|
|
|
|
case CROSS : color = COLORC ;
|
|
if ( specl[*pLspecl-1].other == CIRCLE_NEXT )
|
|
{
|
|
stop = end ;
|
|
start = specl[*pLspecl-2].ibeg ;
|
|
}
|
|
break ;
|
|
|
|
case STICK : color = COLORC ; break ;
|
|
case HATCH : color = COLORC ; break ;
|
|
case ANGLE : color = COLORAN ; break ;
|
|
default : goto QUIT ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch( mark )
|
|
{
|
|
case MINXY : color = COLORMIN ; break ;
|
|
case MAXXY : color = COLORMAX ; break ;
|
|
case MINYX : color = COLORT ; break ;
|
|
case MAXYX : color = COLORMAXN ; break ;
|
|
case SHELF : color = COLORSH ; break ;
|
|
case STROKE : color = COLORT ; break ;
|
|
case DOT : color = COLORP ; break ;
|
|
|
|
case CROSS : color = COLOR ;
|
|
if ( specl[*pLspecl-1].other == CIRCLE_NEXT )
|
|
{
|
|
color = COLORC ;
|
|
stop = end ;
|
|
start = specl[*pLspecl-2].ibeg ;
|
|
}
|
|
break ;
|
|
|
|
case STICK : color = COLOR ; break ;
|
|
case HATCH : color = COLOR ; break ;
|
|
|
|
default : goto QUIT ;
|
|
}
|
|
}
|
|
if ( ( specl[*pLspecl-1].other != CIRCLE_FIRST ) &&
|
|
( specl[*pLspecl-1].other != CIRCLE_NEXT ) )
|
|
draw_arc( color ,x,y, begin,end ) ;
|
|
|
|
if ( specl[*pLspecl-1].other == CIRCLE_NEXT )
|
|
{
|
|
draw_line( x[start], y[start], x[stop], y[stop],
|
|
COLORC,SOLID_LINE,NORM_WIDTH ) ;
|
|
draw_line( x[start], y[start]+1, x[stop], y[stop]+1,
|
|
COLORAN,DOTTED_LINE,THICK_WIDTH ) ;
|
|
draw_line( x[start], y[start]-1, x[stop], y[stop]-1,
|
|
COLORAN,DOTTED_LINE,THICK_WIDTH ) ;
|
|
}
|
|
QUIT: return ;
|
|
}
|
|
#endif
|
|
|
|
|
|
/**************************************************************************/
|
|
#endif //#ifndef LSTRIP
|