11#if defined __cplusplus
19static nfu_status ptwXY_clip2(
ptwXYPoints *ptwXY1,
double y,
double x1,
double y1,
double x2,
double y2 );
20static double ptwXY_thicken_linear_dx(
int sectionSubdivideMax,
double dxMax,
double x1,
double x2 );
21static nfu_status ptwXY_thin2(
ptwXYPoints *thinned,
char *thin,
double accuracy, int64_t i1, int64_t i2 );
49 else if( y2 > yMax ) {
55 return( ptwXY1->
status = status );
56 for( i = 0; i < n; i++ ) {
62 if( points->
y > yMin ) {
63 if( ( status = ptwXY_clip2( clipped, yMin, points->
x, points->
y, x2, y2 ) ) !=
nfu_Okay )
goto Err;
68 for( i++; i < n; i++ )
if( !( ptwXY1->
points[i].
y < yMin ) )
break;
72 if( ( status = ptwXY_clip2( clipped, yMin, ptwXY1->
points[i-1].
x, ptwXY1->
points[i-1].
y, x2, y2 ) ) !=
nfu_Okay )
goto Err;
74 if( ( status = ptwXY_clip2( clipped, yMax, ptwXY1->
points[i-1].
x, ptwXY1->
points[i-1].
y, x2, y2 ) ) !=
nfu_Okay )
goto Err;
76 else if( j != n - 1 ) {
80 else if( y2 > yMax ) {
83 if( points->
y < yMax ) {
84 if( ( status = ptwXY_clip2( clipped, yMax, points->
x, points->
y, x2, y2 ) ) !=
nfu_Okay )
goto Err;
89 for( i++; i < n; i++ )
if( !( ptwXY1->
points[i].
y > yMax ) )
break;
93 if( ( status = ptwXY_clip2( clipped, yMax, ptwXY1->
points[i-1].
x, ptwXY1->
points[i-1].
y, x2, y2 ) ) !=
nfu_Okay )
goto Err;
95 if( ( status = ptwXY_clip2( clipped, yMin, ptwXY1->
points[i-1].
x, ptwXY1->
points[i-1].
y, x2, y2 ) ) !=
nfu_Okay )
goto Err;
97 else if( j != n - 1 ) {
121 return( ptwXY1->
status = status );
126static nfu_status ptwXY_clip2(
ptwXYPoints *clipped,
double y,
double x1,
double y1,
double x2,
double y2 ) {
131 x = ( y - y1 ) * ( x2 - x1 ) / ( y2 - y1 ) + x1;
146 double x1, x2 = 0., y1, y2 = 0., fx = 1.1, x, dx, dxp, lfx, y;
147 int64_t i, notFirstPass = 0;
148 int nfx, nDone, doLinear;
152 if( ( sectionSubdivideMax < 1 ) || ( dxMax < 0. ) || ( fxMax < 1. ) )
return(
nfu_badInput );
155 for( i = ptwXY1->
length - 1; i >= 0; i-- ) {
159 dx = ptwXY_thicken_linear_dx( sectionSubdivideMax, dxMax, x1, x2 );
168 nfx = sectionSubdivideMax; }
170 nfx = ( (int) ( lfx /
G4Log( fxMax ) ) ) + 1;
171 if( nfx > sectionSubdivideMax ) nfx = sectionSubdivideMax;
173 if( nfx > 0 ) fx =
G4Exp( lfx / nfx );
175 if( dx < ( fx - 1 ) * x1 ) doLinear = 1; }
187 dx = ptwXY_thicken_linear_dx( sectionSubdivideMax - nDone, dxMax, x, x2 );
188 if( dx <= ( fx - 1 ) * x ) {
193 dxp = ( fx - 1. ) * x;
196 if( ( x2 - x ) < 0.05 * std::fabs( dxp ) )
break;
213 int64_t i, j, length = ptwXY1->
length;
218 if( length < 3 )
return(
ptwXY_clone( ptwXY1, status ) );
222 if( accuracy < ptwXY1->accuracy ) accuracy = ptwXY1->
accuracy;
229 for( i = 2, j = 1; i < length; i++ ) {
231 if( ( y1 != y2 ) || ( y2 != y3 ) ) {
240 length = thinned->
length = j;
241 if( ( thin = (
char *)
nfu_calloc( 1, (
size_t) length ) ) == NULL )
goto Err;
242 if( ( *status = ptwXY_thin2( thinned, thin, accuracy, 0, length - 1 ) ) !=
nfu_Okay )
goto Err;
243 for( j = 1; j < length; j++ )
if( thin[j] != 0 )
break;
244 for( i = j + 1; i < length; i++ ) {
258 if( thin != NULL )
nfu_free( thin );
264static nfu_status ptwXY_thin2(
ptwXYPoints *thinned,
char *thin,
double accuracy, int64_t i1, int64_t i2 ) {
267 double y, s, dY, dYMax = 0., dYR, dYRMax = 0;
271 if( i1 + 1 >= i2 )
return(
nfu_Okay );
272 for( i = i1 + 1; i < i2; i++ ) {
274 s = 0.5 * ( std::fabs( y ) + std::fabs( thinned->
points[i].
y ) );
275 dY = std::fabs( y - thinned->
points[i].
y );
277 if( s != 0 ) dYR = dY / s;
278 if( ( dYR > dYRMax ) || ( ( dYR >= 0.9999 * dYRMax ) && ( dY > dYMax ) ) ) {
280 if( dY > dYMax ) dYMax = dY;
281 if( dYR > dYRMax ) dYRMax = dYR;
284 if( dYRMax < accuracy ) {
285 for( i = i1 + 1; i < i2; i++ ) thin[i] = 1; }
287 if( ( status = ptwXY_thin2( thinned, thin, accuracy, i1, iMax ) ) !=
nfu_Okay )
return( status );
288 status = ptwXY_thin2( thinned, thin, accuracy, iMax, i2 );
295static double ptwXY_thicken_linear_dx(
int sectionSubdivideMax,
double dxMax,
double x1,
double x2 ) {
298 double dx = x2 - x1, dndx;
301 dx = ( x2 - x1 ) / sectionSubdivideMax; }
305 if( ( dndx - ndx ) > 1e-6 ) ndx++;
306 if( ndx > sectionSubdivideMax ) ndx = sectionSubdivideMax;
307 if( ndx > 0 ) dx /= ndx;
325 for( i1 = 0; i1 < ptwXY->
length; i1++ ) {
326 if( ptwXY->
points[i1].
y != 0 )
break;
329 for( i2 = ptwXY->
length - 1; i2 >= 0; i2-- ) {
330 if( ptwXY->
points[i2].
y != 0 )
break;
333 if( i2 < ptwXY->length ) i2++;
336 for( i = i1; i < i2; i++ ) ptwXY->
points[i - i1] = ptwXY->
points[i];
338 ptwXY->
length = i2 - i1; }
351 int64_t overflowSize, i, i1 = 0, i2 = 0, n1 = ptwXY1->
length, n2 = ptwXY2->
length, length;
354 double x1 = 0., x2 = 0., y1 = 0., y2 = 0., y, biSectionMax, accuracy;
366 if( ( n1 == 1 ) || ( n2 == 1 ) ) {
376 if( fillWithFirst ) {
377 if( i1 < ( ptwXY1->
length - 1 ) ) {
412 length = ( n1 - i1 ) + ( n2 - i2 );
415 if( biSectionMax < ptwXY2->biSectionMax ) biSectionMax = ptwXY2->
biSectionMax;
417 if( accuracy < ptwXY2->accuracy ) accuracy = ptwXY2->
accuracy;
419 if( n == NULL )
return( NULL );
421 for( i = 0; ( i1 < n1 ) && ( i2 < n2 ); i++ ) {
424 n->points[i].x = ptwXY1->
points[i1].
x;
425 if( fillWithFirst ) {
427 if( i1 < ( ptwXY1->
length - 1 ) ) {
440 n->points[i].x = ptwXY2->
points[i2].
x;
441 if( fillWithFirst && ( ( y1 != 0. ) || ( y2 != 0. ) ) ) {
453 for( ; i1 < n1; i1++, i++ ) {
454 n->points[i].x = ptwXY1->
points[i1].
x;
455 if( fillWithFirst ) y = ptwXY1->
points[i1].
y;
458 for( ; i2 < n2; i2++, i++ ) {
459 n->points[i].x = ptwXY2->
points[i2].
x;
460 if( fillWithFirst && trim && ( n->points[i].x <= x2 ) ) {
483 int64_t i1, length = ptwXY->
length;
492 for( i1 = 0, p1 = ptwXY->
points; i1 < length; i1++, p1++ ) {
493 p1->
x = xScale * p1->
x + xOffset;
494 p1->
y = yScale * p1->
y + yOffset;
498 int64_t length_2 = length / 2;
501 for( i1 = 0, p1 = ptwXY->
points, p2 = &(ptwXY->
points[length-1]); i1 < length_2; i1++ ) {
511#if defined __cplusplus
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
enum nfu_status_e nfu_status
void * nfu_calloc(size_t size, size_t n)
nfu_status ptwXY_setValueAtX(ptwXYPoints *ptwXY, double x, double y)
ptwXYPoints * ptwXY_thin(ptwXYPoints *ptwXY1, double accuracy, nfu_status *status)
double ptwXY_getYMax(ptwXYPoints *ptwXY)
ptwXYPoints * ptwXY_union(ptwXYPoints *ptwXY1, ptwXYPoints *ptwXY2, nfu_status *status, int unionOptions)
nfu_status ptwXY_scaleOffsetXAndY(ptwXYPoints *ptwXY, double xScale, double xOffset, double yScale, double yOffset)
nfu_status ptwXY_simpleCoalescePoints(ptwXYPoints *ptwXY)
ptwXYPoint * ptwXY_getPointAtIndex_Unsafely(ptwXYPoints *ptwXY, int64_t index)
nfu_status ptwXY_trim(ptwXYPoints *ptwXY)
ptwXYPoints * ptwXY_new(ptwXY_interpolation interpolation, ptwXY_interpolationOtherInfo const *interpolationOtherInfo, double biSectionMax, double accuracy, int64_t primarySize, int64_t secondarySize, nfu_status *status, int userFlag)
nfu_status ptwXY_mergeClosePoints(ptwXYPoints *ptwXY, double epsilon)
@ ptwXY_interpolationFlat
@ ptwXY_interpolationOther
#define ptwXY_minimumSize
#define ptwXY_sectionSubdivideMax
nfu_status ptwXY_clear(ptwXYPoints *ptwXY)
#define ptwXY_union_mergeClosePoints
ptwXYPoints * ptwXY_free(ptwXYPoints *ptwXY)
ptwXYPoints * ptwXY_clone(ptwXYPoints *ptwXY, nfu_status *status)
nfu_status ptwXY_thicken(ptwXYPoints *ptwXY1, int sectionSubdivideMax, double dxMax, double fxMax)
nfu_status ptwXY_interpolatePoint(ptwXY_interpolation interpolation, double x, double *y, double x1, double y1, double x2, double y2)
double ptwXY_getYMin(ptwXYPoints *ptwXY)
nfu_status ptwXY_clip(ptwXYPoints *ptwXY1, double yMin, double yMax)
ptwXY_interpolation interpolation
ptwXY_interpolationOtherInfo interpolationOtherInfo
int64_t overflowAllocatedSize