⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 normray.c

📁 该程序主要用于三角网
💻 C
📖 第 1 页 / 共 4 页
字号:

	/* 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 + -