| 6 |
|
*/ |
| 7 |
|
|
| 8 |
|
#include <stdio.h> |
| 9 |
– |
#include <math.h> |
| 9 |
|
#include <stdlib.h> |
| 10 |
|
#include <string.h> |
| 11 |
|
#include "parser.h" |
| 33 |
|
static LUTAB vtx_tab = LU_SINIT(free,free); /* vertex lookup table */ |
| 34 |
|
|
| 35 |
|
static int setspectrum(); |
| 37 |
– |
static int setbbtemp(); |
| 38 |
– |
static void mixcolors(); |
| 36 |
|
|
| 37 |
|
|
| 38 |
|
int |
| 120 |
|
return(MG_EARGC); |
| 121 |
|
if (!isflt(av[1])) |
| 122 |
|
return(MG_ETYPE); |
| 123 |
< |
return(setbbtemp(c_ccolor, atof(av[1]))); |
| 123 |
> |
if (!c_bbtemp(c_ccolor, atof(av[1]))) |
| 124 |
> |
return(MG_EILL); |
| 125 |
> |
c_ccolor->clock++; |
| 126 |
> |
return(MG_OK); |
| 127 |
|
case MG_E_CMIX: /* mix colors */ |
| 128 |
|
if (ac < 5 || (ac-1)%2) |
| 129 |
|
return(MG_EARGC); |
| 143 |
|
return(MG_EMEM); |
| 144 |
|
if (lp->data == NULL) |
| 145 |
|
return(MG_EUNDEF); |
| 146 |
< |
mixcolors(c_ccolor, wsum, c_ccolor, |
| 146 |
> |
c_cmix(c_ccolor, wsum, c_ccolor, |
| 147 |
|
w, (C_COLOR *)lp->data); |
| 148 |
|
wsum += w; |
| 149 |
|
} |
| 522 |
|
clr->clock++; |
| 523 |
|
return(MG_OK); |
| 524 |
|
} |
| 525 |
– |
|
| 526 |
– |
|
| 527 |
– |
static void |
| 528 |
– |
mixcolors(cres, w1, c1, w2, c2) /* mix two colors according to weights given */ |
| 529 |
– |
register C_COLOR *cres, *c1, *c2; |
| 530 |
– |
double w1, w2; |
| 531 |
– |
{ |
| 532 |
– |
double scale; |
| 533 |
– |
float cmix[C_CNSS]; |
| 534 |
– |
register int i; |
| 535 |
– |
|
| 536 |
– |
if ((c1->flags|c2->flags) & C_CDSPEC) { /* spectral mixing */ |
| 537 |
– |
c_ccvt(c1, C_CSSPEC|C_CSEFF); |
| 538 |
– |
c_ccvt(c2, C_CSSPEC|C_CSEFF); |
| 539 |
– |
w1 /= c1->eff*c1->ssum; |
| 540 |
– |
w2 /= c2->eff*c2->ssum; |
| 541 |
– |
scale = 0.; |
| 542 |
– |
for (i = 0; i < C_CNSS; i++) { |
| 543 |
– |
cmix[i] = w1*c1->ssamp[i] + w2*c2->ssamp[i]; |
| 544 |
– |
if (cmix[i] > scale) |
| 545 |
– |
scale = cmix[i]; |
| 546 |
– |
} |
| 547 |
– |
scale = C_CMAXV / scale; |
| 548 |
– |
cres->ssum = 0; |
| 549 |
– |
for (i = 0; i < C_CNSS; i++) |
| 550 |
– |
cres->ssum += cres->ssamp[i] = scale*cmix[i] + .5; |
| 551 |
– |
cres->flags = C_CDSPEC|C_CSSPEC; |
| 552 |
– |
} else { /* CIE xy mixing */ |
| 553 |
– |
c_ccvt(c1, C_CSXY); |
| 554 |
– |
c_ccvt(c2, C_CSXY); |
| 555 |
– |
scale = w1/c1->cy + w2/c2->cy; |
| 556 |
– |
if (scale == 0.) |
| 557 |
– |
return; |
| 558 |
– |
scale = 1. / scale; |
| 559 |
– |
cres->cx = (c1->cx*w1/c1->cy + c2->cx*w2/c2->cy) * scale; |
| 560 |
– |
cres->cy = (w1 + w2) * scale; |
| 561 |
– |
cres->flags = C_CDXY|C_CSXY; |
| 562 |
– |
} |
| 563 |
– |
} |
| 564 |
– |
|
| 565 |
– |
|
| 566 |
– |
#define C1 3.741832e-16 /* W-m^2 */ |
| 567 |
– |
#define C2 1.4388e-2 /* m-K */ |
| 568 |
– |
|
| 569 |
– |
#define bbsp(l,t) (C1/((l)*(l)*(l)*(l)*(l)*(exp(C2/((t)*(l)))-1.))) |
| 570 |
– |
#define bblm(t) (C2/5./(t)) |
| 571 |
– |
|
| 572 |
– |
static int |
| 573 |
– |
setbbtemp(clr, tk) /* set black body spectrum */ |
| 574 |
– |
register C_COLOR *clr; |
| 575 |
– |
double tk; |
| 576 |
– |
{ |
| 577 |
– |
double sf, wl; |
| 578 |
– |
register int i; |
| 579 |
– |
|
| 580 |
– |
if (tk < 1000) |
| 581 |
– |
return(MG_EILL); |
| 582 |
– |
wl = bblm(tk); /* scalefactor based on peak */ |
| 583 |
– |
if (wl < C_CMINWL*1e-9) |
| 584 |
– |
wl = C_CMINWL*1e-9; |
| 585 |
– |
else if (wl > C_CMAXWL*1e-9) |
| 586 |
– |
wl = C_CMAXWL*1e-9; |
| 587 |
– |
sf = C_CMAXV/bbsp(wl,tk); |
| 588 |
– |
clr->ssum = 0; |
| 589 |
– |
for (i = 0; i < C_CNSS; i++) { |
| 590 |
– |
wl = (C_CMINWL + i*C_CWLI)*1e-9; |
| 591 |
– |
clr->ssum += clr->ssamp[i] = sf*bbsp(wl,tk) + .5; |
| 592 |
– |
} |
| 593 |
– |
clr->flags = C_CDSPEC|C_CSSPEC; |
| 594 |
– |
clr->clock++; |
| 595 |
– |
return(MG_OK); |
| 596 |
– |
} |
| 597 |
– |
|
| 598 |
– |
#undef C1 |
| 599 |
– |
#undef C2 |
| 600 |
– |
#undef bbsp |
| 601 |
– |
#undef bblm |