00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #ifndef lint
00052 static const char RCStabdata[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbn/tabdata.c,v 14.11 2006/09/05 04:19:55 lbutler Exp $ (ARL)";
00053 #endif
00054
00055 #include "common.h"
00056
00057
00058 #include <stdio.h>
00059 #if HAVE_UNISTD_H
00060 #include <unistd.h>
00061 #endif
00062 #include <math.h>
00063 #include <fcntl.h>
00064 #ifdef HAVE_STRING_H
00065 #include <string.h>
00066 #else
00067 #include <strings.h>
00068 #endif
00069
00070 #include "machine.h"
00071 #include "vmath.h"
00072 #include "bu.h"
00073 #include "bn.h"
00074
00075
00076
00077
00078 void
00079 bn_table_free(struct bn_table *tabp)
00080 {
00081 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_free(x%x)\n", tabp);
00082 BN_CK_TABLE(tabp);
00083
00084 tabp->nx = 0;
00085 bu_free( tabp, "struct bn_table");
00086 }
00087
00088
00089
00090
00091 void
00092 bn_tabdata_free(struct bn_tabdata *data)
00093 {
00094 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_free(x%x)\n", data);
00095
00096 BN_CK_TABDATA(data);
00097 BN_CK_TABLE(data->table);
00098
00099 data->ny = 0;
00100 data->table = NULL;
00101 bu_free( data, "struct bn_tabdata" );
00102 }
00103
00104
00105
00106
00107 void
00108 bn_ck_table(const struct bn_table *tabp)
00109 {
00110 register int i;
00111
00112 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_ck_table(x%x)\n", tabp);
00113
00114 BN_CK_TABLE(tabp);
00115
00116 if( tabp->nx < 2 ) bu_bomb("bn_ck_table() less than 2 wavelengths\n");
00117
00118 for( i=0; i < tabp->nx; i++ ) {
00119 if( tabp->x[i] >= tabp->x[i+1] )
00120 bu_bomb("bn_ck_table() wavelengths not in strictly ascending order\n");
00121 }
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 struct bn_table *
00131 bn_table_make_uniform(int num, double first, double last)
00132 {
00133 struct bn_table *tabp;
00134 fastf_t *fp;
00135 fastf_t delta;
00136 int j;
00137
00138 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_make_uniform( num=%d, %g, %g )\n", num, first, last );
00139
00140 if( first >= last ) bu_bomb("bn_table_make_uniform() first >= last\n");
00141
00142 BN_GET_TABLE( tabp, num );
00143
00144 delta = (last - first) / (double)num;
00145
00146 fp = &tabp->x[0];
00147 for( j = num; j > 0; j-- ) {
00148 *fp++ = first;
00149 first += delta;
00150 }
00151 tabp->x[num] = last;
00152
00153 return( tabp );
00154 }
00155
00156
00157
00158
00159
00160
00161 void
00162 bn_tabdata_add(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2)
00163 {
00164 register int j;
00165 register fastf_t *op;
00166 register const fastf_t *i1, *i2;
00167
00168 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_add(x%x, x%x, x%x)\n", out, in1, in2);
00169
00170 BN_CK_TABDATA( out );
00171 BN_CK_TABDATA( in1 );
00172 BN_CK_TABDATA( in2 );
00173
00174 if( in1->table != in2->table || in1->table != out->table )
00175 bu_bomb("bn_tabdata_add(): samples drawn from different tables\n");
00176 if( in1->ny != in2->ny || in1->ny != out->ny )
00177 bu_bomb("bn_tabdata_add(): different tabdata lengths?\n");
00178
00179 op = out->y;
00180 i1 = in1->y;
00181 i2 = in2->y;
00182 for( j = in1->ny; j > 0; j-- )
00183 *op++ = *i1++ + *i2++;
00184
00185 }
00186
00187
00188
00189
00190
00191
00192 void
00193 bn_tabdata_mul(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2)
00194 {
00195 register int j;
00196 register fastf_t *op;
00197 register const fastf_t *i1, *i2;
00198
00199 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_mul(x%x, x%x, x%x)\n", out, in1, in2);
00200
00201 BN_CK_TABDATA( out );
00202 BN_CK_TABDATA( in1 );
00203 BN_CK_TABDATA( in2 );
00204
00205 if( in1->table != in2->table || in1->table != out->table )
00206 bu_bomb("bn_tabdata_mul(): samples drawn from different tables\n");
00207 if( in1->ny != in2->ny || in1->ny != out->ny )
00208 bu_bomb("bn_tabdata_mul(): different tabdata lengths?\n");
00209
00210 op = out->y;
00211 i1 = in1->y;
00212 i2 = in2->y;
00213 for( j = in1->ny; j > 0; j-- )
00214 *op++ = *i1++ * *i2++;
00215
00216 }
00217
00218
00219
00220
00221
00222
00223 void
00224 bn_tabdata_mul3(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2, const struct bn_tabdata *in3)
00225 {
00226 register int j;
00227 register fastf_t *op;
00228 register const fastf_t *i1, *i2, *i3;
00229
00230 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_mul3(x%x, x%x, x%x, x%x)\n", out, in1, in2, in3);
00231
00232 BN_CK_TABDATA( out );
00233 BN_CK_TABDATA( in1 );
00234 BN_CK_TABDATA( in2 );
00235 BN_CK_TABDATA( in3 );
00236
00237 if( in1->table != in2->table || in1->table != out->table || in1->table != in2->table )
00238 bu_bomb("bn_tabdata_mul(): samples drawn from different tables\n");
00239 if( in1->ny != in2->ny || in1->ny != out->ny )
00240 bu_bomb("bn_tabdata_mul(): different tabdata lengths?\n");
00241
00242 op = out->y;
00243 i1 = in1->y;
00244 i2 = in2->y;
00245 i3 = in3->y;
00246 for( j = in1->ny; j > 0; j-- )
00247 *op++ = *i1++ * *i2++ * *i3++;
00248
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258 void
00259 bn_tabdata_incr_mul3_scale(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2, const struct bn_tabdata *in3, register double scale)
00260 {
00261 register int j;
00262 register fastf_t *op;
00263 register const fastf_t *i1, *i2, *i3;
00264
00265 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_incr_mul3_scale(x%x, x%x, x%x, x%x, %g)\n", out, in1, in2, in3, scale);
00266
00267 BN_CK_TABDATA( out );
00268 BN_CK_TABDATA( in1 );
00269 BN_CK_TABDATA( in2 );
00270 BN_CK_TABDATA( in3 );
00271
00272 if( in1->table != in2->table || in1->table != out->table || in1->table != in3->table )
00273 bu_bomb("bn_tabdata_mul(): samples drawn from different tables\n");
00274 if( in1->ny != in2->ny || in1->ny != out->ny )
00275 bu_bomb("bn_tabdata_mul(): different tabdata lengths?\n");
00276
00277 op = out->y;
00278 i1 = in1->y;
00279 i2 = in2->y;
00280 i3 = in3->y;
00281 for( j = in1->ny; j > 0; j-- )
00282 *op++ += *i1++ * *i2++ * *i3++ * scale;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292 void
00293 bn_tabdata_incr_mul2_scale(struct bn_tabdata *out, const struct bn_tabdata *in1, const struct bn_tabdata *in2, register double scale)
00294 {
00295 register int j;
00296 register fastf_t *op;
00297 register const fastf_t *i1, *i2;
00298
00299 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_incr_mul2_scale(x%x, x%x, x%x, %g)\n", out, in1, in2, scale);
00300
00301 BN_CK_TABDATA( out );
00302 BN_CK_TABDATA( in1 );
00303 BN_CK_TABDATA( in2 );
00304
00305 if( in1->table != in2->table || in1->table != out->table )
00306 bu_bomb("bn_tabdata_mul(): samples drawn from different tables\n");
00307 if( in1->ny != in2->ny || in1->ny != out->ny )
00308 bu_bomb("bn_tabdata_mul(): different tabdata lengths?\n");
00309
00310 op = out->y;
00311 i1 = in1->y;
00312 i2 = in2->y;
00313 for( j = in1->ny; j > 0; j-- )
00314 *op++ += *i1++ * *i2++ * scale;
00315 }
00316
00317
00318
00319
00320
00321
00322 void
00323 bn_tabdata_scale(struct bn_tabdata *out, const struct bn_tabdata *in1, register double scale)
00324 {
00325 register int j;
00326 register fastf_t *op;
00327 register const fastf_t *i1;
00328
00329 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_scale(x%x, x%x, %g)\n", out, in1, scale);
00330
00331 BN_CK_TABDATA( out );
00332 BN_CK_TABDATA( in1 );
00333
00334 if( in1->table != out->table )
00335 bu_bomb("bn_tabdata_scale(): samples drawn from different tables\n");
00336 if( in1->ny != out->ny )
00337 bu_bomb("bn_tabdata_scale(): different tabdata lengths?\n");
00338
00339 op = out->y;
00340 i1 = in1->y;
00341 for( j = in1->ny; j > 0; j-- )
00342 *op++ = *i1++ * scale;
00343
00344 }
00345
00346
00347
00348
00349
00350
00351 void
00352 bn_table_scale(struct bn_table *tabp, register double scale)
00353 {
00354 register int j;
00355 register fastf_t *op;
00356
00357 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_scale(x%x, %g)\n", tabp, scale );
00358
00359 BN_CK_TABLE( tabp );
00360
00361 op = tabp->x;
00362 for( j = tabp->nx+1; j > 0; j-- )
00363 *op++ *= scale;
00364
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374 void
00375 bn_tabdata_join1(struct bn_tabdata *out, const struct bn_tabdata *in1, register double scale, const struct bn_tabdata *in2)
00376 {
00377 register int j;
00378 register fastf_t *op;
00379 register const fastf_t *i1, *i2;
00380
00381 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_join1(x%x, x%x, %g, x%x)\n", out, in1, scale, in2 );
00382
00383 BN_CK_TABDATA( out );
00384 BN_CK_TABDATA( in1 );
00385 BN_CK_TABDATA( in2 );
00386
00387 if( in1->table != out->table )
00388 bu_bomb("bn_tabdata_join1(): samples drawn from different tables\n");
00389 if( in1->table != in2->table )
00390 bu_bomb("bn_tabdata_join1(): samples drawn from different tables\n");
00391 if( in1->ny != out->ny )
00392 bu_bomb("bn_tabdata_join1(): different tabdata lengths?\n");
00393
00394 op = out->y;
00395 i1 = in1->y;
00396 i2 = in2->y;
00397 for( j = in1->ny; j > 0; j-- )
00398 *op++ = *i1++ + scale * *i2++;
00399
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 void
00411 bn_tabdata_join2(struct bn_tabdata *out, const struct bn_tabdata *in1, register double scale2, const struct bn_tabdata *in2, register double scale3, const struct bn_tabdata *in3)
00412 {
00413 register int j;
00414 register fastf_t *op;
00415 register const fastf_t *i1, *i2, *i3;
00416
00417 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_join2(x%x, x%x, %g, x%x, %g, x%x)\n", out, in1, scale2, in2, scale3, in3 );
00418
00419 BN_CK_TABDATA( out );
00420 BN_CK_TABDATA( in1 );
00421 BN_CK_TABDATA( in2 );
00422
00423 if( in1->table != out->table )
00424 bu_bomb("bn_tabdata_join1(): samples drawn from different tables\n");
00425 if( in1->table != in2->table )
00426 bu_bomb("bn_tabdata_join1(): samples drawn from different tables\n");
00427 if( in1->table != in3->table )
00428 bu_bomb("bn_tabdata_join1(): samples drawn from different tables\n");
00429 if( in1->ny != out->ny )
00430 bu_bomb("bn_tabdata_join1(): different tabdata lengths?\n");
00431
00432 op = out->y;
00433 i1 = in1->y;
00434 i2 = in2->y;
00435 i3 = in3->y;
00436 for( j = in1->ny; j > 0; j-- )
00437 *op++ = *i1++ + scale2 * *i2++ + scale3 * *i3++;
00438
00439 }
00440
00441
00442
00443
00444 void
00445 bn_tabdata_blend2(struct bn_tabdata *out, register double scale1, const struct bn_tabdata *in1, register double scale2, const struct bn_tabdata *in2)
00446 {
00447 register int j;
00448 register fastf_t *op;
00449 register const fastf_t *i1, *i2;
00450
00451 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_blend2(x%x, %g, x%x, %g, x%x)\n", out, scale1, in1, scale2, in2 );
00452
00453 BN_CK_TABDATA( out );
00454 BN_CK_TABDATA( in1 );
00455 BN_CK_TABDATA( in2 );
00456
00457 if( in1->table != out->table )
00458 bu_bomb("bn_tabdata_blend2(): samples drawn from different tables\n");
00459 if( in1->table != in2->table )
00460 bu_bomb("bn_tabdata_blend2(): samples drawn from different tables\n");
00461 if( in1->ny != out->ny )
00462 bu_bomb("bn_tabdata_blend2(): different tabdata lengths?\n");
00463
00464 op = out->y;
00465 i1 = in1->y;
00466 i2 = in2->y;
00467 for( j = in1->ny; j > 0; j-- )
00468 *op++ = scale1 * *i1++ + scale2 * *i2++;
00469
00470 }
00471
00472
00473
00474
00475 void
00476 bn_tabdata_blend3(struct bn_tabdata *out, register double scale1, const struct bn_tabdata *in1, register double scale2, const struct bn_tabdata *in2, register double scale3, const struct bn_tabdata *in3)
00477 {
00478 register int j;
00479 register fastf_t *op;
00480 register const fastf_t *i1, *i2, *i3;
00481
00482 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_blend3(x%x, %g, x%x, %g, x%x, %g, x%x)\n", out, scale1, in1, scale2, in2, scale3, in3 );
00483
00484 BN_CK_TABDATA( out );
00485 BN_CK_TABDATA( in1 );
00486 BN_CK_TABDATA( in2 );
00487 BN_CK_TABDATA( in3 );
00488
00489 if( in1->table != out->table )
00490 bu_bomb("bn_tabdata_blend3(): samples drawn from different tables\n");
00491 if( in1->table != in2->table )
00492 bu_bomb("bn_tabdata_blend3(): samples drawn from different tables\n");
00493 if( in1->table != in3->table )
00494 bu_bomb("bn_tabdata_blend3(): samples drawn from different tables\n");
00495 if( in1->ny != out->ny )
00496 bu_bomb("bn_tabdata_blend3(): different tabdata lengths?\n");
00497
00498 op = out->y;
00499 i1 = in1->y;
00500 i2 = in2->y;
00501 i3 = in3->y;
00502 for( j = in1->ny; j > 0; j-- )
00503 *op++ = scale1 * *i1++ + scale2 * *i2++ + scale3 * *i3++;
00504
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514 double
00515 bn_tabdata_area1(const struct bn_tabdata *in)
00516 {
00517 FAST fastf_t area;
00518 register const fastf_t *ip;
00519 register int j;
00520
00521 BN_CK_TABDATA(in);
00522
00523 area = 0;
00524 ip = in->y;
00525 for( j = in->ny; j > 0; j-- )
00526 area += *ip++;
00527
00528 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_area(x%x) = %g\n", in, area);
00529
00530 return area;
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 double
00542 bn_tabdata_area2(const struct bn_tabdata *in)
00543 {
00544 const struct bn_table *tabp;
00545 FAST fastf_t area;
00546 fastf_t width;
00547 register int j;
00548
00549 BN_CK_TABDATA(in);
00550 tabp = in->table;
00551 BN_CK_TABLE(tabp);
00552
00553 area = 0;
00554 for( j = in->ny-1; j >= 0; j-- ) {
00555 width = tabp->x[j+1] - tabp->x[j];
00556 area += in->y[j] * width;
00557 }
00558
00559 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_area2(x%x) = %g\n", in, area);
00560 return area;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 double
00573 bn_tabdata_mul_area1(const struct bn_tabdata *in1, const struct bn_tabdata *in2)
00574 {
00575 FAST fastf_t area;
00576 register const fastf_t *i1, *i2;
00577 register int j;
00578
00579 BN_CK_TABDATA(in1);
00580 BN_CK_TABDATA(in2);
00581
00582 area = 0;
00583 i1 = in1->y;
00584 i2 = in2->y;
00585 for( j = in1->ny; j > 0; j-- )
00586 area += *i1++ * *i2++;
00587
00588 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_mul_area1(x%x, x%x) = %g\n", in1, in2, area);
00589 return area;
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 double
00601 bn_tabdata_mul_area2(const struct bn_tabdata *in1, const struct bn_tabdata *in2)
00602 {
00603 const struct bn_table *tabp;
00604 FAST fastf_t area;
00605 fastf_t width;
00606 register int j;
00607
00608 BN_CK_TABDATA(in1);
00609 BN_CK_TABDATA(in2);
00610 tabp = in1->table;
00611 BN_CK_TABLE(tabp);
00612
00613 area = 0;
00614 for( j = in1->ny-1; j >= 0; j-- ) {
00615 width = tabp->x[j+1] - tabp->x[j];
00616 area += in1->y[j] * in2->y[j] * width;
00617 }
00618
00619 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_mul_area2(x%x, x%x) = %g\n", in1, in2, area);
00620 return area;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 int
00639 bn_table_find_x(const struct bn_table *tabp, double xval)
00640 {
00641 register int i;
00642
00643 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_find_x(x%x, %g)\n", tabp, xval );
00644 BN_CK_TABLE(tabp);
00645
00646 if( xval > tabp->x[tabp->nx] ) return -2;
00647 if( xval >= tabp->x[tabp->nx-1] ) return tabp->nx-1;
00648
00649
00650 for( i = tabp->nx-2; i >=0; i-- ) {
00651 if( xval >= tabp->x[i] ) return i;
00652 }
00653
00654 return -1;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664 fastf_t
00665 bn_table_lin_interp(const struct bn_tabdata *samp, register double wl)
00666 {
00667 const struct bn_table *tabp;
00668 register int i;
00669 register fastf_t fract;
00670 register fastf_t ret;
00671
00672 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_lin_interp(x%x, %g)\n", samp, wl);
00673
00674 BN_CK_TABDATA(samp);
00675 tabp = samp->table;
00676 BN_CK_TABLE(tabp);
00677
00678 if( (i = bn_table_find_x( tabp, wl )) < 0 ) {
00679 if(bu_debug&BU_DEBUG_TABDATA)bu_log("bn_table_lin_interp(%g) out of range %g to %g\n", wl, tabp->x[0], tabp->x[tabp->nx] );
00680 return 0;
00681 }
00682
00683 if( wl < tabp->x[i] || wl >= tabp->x[i+1] ) {
00684 bu_log("bn_table_lin_interp(%g) assertion1 failed at %g\n", wl, tabp->x[i] );
00685 bu_bomb("bn_table_lin_interp() assertion1 failed\n");
00686 }
00687
00688 if( i >= tabp->nx-2 ) {
00689
00690 if(bu_debug&BU_DEBUG_TABDATA)bu_log("bn_table_lin_interp(%g)=%g off end of range %g to %g\n", wl, samp->y[tabp->nx-1], tabp->x[0], tabp->x[tabp->nx] );
00691 return samp->y[tabp->nx-1];
00692 }
00693
00694
00695 fract = (wl - tabp->x[i]) / (tabp->x[i+1] - tabp->x[i]);
00696 if( fract < 0 || fract > 1 ) bu_bomb("bn_table_lin_interp() assertion2 failed\n");
00697 ret = (1-fract) * samp->y[i] + fract * samp->y[i+1];
00698 if(bu_debug&BU_DEBUG_TABDATA)bu_log("bn_table_lin_interp(%g)=%g in range %g to %g\n",
00699 wl, ret, tabp->x[i], tabp->x[i+1] );
00700 return ret;
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 struct bn_tabdata *
00715 bn_tabdata_resample_max(const struct bn_table *newtable, const struct bn_tabdata *olddata)
00716 {
00717 const struct bn_table *oldtable;
00718 struct bn_tabdata *newsamp;
00719 int i;
00720 int j, k;
00721
00722 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_resample_max(x%x, x%x)\n", newtable, olddata);
00723
00724 BN_CK_TABLE(newtable);
00725 BN_CK_TABDATA(olddata);
00726 oldtable = olddata->table;
00727 BN_CK_TABLE(oldtable);
00728
00729 if( oldtable == newtable ) bu_log("bn_tabdata_resample_max() NOTICE old and new bn_table structs are the same\n");
00730
00731 BN_GET_TABDATA( newsamp, newtable );
00732
00733 for( i = 0; i < newtable->nx; i++ ) {
00734
00735
00736
00737
00738 j = bn_table_find_x( oldtable, newtable->x[i] );
00739 k = bn_table_find_x( oldtable, newtable->x[i+1] );
00740 if( k == -1 ) {
00741
00742 newsamp->y[i] = 0;
00743 continue;
00744 }
00745 if( j == -2 ) {
00746
00747 newsamp->y[i] = 0;
00748 continue;
00749 }
00750
00751 if( j == k && j > 0 ) {
00752 register fastf_t tmp;
00753
00754
00755
00756
00757
00758
00759 newsamp->y[i] = bn_table_lin_interp( olddata, newtable->x[i] );
00760 tmp = bn_table_lin_interp( olddata, newtable->x[i+1] );
00761 if( tmp > newsamp->y[i] ) newsamp->y[i] = tmp;
00762 } else {
00763 register fastf_t tmp, n;
00764 register int s;
00765
00766
00767
00768
00769
00770
00771 n = bn_table_lin_interp( olddata, newtable->x[i] );
00772 tmp = bn_table_lin_interp( olddata, newtable->x[i+1] );
00773 if( tmp > n ) n = tmp;
00774 for( s = j+1; s <= k; s++ ) {
00775 if( (tmp = olddata->y[s]) > n )
00776 n = tmp;
00777 }
00778 newsamp->y[i] = n;
00779 }
00780 }
00781 return newsamp;
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795 struct bn_tabdata *
00796 bn_tabdata_resample_avg(const struct bn_table *newtable, const struct bn_tabdata *olddata)
00797 {
00798 const struct bn_table *oldtable;
00799 struct bn_tabdata *newsamp;
00800 int i;
00801 int j, k;
00802
00803 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_resample_avg(x%x, x%x)\n", newtable, olddata);
00804
00805 BN_CK_TABLE(newtable);
00806 BN_CK_TABDATA(olddata);
00807 oldtable = olddata->table;
00808 BN_CK_TABLE(oldtable);
00809
00810 if( oldtable == newtable ) bu_log("bn_tabdata_resample_avg() NOTICE old and new bn_table structs are the same\n");
00811
00812 BN_GET_TABDATA( newsamp, newtable );
00813
00814 for( i = 0; i < newtable->nx; i++ ) {
00815
00816
00817
00818
00819 j = bn_table_find_x( oldtable, newtable->x[i] );
00820 k = bn_table_find_x( oldtable, newtable->x[i+1] );
00821
00822 if( j < 0 || k < 0 || j == k ) {
00823
00824
00825
00826
00827
00828
00829 newsamp->y[i] = 0.5 * (
00830 bn_table_lin_interp( olddata, newtable->x[i] ) +
00831 bn_table_lin_interp( olddata, newtable->x[i+1] ) );
00832 } else {
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842 fastf_t wsum;
00843 fastf_t a,b;
00844 int s;
00845
00846
00847 a = bn_table_lin_interp( olddata, newtable->x[i] );
00848 b = olddata->y[j+1];
00849 wsum = 0.5 * (a+b) * (oldtable->x[j+1] - newtable->x[i] );
00850
00851
00852 for( s = j+1; s < k; s++ ) {
00853 a = olddata->y[s];
00854 b = olddata->y[s+1];
00855 wsum += 0.5 * (a+b) * (oldtable->x[s+1] - oldtable->x[s] );
00856 }
00857
00858
00859 a = olddata->y[k];
00860 b = bn_table_lin_interp( olddata, newtable->x[i+1] );
00861 wsum += 0.5 * (a+b) * (newtable->x[i+1] - oldtable->x[k] );
00862
00863
00864 newsamp->y[i] =
00865 wsum / (newtable->x[i+1] - newtable->x[i]);
00866 }
00867 }
00868 return newsamp;
00869 }
00870
00871
00872
00873
00874
00875
00876
00877
00878 int
00879 bn_table_write(const char *filename, const struct bn_table *tabp)
00880 {
00881 FILE *fp;
00882 int j;
00883
00884 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_write(%s, x%x)\n", filename, tabp);
00885
00886 BN_CK_TABLE(tabp);
00887
00888 bu_semaphore_acquire( BU_SEM_SYSCALL );
00889 fp = fopen( filename, "w" );
00890 bu_semaphore_release( BU_SEM_SYSCALL );
00891
00892 if( fp == NULL ) {
00893 perror(filename);
00894 bu_log("bn_table_write(%s, x%x) FAILED\n", filename, tabp);
00895 return -1;
00896 }
00897
00898 bu_semaphore_acquire( BU_SEM_SYSCALL );
00899 fprintf(fp, " %d sample starts, and one end.\n", tabp->nx );
00900 for( j=0; j <= tabp->nx; j++ ) {
00901 fprintf( fp, "%g\n", tabp->x[j] );
00902 }
00903 fclose(fp);
00904 bu_semaphore_release( BU_SEM_SYSCALL );
00905 return 0;
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915 struct bn_table *
00916 bn_table_read(const char *filename)
00917 {
00918 struct bn_table *tabp;
00919 struct bu_vls line;
00920 FILE *fp;
00921 int nw;
00922 int j;
00923
00924 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_read(%s)\n", filename);
00925
00926 bu_semaphore_acquire( BU_SEM_SYSCALL );
00927 fp = fopen( filename, "r" );
00928 bu_semaphore_release( BU_SEM_SYSCALL );
00929
00930 if( fp == NULL ) {
00931 perror(filename);
00932 bu_log("bn_table_read(%s) FAILED\n", filename);
00933 return NULL;
00934 }
00935
00936 bu_vls_init(&line);
00937 bu_vls_gets( &line, fp );
00938 nw = 0;
00939 sscanf( bu_vls_addr(&line), "%d", &nw );
00940 bu_vls_free(&line);
00941
00942 if( nw <= 0 ) bu_bomb("bn_table_read() bad nw value\n");
00943
00944 BN_GET_TABLE( tabp, nw );
00945
00946 bu_semaphore_acquire( BU_SEM_SYSCALL );
00947 for( j=0; j <= tabp->nx; j++ ) {
00948
00949 fscanf( fp, "%lf", &tabp->x[j] );
00950 }
00951 fclose(fp);
00952 bu_semaphore_release( BU_SEM_SYSCALL );
00953
00954 bn_ck_table( tabp );
00955
00956 return tabp;
00957 }
00958
00959
00960
00961
00962 void
00963 bn_pr_table(const char *title, const struct bn_table *tabp)
00964 {
00965 int j;
00966
00967 bu_log("%s\n", title);
00968 BN_CK_TABLE(tabp);
00969
00970 for( j=0; j <= tabp->nx; j++ ) {
00971 bu_log("%3d: %g\n", j, tabp->x[j] );
00972 }
00973 }
00974
00975
00976
00977
00978 void
00979 bn_pr_tabdata(const char *title, const struct bn_tabdata *data)
00980 {
00981 int j;
00982
00983 bu_log("%s: ", title);
00984 BN_CK_TABDATA(data);
00985
00986 for( j=0; j < data->ny; j++ ) {
00987 bu_log("%g, ", data->y[j] );
00988 }
00989 bu_log("\n");
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 int
01003 bn_print_table_and_tabdata(const char *filename, const struct bn_tabdata *data)
01004 {
01005 FILE *fp;
01006 const struct bn_table *tabp;
01007 int j;
01008
01009 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_print_table_and_tabdata(%s, x%x)\n", filename, data);
01010
01011 BN_CK_TABDATA(data);
01012 tabp = data->table;
01013 BN_CK_TABLE(tabp);
01014
01015 bu_semaphore_acquire( BU_SEM_SYSCALL );
01016 fp = fopen( filename, "w" );
01017 bu_semaphore_release( BU_SEM_SYSCALL );
01018
01019 if( fp == NULL ) {
01020 perror(filename);
01021 bu_log("bn_print_table_and_tabdata(%s, x%x) FAILED\n", filename, data );
01022 return -1;
01023 }
01024
01025 bu_semaphore_acquire( BU_SEM_SYSCALL );
01026 for( j=0; j < tabp->nx; j++ ) {
01027 fprintf( fp, "%g %g\n", tabp->x[j], data->y[j] );
01028 }
01029 fprintf( fp, "%g (novalue)\n", tabp->x[tabp->nx] );
01030 fclose(fp);
01031 bu_semaphore_release( BU_SEM_SYSCALL );
01032 return 0;
01033 }
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046 struct bn_tabdata *
01047 bn_read_table_and_tabdata(const char *filename)
01048 {
01049 struct bn_table *tabp;
01050 struct bn_tabdata *data;
01051 FILE *fp;
01052 char buf[128];
01053 int count = 0;
01054 int i;
01055
01056 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_read_table_and_tabdata(%s)\n", filename);
01057
01058 bu_semaphore_acquire( BU_SEM_SYSCALL );
01059 fp = fopen( filename, "r" );
01060 bu_semaphore_release( BU_SEM_SYSCALL );
01061
01062 if( fp == NULL ) {
01063 perror(filename);
01064 bu_log("bn_read_table_and_tabdata(%s) FAILED\n", filename);
01065 return NULL;
01066 }
01067
01068
01069 bu_semaphore_acquire( BU_SEM_SYSCALL );
01070 for(;;) {
01071 if( fgets( buf, sizeof(buf), fp ) == NULL ) break;
01072 count++;
01073 }
01074 fclose(fp);
01075 bu_semaphore_release( BU_SEM_SYSCALL );
01076
01077
01078 BN_GET_TABLE( tabp, count );
01079 BN_GET_TABDATA( data, tabp );
01080
01081
01082 bu_semaphore_acquire( BU_SEM_SYSCALL );
01083 fp = fopen( filename, "r" );
01084 for( i=0; i < count; i++ ) {
01085 buf[0] = '\0';
01086 if( fgets( buf, sizeof(buf), fp ) == NULL ) {
01087 bu_log("bn_read_table_and_tabdata(%s) unexpected EOF on line %d\n", filename, i);
01088 break;
01089 }
01090 sscanf( buf, "%lf %lf", &tabp->x[i], &data->y[i] );
01091 }
01092 fclose(fp);
01093 bu_semaphore_release( BU_SEM_SYSCALL );
01094
01095
01096 tabp->x[count] = 2 * tabp->x[count-1] - tabp->x[count-2];
01097
01098 bn_ck_table( tabp );
01099
01100 return data;
01101 }
01102
01103
01104
01105
01106 struct bn_tabdata *
01107 bn_tabdata_binary_read(const char *filename, int num, const struct bn_table *tabp)
01108 {
01109 struct bn_tabdata *data;
01110 char *cp;
01111 int nbytes;
01112 int len;
01113 int got;
01114 int fd;
01115 int i;
01116
01117 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_binary_read(%s, num=%d, x%x)\n", filename, num, tabp);
01118
01119 BN_CK_TABLE(tabp);
01120
01121 nbytes = BN_SIZEOF_TABDATA(tabp);
01122 len = num * nbytes;
01123
01124 bu_semaphore_acquire( BU_SEM_SYSCALL );
01125 fd = open(filename, 0);
01126 bu_semaphore_release( BU_SEM_SYSCALL );
01127 if( fd <= 0 ) {
01128 perror(filename);
01129 bu_log("bn_tabdata_binary_read open failed on \"%s\"\n", filename);
01130 bu_semaphore_acquire( BU_SEM_SYSCALL );
01131 close(fd);
01132 bu_semaphore_release( BU_SEM_SYSCALL );
01133 return (struct bn_tabdata *)NULL;
01134 }
01135
01136
01137 data = (struct bn_tabdata *)bu_malloc( len+8, "bn_tabdata[]" );
01138
01139 bu_semaphore_acquire( BU_SEM_SYSCALL );
01140 got = read( fd, (char *)data, len );
01141 bu_semaphore_release( BU_SEM_SYSCALL );
01142 if( got != len ) {
01143 if (got < 0) {
01144 perror(filename);
01145 bu_log("bn_tabdata_binary_read read error on \"%s\"\n", filename);
01146 } else {
01147 bu_log("bn_tabdata_binary_read(%s) expected %d got %d\n", filename, len, got);
01148 }
01149 bu_free( data, "bn_tabdata[]" );
01150 bu_semaphore_acquire( BU_SEM_SYSCALL );
01151 close(fd);
01152 bu_semaphore_release( BU_SEM_SYSCALL );
01153 return (struct bn_tabdata *)NULL;
01154 }
01155 bu_semaphore_acquire( BU_SEM_SYSCALL );
01156 close(fd);
01157 bu_semaphore_release( BU_SEM_SYSCALL );
01158
01159
01160 cp = (char *)data;
01161 for( i = num-1; i >= 0; i--, cp += nbytes ) {
01162 register struct bn_tabdata *sp;
01163 sp = (struct bn_tabdata *)cp;
01164 BN_CK_TABDATA(sp);
01165 sp->table = tabp;
01166 }
01167
01168 return data;
01169 }
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179 struct bn_tabdata *
01180 bn_tabdata_malloc_array(const struct bn_table *tabp, int num)
01181 {
01182 struct bn_tabdata *data;
01183 char *cp;
01184 int i;
01185 int nw;
01186 int nbytes;
01187
01188 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_malloc_array(x%x, num=%d)\n", tabp, num);
01189
01190 BN_CK_TABLE(tabp);
01191 nw = tabp->nx;
01192 nbytes = BN_SIZEOF_TABDATA(tabp);
01193
01194 data = (struct bn_tabdata *)bu_calloc( num,
01195 nbytes, "struct bn_tabdata[]" );
01196
01197 cp = (char *)data;
01198 for( i = 0; i < num; i++ ) {
01199 register struct bn_tabdata *sp;
01200
01201 sp = (struct bn_tabdata *)cp;
01202 sp->magic = BN_TABDATA_MAGIC;
01203 sp->ny = nw;
01204 sp->table = tabp;
01205 cp += nbytes;
01206 }
01207 return data;
01208 }
01209
01210
01211
01212
01213 void
01214 bn_tabdata_copy(struct bn_tabdata *out, const struct bn_tabdata *in)
01215 {
01216 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_copy(x%x, x%x)\n", out, in);
01217
01218 BN_CK_TABDATA( out );
01219 BN_CK_TABDATA( in );
01220
01221 if( in->table != out->table )
01222 bu_bomb("bn_tabdata_copy(): samples drawn from different tables\n");
01223 if( in->ny != out->ny )
01224 bu_bomb("bn_tabdata_copy(): different tabdata lengths?\n");
01225
01226 bcopy( (const char *)in->y, (char *)out->y, BN_SIZEOF_TABDATA_Y(in) );
01227 }
01228
01229
01230
01231
01232 struct bn_tabdata *
01233 bn_tabdata_dup(const struct bn_tabdata *in)
01234 {
01235 struct bn_tabdata *data;
01236
01237 BN_CK_TABDATA( in );
01238 BN_GET_TABDATA( data, in->table );
01239
01240 bcopy( (const char *)in->y, (char *)data->y, BN_SIZEOF_TABDATA_Y(in) );
01241
01242 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_dup(x%x) = x%x\n", in, data);
01243 return data;
01244 }
01245
01246
01247
01248
01249
01250
01251
01252 struct bn_tabdata *
01253 bn_tabdata_get_constval(double val, const struct bn_table *tabp)
01254 {
01255 struct bn_tabdata *data;
01256 int todo;
01257 register fastf_t *op;
01258
01259 BN_CK_TABLE(tabp);
01260 BN_GET_TABDATA( data, tabp );
01261
01262 op = data->y;
01263 for( todo = data->ny-1; todo >= 0; todo-- )
01264 *op++ = val;
01265
01266 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_get_constval(val=%g, x%x)=x%x\n", val, tabp, data);
01267
01268 return data;
01269 }
01270
01271
01272
01273
01274
01275
01276 void
01277 bn_tabdata_constval(struct bn_tabdata *data, double val)
01278 {
01279 int todo;
01280 register fastf_t *op;
01281
01282 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_constval(x%x, val=%g)\n", data, val);
01283
01284 BN_CK_TABDATA(data);
01285
01286 op = data->y;
01287 for( todo = data->ny-1; todo >= 0; todo-- )
01288 *op++ = val;
01289 }
01290
01291
01292
01293
01294
01295
01296
01297
01298 void
01299 bn_tabdata_to_tcl(struct bu_vls *vp, const struct bn_tabdata *data)
01300 {
01301 const struct bn_table *tabp;
01302 register int i;
01303 FAST fastf_t minval = MAX_FASTF, maxval = -MAX_FASTF;
01304
01305 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_to_tcl(x%x, x%x)\n", vp, data);
01306
01307 BU_CK_VLS(vp);
01308 BN_CK_TABDATA(data);
01309 tabp = data->table;
01310 BN_CK_TABLE(tabp);
01311
01312 bu_vls_strcat(vp, "x {");
01313 for( i=0; i < tabp->nx; i++ ) {
01314 bu_vls_printf( vp, "%g ", tabp->x[i] );
01315 }
01316 bu_vls_strcat(vp, "} y {");
01317 for( i=0; i < data->ny; i++ ) {
01318 register fastf_t val = data->y[i];
01319 bu_vls_printf( vp, "%g ", val );
01320 if( val < minval ) minval = val;
01321 if( val > maxval ) maxval = val;
01322 }
01323 bu_vls_printf( vp, "} nx %d ymin %g ymax %g",
01324 tabp->nx, minval, maxval );
01325 }
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 struct bn_tabdata *
01338 bn_tabdata_from_array(const double *array)
01339 {
01340 register const double *dp;
01341 int len = 0;
01342 struct bn_table *tabp;
01343 struct bn_tabdata *data;
01344 register int i;
01345
01346
01347 for( dp = array; *dp > 0; dp += 2 ) ;
01348 len = (dp - array) >> 1;
01349
01350
01351 BN_GET_TABLE( tabp, len );
01352 for( i = 0; i < len; i++ ) {
01353 tabp->x[i] = array[i<<1];
01354 }
01355 tabp->x[len] = tabp->x[len-1] + 1;
01356
01357
01358 BN_GET_TABDATA( data, tabp );
01359 for( i = 0; i < len-1; i++ ) {
01360 data->y[i] = array[(i<<1)+1];
01361 }
01362
01363 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_from_array(x%x) = x%x\n", array, data);
01364 return data;
01365 }
01366
01367
01368
01369
01370
01371
01372
01373 void
01374 bn_tabdata_freq_shift(struct bn_tabdata *out, const struct bn_tabdata *in, double offset)
01375 {
01376 const struct bn_table *tabp;
01377 register int i;
01378
01379 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_freq_shift(x%x, x%x, offset=%g)\n", out, in, offset);
01380
01381 BN_CK_TABDATA( out );
01382 BN_CK_TABDATA( in );
01383 tabp = in->table;
01384
01385 if( tabp != out->table )
01386 bu_bomb("bn_tabdata_freq_shift(): samples drawn from different tables\n");
01387 if( in->ny != out->ny )
01388 bu_bomb("bn_tabdata_freq_shift(): different tabdata lengths?\n");
01389
01390 for( i=0; i < out->ny; i++ ) {
01391 out->y[i] = bn_table_lin_interp( in, tabp->x[i]+offset );
01392 }
01393 }
01394
01395
01396
01397
01398
01399
01400 int
01401 bn_table_interval_num_samples(const struct bn_table *tabp, double low, double hi)
01402 {
01403 register int i;
01404 register int count = 0;
01405
01406 BN_CK_TABLE(tabp);
01407
01408 for( i=0; i < tabp->nx-1; i++ ) {
01409 if( tabp->x[i] >= low && tabp->x[i] <= hi ) count++;
01410 }
01411
01412 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_interval_num_samples(x%x, low=%g, hi=%g) = %d\n", tabp, low, hi, count);
01413 return count;
01414 }
01415
01416
01417
01418
01419
01420
01421
01422
01423 int
01424 bn_table_delete_sample_pts(struct bn_table *tabp, int i, int j)
01425 {
01426 int tokill;
01427 int k;
01428
01429 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_delete_samples(x%x, %d, %d)\n", tabp, i, j);
01430
01431 BN_CK_TABLE(tabp);
01432
01433 if( i < 0 || j < 0 ) bu_bomb("bn_table_delete_sample_pts() negative indices\n");
01434 if( i >= tabp->nx || j >= tabp->nx ) bu_bomb("bn_table_delete_sample_pts() index out of range\n");
01435
01436 tokill = j - i + 1;
01437 if( tokill < 1 ) bu_bomb("bn_table_delete_sample_pts(): nothing to delete\n");
01438 if( tokill >= tabp->nx ) bu_bomb("bn_table_delete_sample_pts(): you can't kill 'em all!\n");
01439
01440 tabp->nx -= tokill;
01441
01442 for( k = i; k < tabp->nx; k++ ) {
01443 tabp->x[k] = tabp->x[k+tokill];
01444 }
01445 return tokill;
01446 }
01447
01448
01449
01450
01451
01452
01453
01454 struct bn_table *
01455 bn_table_merge2(const struct bn_table *a, const struct bn_table *b)
01456 {
01457 struct bn_table *new;
01458 register int i, j, k;
01459
01460 BN_CK_TABLE(a);
01461 BN_CK_TABLE(b);
01462
01463 BN_GET_TABLE(new, a->nx + b->nx + 2 );
01464
01465 i = j = 0;
01466 k = 0;
01467 while( i <= a->nx || j <= b->nx ) {
01468 if( i > a->nx ) {
01469 while( j <= b->nx )
01470 new->x[k++] = b->x[j++];
01471 break;
01472 }
01473 if( j > b->nx ) {
01474 while( i <= a->nx )
01475 new->x[k++] = a->x[i++];
01476 break;
01477 }
01478
01479 if( a->x[i] == b->x[j] ) {
01480 new->x[k++] = a->x[i++];
01481 j++;
01482 continue;
01483 }
01484 if( a->x[i] <= b->x[j] ) {
01485 new->x[k++] = a->x[i++];
01486 } else {
01487 new->x[k++] = b->x[j++];
01488 }
01489 }
01490 if( k > new->nx ) bu_bomb("bn_table_merge2() assertion failed, k>nx?\n");
01491 new->nx = k-1;
01492
01493 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_table_merge2(x%x, x%x) = x%x\n", a, b, new);
01494 return new;
01495 }
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509 struct bn_tabdata *
01510 bn_tabdata_mk_linear_filter(const struct bn_table *spectrum, double lower_wavelen, double upper_wavelen)
01511 {
01512 struct bn_tabdata *filt;
01513 int first;
01514 int last;
01515 fastf_t filt_range;
01516 fastf_t cell_range;
01517 fastf_t frac;
01518 int i;
01519
01520 BN_CK_TABLE(spectrum);
01521
01522 if(bu_debug&BU_DEBUG_TABDATA) bu_log("bn_tabdata_mk_linear_filter(x%x, low=%g, up=%g)\n", spectrum, lower_wavelen, upper_wavelen);
01523
01524 if( lower_wavelen < spectrum->x[0] )
01525 if( upper_wavelen > spectrum->x[spectrum->nx] )
01526 bu_log("bn_tabdata_mk_linear_filter() warning, upper_wavelen %g > hightest sampled wavelen %g\n",
01527 upper_wavelen, spectrum->x[spectrum->nx] );
01528
01529
01530 first = bn_table_find_x( spectrum, lower_wavelen );
01531 if( first == -1 ) {
01532 first = 0;
01533 bu_log("bn_tabdata_mk_linear_filter() warning, lower_wavelen %g < lowest sampled wavelen %g\n",
01534 lower_wavelen, spectrum->x[0] );
01535 } else if( first <= -2 ) {
01536 bu_log("bn_tabdata_mk_linear_filter() ERROR, lower_wavelen %g > highest sampled wavelen %g\n",
01537 lower_wavelen, spectrum->x[spectrum->nx] );
01538 return NULL;
01539 }
01540
01541
01542 last = bn_table_find_x( spectrum, upper_wavelen );
01543 if( last == -1 ) {
01544 bu_log("bn_tabdata_mk_linear_filter() ERROR, upper_wavelen %g < lowest sampled wavelen %g\n",
01545 upper_wavelen, spectrum->x[0] );
01546 return NULL;
01547 } else if( last <= -2 ) {
01548 last = spectrum->nx-1;
01549 bu_log("bn_tabdata_mk_linear_filter() warning, upper_wavelen %g > highest sampled wavelen %g\n",
01550 upper_wavelen, spectrum->x[spectrum->nx] );
01551 }
01552
01553
01554 BN_GET_TABDATA( filt, spectrum );
01555
01556
01557 if( first == last ) {
01558 filt_range = upper_wavelen - lower_wavelen;
01559 cell_range = spectrum->x[first+1] - spectrum->x[first];
01560 frac = filt_range / cell_range;
01561
01562
01563 BU_ASSERT( (frac >= 0.0) && (frac <= 1.0) );
01564
01565 filt->y[first] = frac;
01566 return filt;
01567 }
01568
01569
01570 filt_range = spectrum->x[first+1] - lower_wavelen;
01571 cell_range = spectrum->x[first+1] - spectrum->x[first];
01572 frac = filt_range / cell_range;
01573 if( frac > 1 ) frac = 1;
01574 BU_ASSERT( (frac >= 0.0) && (frac <= 1.0) );
01575 filt->y[first] = frac;
01576
01577 filt_range = upper_wavelen - spectrum->x[last];
01578 cell_range = spectrum->x[last+1] - spectrum->x[last];
01579 frac = filt_range / cell_range;
01580 if( frac > 1 ) frac = 1;
01581 BU_ASSERT( (frac >= 0.0) && (frac <= 1.0) );
01582 filt->y[last] = frac;
01583
01584
01585 for( i = first+1; i < last; i++ )
01586 filt->y[i] = 1.0;
01587
01588 return filt;
01589 }
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599