23 |
|
|
24 |
|
#ifdef NEWAMB |
25 |
|
|
26 |
< |
/* #define HEM_MULT 4.0 /* hem multiplier (bigger => sparser cache) */ |
26 |
> |
/* #define AHEM_MARG 1.2 /* hem margin */ |
27 |
|
|
28 |
|
extern void SDsquare2disk(double ds[2], double seedx, double seedy); |
29 |
|
|
721 |
|
|
722 |
|
|
723 |
|
/* Make sure radii don't extend beyond what we see in our periphery */ |
724 |
< |
static void |
724 |
> |
static int |
725 |
|
hem_radii(AMBHEMI *hp, FVECT uv[2], float ra[2]) |
726 |
|
{ |
727 |
< |
#ifdef HEM_MULT |
728 |
< |
double udsum = 0, vdsum = 0; |
729 |
< |
double uwsum = 0, vwsum = 0; |
730 |
< |
int i, j; |
727 |
> |
#ifdef AHEM_MARG |
728 |
> |
#define MAXDACCUM 47 |
729 |
> |
const double hemarg = AHEM_MARG*ambacc; /* hem margin */ |
730 |
> |
float radivisor2[MAXDACCUM+1]; |
731 |
> |
int i, j, k = hp->ns/10 + 1; /* around 5%ile */ |
732 |
> |
const int n2accum = (k < MAXDACCUM) ? k : MAXDACCUM ; |
733 |
> |
int na = 0; |
734 |
> |
double d; |
735 |
|
/* circle around perimeter */ |
736 |
|
for (i = 0; i < hp->ns; i++) |
737 |
|
for (j = 0; j < hp->ns; j += !i|(i==hp->ns-1) ? 1 : hp->ns-1) { |
738 |
|
AMBSAMP *ap = &ambsam(hp,i,j); |
739 |
+ |
double radiv2 = 0; |
740 |
|
FVECT vec; |
741 |
< |
double us2, vs2; |
741 |
> |
if (ap->d <= FTINY) |
742 |
> |
continue; |
743 |
|
VSUB(vec, ap->p, hp->rp->rop); |
744 |
< |
us2 = DOT(vec, uv[0]) * ap->d; |
745 |
< |
us2 *= us2; |
746 |
< |
vs2 = DOT(vec, uv[1]) * ap->d; |
747 |
< |
vs2 *= vs2; |
748 |
< |
udsum += us2 * ap->d; |
749 |
< |
uwsum += us2; |
750 |
< |
vdsum += vs2 * ap->d; |
751 |
< |
vwsum += vs2; |
744 |
> |
for (k = 2; k--; ) { |
745 |
> |
d = ap->d * DOT(vec, uv[k]) * ra[k]; |
746 |
> |
radiv2 += d*d; |
747 |
> |
} |
748 |
> |
radiv2 *= hemarg*hemarg * ap->d * ap->d; |
749 |
> |
if (radiv2 <= 1.0) |
750 |
> |
continue; |
751 |
> |
/* insert in percentile list */ |
752 |
> |
for (k = na; k && radiv2 > radivisor2[k-1]; k--) |
753 |
> |
radivisor2[k] = radivisor2[k-1]; |
754 |
> |
radivisor2[k] = radiv2; |
755 |
> |
na += (na < n2accum); |
756 |
|
} |
757 |
< |
uwsum *= HEM_MULT; /* adjust effective hem size */ |
758 |
< |
vwsum *= HEM_MULT; |
759 |
< |
/* cap radii (recall d=1/rt) */ |
760 |
< |
if (ra[0]*udsum > uwsum) |
761 |
< |
ra[0] = uwsum/udsum; |
762 |
< |
if (ra[1]*vdsum > vwsum) |
763 |
< |
ra[1] = vwsum/vdsum; |
757 |
> |
if (na < n2accum) /* current radii are OK? */ |
758 |
> |
return(0); |
759 |
> |
/* else apply divisor */ |
760 |
> |
d = 1.0/sqrt(radivisor2[na-1]); |
761 |
> |
ra[0] *= d; |
762 |
> |
ra[1] *= d; |
763 |
> |
return(1); |
764 |
> |
#undef MAXDACCUM |
765 |
> |
#else |
766 |
> |
return(0); |
767 |
|
#endif |
768 |
|
} |
769 |
|
|
849 |
|
ra[0] = 1.0/d; |
850 |
|
if (ra[1]*(d = fabs(pg[1])) > 1.0) |
851 |
|
ra[1] = 1.0/d; |
852 |
+ |
if (ra[0] > ra[1]) |
853 |
+ |
ra[0] = ra[1]; |
854 |
|
} |
855 |
|
hem_radii(hp, uv, ra); |
841 |
– |
if (ra[0] > ra[1]) |
842 |
– |
ra[0] = ra[1]; |
856 |
|
if (ra[0] < minarad) { |
857 |
|
ra[0] = minarad; |
858 |
|
if (ra[1] < minarad) |