📄 normray.c
字号:
/* increment number of reflections */
++nref;
if (s2-pxr*pxr>=0) {
/* pre-critical reflection */
if (infofp!=NULL)
fprintf(infofp,
"Reflected pre-critically at %g degrees.\n",
acos(-pzr/sqrt(s))*180/PI);
temp1 = -pzr*dens2/dens1/sqrt(s);
temp2 = sqrt(s2/s-(pxr*pxr/s));
coeff = (temp1-temp2)/(temp1+temp2);
ampli *= coeff;
} else {
/* post-critical reflection */
coeff = 1;
ampliphase -= 2*atan(-sqrt(pxr*pxr-s2)*dens1/(dens2*pzr));
if (infofp!=NULL)
fprintf(infofp,
"Reflected post-critically at %g degrees.\n",
acos(-pzr/sqrt(s))*180/PI);
}
if (infofp!=NULL) {
fprintf(infofp," --incident side: v1=%g dens1=%g\n",
1/sqrt(s),dens1);
fprintf(infofp," --opposite side: v2=%g dens2=%g\n",
1/sqrt(s2),dens2);
fprintf(infofp," --reflection coeff: %g\n",coeff);
fprintf(infofp," --total ampl coeff: %g\n",ampli);
fprintf(infofp," --total phase shift: %g\n",ampliphase);
}
/* return new raystep */
rs->rsNext = (RayStep*)ealloc1(1,sizeof(RayStep));
rs = rs->rsNext;
rs->sigma = sigma;
rs->x = x;
rs->z = z;
rs->px = px;
rs->pz = pz;
rs->t = t;
rs->q1 = q1;
rs->p1 = p1;
rs->q2 = q2;
rs->p2 = p2;
rs->kmah = kmah;
rs->nref = nref;
rs->eu = eu;
rs->f = f;
rs->rsNext = NULL;
rs->ampli = ampli;
rs->ampliphase = ampliphase;
rs->atten = atten;
return rs;
}
static void evaluateDynamic (float sigma,
float px, float pz, float dsdx, float dsdz,
float *q1, float *p1, float *q2, float *p2, int *kmah)
/* evaluate dynamic ray parameters */
{
double s0,s1,s2,ss,scale,a,b,c,d,e,
q1i,p1i,q2i,p2i,q1o,p1o,q2o,p2o;
/* get input dynamic ray parameters */
q1i = *q1; p1i = *p1; q2i = *q2; p2i = *p2;
/* trivial case: constant sloth or ray parallel to sloth gradient */
if (pz*dsdx==px*dsdz) {
q1o = q1i+p1i*sigma;
q2o = q2i+p2i*sigma;
p2o = p2i;
p1o = p1i;
/* else, general case */
} else {
/* constants */
s0 = px*px+pz*pz;
s1 = px*dsdx+pz*dsdz;
s2 = 0.25*(dsdx*dsdx+dsdz*dsdz);
ss = (s2*sigma+s1)*sigma+s0;
scale = 1.0/sqrt(s0*ss);
a = s0+0.5*s1*sigma;
b = (0.25*s1*s1/s0-s2)*sigma;
c = s0+s1*sigma;
d = 0.5*s1+2.0*b;
b *= sigma;
e = (0.5*s1+s2*sigma)/ss;
/* update q1 and q2 */
q1o = scale*(a*(q1i+p1i*sigma)+b*q1i);
q2o = scale*(a*(q2i+p2i*sigma)+b*q2i);
/* update p1 and p2 */
p1o = scale*(c*p1i+d*q1i)-e*q1o;
p2o = scale*(c*p2i+d*q2i)-e*q2o;
}
/* update kmah index */
if (q2i*q2o>=0.0 && p2i*p2o<0.0 && q2i*p2i<0.0)
*kmah += 2;
else if (q2o==0.0 || q2i*q2o<0.0
|| (q2i==0.0 && p2i*p2o<0.0 && q2o*p2o>0.0))
*kmah += 1;
/* return updated dynamic ray parameters */
*q1 = q1o; *p1 = p1o; *q2 = q2o; *p2 = p2o;
}
static void evaluateDynamic2 (float sigma,
float px, float pz, float dsdx, float dsdz,
float *q1, float *p1, float *q2, float *p2,
float s0, float s1, float s2)
/* evaluate dynamic ray parameters at each point of the ray */
{
double ss,scale,a,b,c,d,e,
q1i,p1i,q2i,p2i,q1o,p1o,q2o,p2o;
/* get input dynamic ray parameters */
q1i = *q1; p1i = *p1; q2i = *q2; p2i = *p2;
/* trivial case: constant sloth or ray parallel to sloth gradient */
if (pz*dsdx==px*dsdz) {
q1o = q1i+p1i*sigma;
q2o = q2i+p2i*sigma;
p2o = p2i;
p1o = p1i;
/* else, general case */
} else {
/* constants */
ss = (s2*sigma+s1)*sigma+s0;
scale = 1.0/sqrt(s0*ss);
a = s0+0.5*s1*sigma;
b = (0.25*s1*s1/s0-s2)*sigma;
c = s0+s1*sigma;
d = 0.5*s1+2.0*b;
b *= sigma;
e = (0.5*s1+s2*sigma)/ss;
/* update q1 and q2 */
q1o = scale*(a*(q1i+p1i*sigma)+b*q1i);
q2o = scale*(a*(q2i+p2i*sigma)+b*q2i);
/* update p1 and p2 */
p1o = scale*(c*p1i+d*q1i)-e*q1o;
p2o = scale*(c*p2i+d*q2i)-e*q2o;
}
/* return updated dynamic ray parameters */
*q1 = q1o; *p1 = p1o; *q2 = q2o; *p2 = p2o;
}
int checkIfSourceOnEdge (Face *tris, float zs, float xs)
{
float x1,x2,x3,z1,z2,z3,m12,m13,m23,b12,b13,b23,eps;
EdgeUse *eu;
eu = tris->eu;
eps = tris->m->eps;
/* get vertices */
x1 = eu->vu->v->y;
z1 = eu->vu->v->x;
x2 = eu->euCW->vu->v->y;
z2 = eu->euCW->vu->v->x;
x3 = eu->euCCW->vu->v->y;
z3 = eu->euCCW->vu->v->x;
/* source is sitting on vertex */
if ((xs-x1)*(xs-x1)+(zs-z1)*(zs-z1)<eps
|| (xs-x2)*(xs-x2)+(zs-z2)*(zs-z2)<eps
|| (xs-x3)*(xs-x3)+(zs-z3)*(zs-z3)<eps) return 2;
/* check special cases and compute slope of edges */
if (ABS(x1-x2)<0.1*eps) {
if (ABS(xs-x1)<0.1*eps) {
return 1;
} else {
m12 = 0.01*FLT_MAX;
}
} else {
m12 = (z1-z2)/(x1-x2);
}
if (ABS(x1-x3)<0.1*eps) {
if (ABS(xs-x1)<0.1*eps) {
return 1;
} else {
m13 = 0.01*FLT_MAX;
}
} else {
m13 = (z1-z3)/(x1-x3);
}
if (ABS(x2-x3)<0.1*eps) {
if (ABS(xs-x2)<0.1*eps) {
return 1;
} else {
m23 = 0.01*FLT_MAX;
}
} else {
m23 = (z2-z3)/(x2-x3);
}
b12 = z1-m12*x1;
b13 = z1-m13*x1;
b23 = z2-m23*x2;
/* source on edge? */
if (ABS(zs-m12*xs-b12)<0.1*eps
|| ABS(zs-m13*xs-b13)<0.1*eps
|| ABS(zs-m23*xs-b23)<0.1*eps) return 1;
return 0;
}
void writeFresnel (Model *m, FILE *rayfp, FILE *infofp, int nxz, int nray,
RayStep *rs[], RayEnd re[], int krecord, float freq, int prim,
FILE *fresnelfp)
/* for each ray, write x,z pairs and FresnelVolume */
{
int iray,nrs,irs,nxzw,ns,is,icount;
float sigmamax=0.0,sigma1,sigma2,x,z,px,pz,dsdx,dsdz,dummy,
ds,xs,zs,dsigma,mfa,mfb,scale;
float q1end=0.0,q2end=0.0,q1,q2,p1,p2,s0,s1,s2,q1i,q2i,p1i,p2i;
float xfresnel1,xfresnel2,zfresnel1,zfresnel2;
float *xa,*za,*r;
RayStep *rsi;
FaceAttributes *fa;
/* allocate space for auxiliary arrays */
xa = ealloc1float(nxz);
za = ealloc1float(nxz);
r = ealloc1float(nxz);
/* initialize counter */
icount = 0;
/* loop over rays */
for (iray=0; iray<nray; ++iray) {
if (krecord==INT_MAX || (krecord==re[iray].kend
&& (prim==INT_MAX || prim==re[iray].nref))) {
/* count rays */
++icount;
/* count ray steps while determining maximum sigma */
/* and the spreading values at the ray ends */
for (nrs=0,rsi=rs[iray]; rsi!=NULL;
++nrs,rsi=rsi->rsNext) {
sigmamax = rsi->sigma;
q1end = rsi->q1;
q2end = rsi->q2;
}
/* initialize number of (x,z) written for this ray */
nxzw = 0;
/* loop over ray steps */
for (irs=0,rsi=rs[iray]; irs<nrs;
++irs,rsi=rsi->rsNext) {
/* if sufficient number of (x,z) */
/* have been written */
if (nxzw>=nxz) break;
/* ray parameters at this step */
x = rsi->x;
z = rsi->z;
px = rsi->px;
pz = rsi->pz;
fa = rsi->f->fa;
dsdx = fa->dsdx;
dsdz = fa->dsdz;
/* constants for nontrivial case */
s0 = px*px+pz*pz;
s1 = px*dsdx+pz*dsdz;
s2 = 0.25*(dsdx*dsdx+dsdz*dsdz);
/* sigma at this step and next step */
sigma1 = rsi->sigma;
sigma2 = (irs<nrs-1)?rsi->rsNext->sigma:sigma1;
/* q1, q2, p1, p2 at this step */
q1i = rsi->q1;
q2i = rsi->q2;
p1i = rsi->p1;
p2i = rsi->p2;
/* number of sigma between this */
/* step and next */
ns = 1+(sigma2-sigma1)*(nxz-1)/(2.0*sigmamax);
/* increment in sigma */
ds = (sigma2-sigma1)/ns;
/* loop over sigma */
for (is=0,dsigma=0.0; is<ns; ++is,dsigma+=ds) {
/* compute and write x and z */
xs = x+dsigma*(px+dsigma*0.25*dsdx);
zs = z+dsigma*(pz+dsigma*0.25*dsdz);
xa[nxzw] = xs;
za[nxzw] = zs;
if (efwrite(&zs,sizeof(float),1,rayfp)
!=1) err("error writing "
"ray file!\n");
if (efwrite(&xs,sizeof(float),1,rayfp)
!=1) err("error writing "
"ray file!\n");
q1 = q1i;
q2 = q2i;
p1 = p1i;
p2 = p2i;
/* compute and write p1,p2,q1,q2 */
evaluateDynamic2(dsigma,px,pz,
dsdx,dsdz,&q1,&p1,&q2,&p2,
s0,s1,s2);
/* compute m(Of,A) */
if (q2==0)
mfa = FLT_MAX;
else
mfa = p2/q2;
/* compute m(Of,B) */
mfb = -q1*q2end+q2*q1end;
if (mfb==0)
mfb = FLT_MAX;
else
mfb = (p2*q1end-p1*q2end)/mfb;
/* compute fresnel radius */
dummy = ABS(1.0/((mfa-mfb)*freq));
r[nxzw] = sqrt(dummy);
/* if sufficient number */
/* written, break */
if (++nxzw>=nxz) break;
}
}
/* if necessary, repeat last (x,z) and r */
while (nxzw<nxz) {
xa[nxzw] = xs;
za[nxzw] = zs;
r[nxzw] = 0;
if (efwrite(&zs,sizeof(float),1,rayfp)!=1)
err("error writing ray file!\n");
if (efwrite(&xs,sizeof(float),1,rayfp)!=1)
err("error writing ray file!\n");
++nxzw;
}
/* compute fresnel points */
if (infofp!=NULL)
fprintf(infofp,"Fresnel points:\n");
for (is=0; is<nxz; ++is) {
if (is==0 || is==nxz-1) {
xfresnel1 = xfresnel2 = xa[is];
zfresnel1 = zfresnel2 = za[is];
} else {
scale = sqrt((za[is-1]-za[is+1])
*(za[is-1]-za[is+1])
+(xa[is+1]-xa[is-1])
*(xa[is+1]-xa[is-1]));
if (scale==0 || is==0 || is==nxz-1) {
xfresnel1 = xfresnel2 = xa[is];
zfresnel1 = zfresnel2 = za[is];
} else {
dummy = 1.0/scale
*(za[is-1]-za[is+1])
*r[is];
xfresnel1 = xa[is]+dummy;
xfresnel2 = xa[is]-dummy;
dummy = 1.0/scale
*(xa[is+1]-xa[is-1])
*r[is];
zfresnel1 = za[is]+dummy;
zfresnel2 = za[is]-dummy;
}
}
if (infofp!=NULL)
fprintf(infofp,
"x1=%g z1=%g "
"x2=%g z2=%g r=%g\n",
xfresnel1,zfresnel1,
xfresnel2,zfresnel2,r[is]);
if (efwrite(&zfresnel1,sizeof(float),1,
fresnelfp)!=1)
err("error writing Fresnel file!\n");
if (efwrite(&xfresnel1,sizeof(float),1,
fresnelfp)!=1)
err("error writing Fresnel file!\n");
if (efwrite(&zfresnel2,sizeof(float),1,
fresnelfp)!=1)
err("error writing Fresnel file!\n");
if (efwrite(&xfresnel2,sizeof(float),1,
fresnelfp)!=1)
err("error writing Fresnel file!\n");
} /* end loop over fresnel points */
} else {
/* do not write rays and fresnel volumes; */
/* manipulate rayend information */
re[iray].kend = -1;
}
} /* close loop over rays */
if (infofp!=NULL)
fprintf(infofp,"\nWrote %d rays to ray file.\n",icount);
/* free space */
free1float(xa);
free1float(za);
free1float(r);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -