inline Tv trilinear( const Tf& fracX, const Tf& fracY, const Tf& fracZ, const Tv& xyz, const Tv& Xyz, const Tv& xYz, const Tv& XYz, const Tv& xyZ, const Tv& XyZ, const Tv& xYZ, const Tv& XYZ ){ return linear(fracZ, bilinear(fracX,fracY, xyz,Xyz,xYz,XYz), bilinear(fracX,fracY, xyZ,XyZ,xYZ,XYZ) ); }
inline Tv bilinear( const Tf2& f, const Tv& xy, const Tv& Xy, const Tv& xY, const Tv& XY ){ return bilinear(f[0],f[1],xy,Xy,xY,XY); }
extern int metric_tensor(vector_t v, mt_t mt, m2_t *m2) { double a[3]; bilinear_t *B[3] = {mt.a, mt.b, mt.c}; for (int i = 0 ; i < 3 ; i++) { int err = bilinear(v.x, v.y, B[i], a+i); switch (err) { case ERROR_OK: break; case ERROR_NODATA: default: return err; } } M2A(*m2) = a[0]; M2B(*m2) = a[1]; M2C(*m2) = a[1]; M2D(*m2) = a[2]; return ERROR_OK; }
// argv[1] = img_src_path; argv[2] = img_dst_path; argv[3] = transformation int main( int argc, char *argv[] ) { // Input img *src_img = read_img( "hw8", argv[1] ) ; write_img( "yo", bilinear( "yo", src_img, 3 ), "test.img" ); return 0 ; }
double wgs84_separation(double lat, double lon) /* return geoid separation (MSL-WGS84) in meters, given a lat/lon in degrees */ { #define GEOID_ROW 19 #define GEOID_COL 37 /* *INDENT-OFF* */ /*@ +charint @*/ const int geoid_delta[GEOID_COL*GEOID_ROW]={ /* 90S */ -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, /* 80S */ -53,-54,-55,-52,-48,-42,-38,-38,-29,-26,-26,-24,-23,-21,-19,-16,-12, -8, -4, -1, 1, 4, 4, 6, 5, 4, 2, -6,-15,-24,-33,-40,-48,-50,-53,-52,-53, /* 70S */ -61,-60,-61,-55,-49,-44,-38,-31,-25,-16, -6, 1, 4, 5, 4, 2, 6, 12, 16, 16, 17, 21, 20, 26, 26, 22, 16, 10, -1,-16,-29,-36,-46,-55,-54,-59,-61, /* 60S */ -45,-43,-37,-32,-30,-26,-23,-22,-16,-10, -2, 10, 20, 20, 21, 24, 22, 17, 16, 19, 25, 30, 35, 35, 33, 30, 27, 10, -2,-14,-23,-30,-33,-29,-35,-43,-45, /* 50S */ -15,-18,-18,-16,-17,-15,-10,-10, -8, -2, 6, 14, 13, 3, 3, 10, 20, 27, 25, 26, 34, 39, 45, 45, 38, 39, 28, 13, -1,-15,-22,-22,-18,-15,-14,-10,-15, /* 40S */ 21, 6, 1, -7,-12,-12,-12,-10, -7, -1, 8, 23, 15, -2, -6, 6, 21, 24, 18, 26, 31, 33, 39, 41, 30, 24, 13, -2,-20,-32,-33,-27,-14, -2, 5, 20, 21, /* 30S */ 46, 22, 5, -2, -8,-13,-10, -7, -4, 1, 9, 32, 16, 4, -8, 4, 12, 15, 22, 27, 34, 29, 14, 15, 15, 7, -9,-25,-37,-39,-23,-14, 15, 33, 34, 45, 46, /* 20S */ 51, 27, 10, 0, -9,-11, -5, -2, -3, -1, 9, 35, 20, -5, -6, -5, 0, 13, 17, 23, 21, 8, -9,-10,-11,-20, -40,-47,-45,-25, 5, 23, 45, 58, 57, 63, 51, /* 10S */ 36, 22, 11, 6, -1, -8,-10, -8,-11, -9, 1, 32, 4,-18,-13, -9, 4, 14, 12, 13, -2,-14,-25,-32,-38,-60, -75,-63,-26, 0, 35, 52, 68, 76, 64, 52, 36, /* 00N */ 22, 16, 17, 13, 1,-12,-23,-20,-14, -3, 14, 10,-15,-27,-18, 3, 12, 20, 18, 12,-13, -9,-28,-49,-62,-89,-102,-63, -9, 33, 58, 73, 74, 63, 50, 32, 22, /* 10N */ 13, 12, 11, 2,-11,-28,-38,-29,-10, 3, 1,-11,-41,-42,-16, 3, 17, 33, 22, 23, 2, -3, -7,-36,-59,-90, -95,-63,-24, 12, 53, 60, 58, 46, 36, 26, 13, /* 20N */ 5, 10, 7, -7,-23,-39,-47,-34, -9,-10,-20,-45,-48,-32, -9, 17, 25, 31, 31, 26, 15, 6, 1,-29,-44,-61, -67,-59,-36,-11, 21, 39, 49, 39, 22, 10, 5, /* 30N */ -7, -5, -8,-15,-28,-40,-42,-29,-22,-26,-32,-51,-40,-17, 17, 31, 34, 44, 36, 28, 29, 17, 12,-20,-15,-40, -33,-34,-34,-28, 7, 29, 43, 20, 4, -6, -7, /* 40N */ -12,-10,-13,-20,-31,-34,-21,-16,-26,-34,-33,-35,-26, 2, 33, 59, 52, 51, 52, 48, 35, 40, 33, -9,-28,-39, -48,-59,-50,-28, 3, 23, 37, 18, -1,-11,-12, /* 50N */ -8, 8, 8, 1,-11,-19,-16,-18,-22,-35,-40,-26,-12, 24, 45, 63, 62, 59, 47, 48, 42, 28, 12,-10,-19,-33, -43,-42,-43,-29, -2, 17, 23, 22, 6, 2, -8, /* 60N */ 2, 9, 17, 10, 13, 1,-14,-30,-39,-46,-42,-21, 6, 29, 49, 65, 60, 57, 47, 41, 21, 18, 14, 7, -3,-22, -29,-32,-32,-26,-15, -2, 13, 17, 19, 6, 2, /* 70N */ 2, 2, 1, -1, -3, -7,-14,-24,-27,-25,-19, 3, 24, 37, 47, 60, 61, 58, 51, 43, 29, 20, 12, 5, -2,-10, -14,-12,-10,-14,-12, -6, -2, 3, 6, 4, 2, /* 80N */ 3, 1, -2, -3, -3, -3, -1, 3, 1, 5, 9, 11, 19, 27, 31, 34, 33, 34, 33, 34, 28, 23, 17, 13, 9, 4, 4, 1, -2, -2, 0, 2, 3, 2, 1, 1, 3, /* 90N */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13 }; /*@ -charint @*/ /* *INDENT-ON* */ int ilat, ilon; int ilat1, ilat2, ilon1, ilon2; ilat = (int)floor((90. + lat) / 10); ilon = (int)floor((180. + lon) / 10); /* sanity checks to prevent segfault on bad data */ if ((GEOID_ROW <= ilat) || (0 > ilat) || (GEOID_COL <= ilon) || (0 > ilon)) return 0.0; ilat1 = ilat; ilon1 = ilon; ilat2 = (ilat < GEOID_ROW - 1) ? ilat + 1 : ilat; ilon2 = (ilon < GEOID_COL - 1) ? ilon + 1 : ilon; return bilinear(ilon1 * 10.0 - 180.0, ilat1 * 10.0 - 90.0, ilon2 * 10.0 - 180.0, ilat2 * 10.0 - 90.0, lon, lat, (double)geoid_delta[ilon1 + ilat1 * GEOID_COL], (double)geoid_delta[ilon2 + ilat1 * GEOID_COL], (double)geoid_delta[ilon1 + ilat2 * GEOID_COL], (double)geoid_delta[ilon2 + ilat2 * GEOID_COL] ); }
void KisDeformPaintOpSettingsWidget::writeConfiguration( KisPropertiesConfiguration* config ) const { config->setProperty( "paintop", "deformbrush"); // XXX: make this a const id string config->setProperty( "radius", radius() ); config->setProperty( "deform_amount", deformAmount() ); config->setProperty( "deform_action", deformAction() ); config->setProperty( "bilinear", bilinear() ); config->setProperty( "use_movement_paint", useMovementPaint() ); config->setProperty( "use_counter", useCounter() ); config->setProperty( "use_old_data", useOldData() ); config->setProperty( "spacing", spacing() ); }
void init(void) { glEnable(GL_DEPTH_TEST); glClearColor(0.6, 0.6, 0.6, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); pngLoadRaw("terrain5.png", &info); setheight(); move[1] = bilinear(move[0], move[2]); tri[0] = Vec3(0, bilinear(0, 0.5), 0.5); tri[1] = Vec3(2.5, bilinear(2.5, 0), 0); tri[2] = Vec3(0, bilinear(0, -0.5), -0.5); car = glmReadOBJ("porsche.obj"); glmUnitize(car); glmScale(car, 15); glmFacetNormals(car); glmVertexNormals(car, 90); glEnable(GL_TEXTURE_2D); }
/* * ---------------------------------------------------------- * Transform from s to z domain using bilinear transform * with prewarp. * * Arguments: * For argument description look at bilinear() * * coef - pointer to array of floating point coefficients, * corresponding to output of bilinear transofrm * (z domain). * * Note: frequencies are in Hz. * ---------------------------------------------------------- */ void szxform( double *a0, double *a1, double *a2, /* numerator coefficients */ double *b0, double *b1, double *b2, /* denominator coefficients */ double fc, /* Filter cutoff frequency */ double fs, /* sampling rate */ double *k, /* overall gain factor */ float *coef) /* pointer to 4 iir coefficients */ { /* Calculate a1 and a2 and overwrite the original values */ prewarp(a0, a1, a2, fc, fs); prewarp(b0, b1, b2, fc, fs); bilinear(*a0, *a1, *a2, *b0, *b1, *b2, k, fs, coef); }
int main (int argc, char *argv[]){ unsigned int out[NUM_COLS * NUM_ROWS] = {0}; unsigned short theta = 0; theta = atoi(argv[1]); bilinear(in, (unsigned int)(NUM_COLS), (unsigned int) (NUM_ROWS), theta, out); img_write(out, 1024, 1024); return 0; }
void CIIRfilter::iir_design( int iord, char *type, float fl, float fh, float ts ) { double flw; double fhw; complex p[10]; int nps; char ptype[10]; butter_poles(p, ptype, &nps, iord); if (strncmp(type, "BP", 2) == 0) { fl = fl*ts/2.f; fh = fh*ts/2.f; flw = tangent_warp( fl, 2.f ); fhw = tangent_warp( fh, 2.f ); lp_to_bp(p, ptype, nps, flw, fhw, sn, sd, &nsects); } else if (strncmp(type, "BR", 2) == 0 ) { fl = fl*ts/2.f; fh = fh*ts/2.f; flw = tangent_warp( fl, 2.f ); fhw = tangent_warp( fh, 2.f ); lp_to_br(p, ptype, nps, flw, fhw, sn, sd, &nsects); } else if (strncmp(type, "LP", 2) == 0 ) { fh = fh*ts/2.f; fhw = tangent_warp( fh, 2.f ); lowpass( p, ptype, nps, sn, sd, &nsects ); cutoff_alter( sn, sd, nsects, fhw ); } else if (strncmp(type, "HP", 2) == 0 ) { fl = fl*ts/2.f; flw = tangent_warp( fl, 2.f ); lp_to_hp( p, ptype, nps, sn, sd, &nsects ); cutoff_alter( sn, sd, nsects, flw ); } bilinear( sn, sd, nsects ); for (int i = 0; i < nsects; i++) { x1[i] = x2[i] = y1[i] = y2[i] = 0.f; } }
void process( int2 pos ) { // d = u * ( 1 - k * pow( u, 2 ) ); // u = d / ( 1 - k * pow( d, 2 ) ); float2 pos_f = float2( pos.x, pos.y ); float2 dir = center - pos_f; float dist = length( dir ); float n_dist = dist / max_dist; float target_dist; if ( pincushion ) target_dist = dist * ( 1 - lens * pow( n_dist, 2) ); else target_dist = dist / ( 1 - lens * pow( n_dist, 2) ); float2 undistort_pos = center - normalize( dir ) * target_dist; dst() = bilinear( src, undistort_pos.x, undistort_pos.y ); }
/* Function: rotateByBilinear Rotates the image a given angle by applying bilinear method Parameters: image - Image to be rotated. width - The image's width. height - The image's height. depth - The image's color depth. angle - clockwise rotation angle new_width - New image's width new_height - New image's height Returns: ret - The image rotated counter-clockwise by an angle */ void rotateByBilinear (int *image, int *width, int *height, int *depth, double *angle, int *ret, int *new_width, int *new_height){ int x_center, y_center, x_diff, y_diff; int x, y, d; double x_src_d, y_src_d; int x_src, y_src; double x_weight, y_weight; while (*angle >= 360){ *angle = *angle - 360; } x_center = *width/2; y_center = *height/2; x_diff = (*new_width - *width)/2; y_diff = (*new_height - *height)/2; for (y = -1*y_diff; y < (*new_height - y_diff); y++){ for (x = -1*x_diff; x < (*new_width - x_diff); x++){ x_src_d = (x - x_center) * cos(*angle) + (y - y_center) * sin(*angle) + x_center; y_src_d = (y - y_center) * cos(*angle) - (x - x_center) * sin(*angle) + y_center; x_src = (int) x_src_d; y_src = (int) y_src_d; x_weight = x_src_d - x_src; y_weight = y_src_d - y_src; for (d = 0; d < *depth; d++){ if (x_src_d < 0 || y_src_d < 0 || x_src_d >= *width || y_src_d >= *height){ ret[IMGPOS(x + x_diff, y + y_diff, d, *new_width, *new_height)] = 0; }else{ int a[4]; a[0] = image[IMGPOS(x_src, y_src, d, *width, *height)]; a[1] = (x_src == *width - 1) ? a[0] : image[IMGPOS(x_src + 1, y_src, d, *width, *height)]; a[2] = (y_src == *height - 1)? a[0] : image[IMGPOS(x_src, y_src + 1, d, *width, *height)]; a[3] = ((x_src == *width - 1) || (y_src == *height - 1)) ? a[0] : image[IMGPOS(x_src + 1, y_src + 1, d, *width, *height)]; ret[IMGPOS(x + x_diff, y + y_diff, d, *new_width, *new_height)] = (int) bilinear (a, x_weight, y_weight); } } } } }
static void Interp(const ImageData *image, DBL xcoor, DBL ycoor, RGBFTColour& colour, int *index, bool premul) { int iycoor, ixcoor, i; int Corners_Index[4]; RGBFTColour Corner_Colour[4]; DBL Corner_Factors[4]; xcoor += 0.5; ycoor += 0.5; iycoor = (int)ycoor; ixcoor = (int)xcoor; no_interpolation(image, (DBL)ixcoor, (DBL)iycoor, Corner_Colour[0], &Corners_Index[0], premul); no_interpolation(image, (DBL)ixcoor - 1, (DBL)iycoor, Corner_Colour[1], &Corners_Index[1], premul); no_interpolation(image, (DBL)ixcoor, (DBL)iycoor - 1, Corner_Colour[2], &Corners_Index[2], premul); no_interpolation(image, (DBL)ixcoor - 1, (DBL)iycoor - 1, Corner_Colour[3], &Corners_Index[3], premul); if(image->Interpolation_Type == BILINEAR) bilinear(Corner_Factors, xcoor, ycoor); else if(image->Interpolation_Type == NORMALIZED_DIST) norm_dist(Corner_Factors, xcoor, ycoor); else POV_ASSERT(false); // We're using double precision for the colors here to avoid higher-than-1.0 results due to rounding errors, // which would otherwise lead to stray dot artifacts when clamped to [0..1] range for a color_map or similar. // (Note that strictly speaking we don't avoid such rounding errors, but rather make them small enough that // subsequent rounding to single precision will take care of them.) PreciseRGBFTColour temp_colour; DBL temp_index = 0; for (i = 0; i < 4; i ++) { temp_colour += PreciseRGBFTColour(Corner_Colour[i]) * Corner_Factors[i]; temp_index += Corners_Index[i] * Corner_Factors[i]; } colour = RGBFTColour(temp_colour); *index = (int)temp_index; }
void fblt(double d[],double c[],int n,int band,double fln,double fhn,double b[],double a[]) { int i,k,m,n1,n2,ls; double pi,w,w0,w1,w2,tmp,tmpd,tmpc,*work; pi=4.0*atan(1.0); w1=tan(pi*fln); for(i=n;i>=0;i--) { if((c[i]!=0.0)||(d[i]!=0.0)) break; } m=i; switch(band) { case 1:case 2: n2=m; n1=n2+1; if(band==2) { for(i=0;i<=m/2;i++) { tmp=d[i]; d[i]=d[m-i]; d[m-i]=tmp; tmp=c[i]; c[i]=c[m-i]; c[m-i]=tmp; } } for(i=0;i<=m;i++) { d[i]=d[i]/pow(w1,i); c[i]=c[i]/pow(w1,i); } break; case 3:case 4: n2=2*m; n1=n2+1; work=malloc(n1*n1*sizeof(double)); w2=tan(pi*fhn); w=w2-w1; w0=w1*w2; if(band==4) { for(i=0;i<=m/2;i++) { tmp=d[i]; d[i]=d[m-i]; d[m-i]=tmp; tmp=c[i]; c[i]=c[m-i]; c[m-i]=tmp; } } for(i=0;i<=n2;i++) { work[0*n1+i]=0.0; work[1*n1+i]=0.0; } for(i=0;i<=m;i++) { tmpd=d[i]*pow(w,(m-i)); tmpc=c[i]*pow(w,(m-i)); for(k=0;k<=i;k++) { ls=m+i-2*k; tmp=combin(i,i)/(combin(k,k)*combin(i-k,i-k)); work[0*n1+ls]+=tmpd*pow(w0,k)*tmp; work[1*n1+ls]+=tmpc*pow(w0,k)*tmp; } } for(i=0;i<=n2;i++) { d[i]=work[0*n1+i]; c[i]=work[1*n1+i]; } free(work); } bilinear(d,c,b,a,n); }
static void Interp(IMAGE *Image, DBL xcoor, DBL ycoor, COLOUR colour, int *index) { int iycoor, ixcoor, i; int Corners_Index[4]; DBL Index_Crn[4]; COLOUR Corner_Colour[4]; DBL Red_Crn[4]; DBL Green_Crn[4]; DBL Blue_Crn[4]; DBL Filter_Crn[4]; DBL Transm_Crn[4]; DBL val1, val2, val3, val4, val5; val1 = val2 = val3 = val4 = val5 = 0.0; iycoor = (int)ycoor; ixcoor = (int)xcoor; for (i = 0; i < 4; i++) { Make_ColourA(Corner_Colour[i], 0.0, 0.0, 0.0, 0.0, 0.0); } /* OK, now that you have the corners, what are you going to do with them? */ if (Image->Interpolation_Type == BILINEAR) { no_interpolation(Image, (DBL)ixcoor + 1, (DBL)iycoor, Corner_Colour[0], &Corners_Index[0]); no_interpolation(Image, (DBL)ixcoor, (DBL)iycoor, Corner_Colour[1], &Corners_Index[1]); no_interpolation(Image, (DBL)ixcoor + 1, (DBL)iycoor - 1, Corner_Colour[2], &Corners_Index[2]); no_interpolation(Image, (DBL)ixcoor, (DBL)iycoor - 1, Corner_Colour[3], &Corners_Index[3]); for (i = 0; i < 4; i++) { Red_Crn[i] = Corner_Colour[i][pRED]; Green_Crn[i] = Corner_Colour[i][pGREEN]; Blue_Crn[i] = Corner_Colour[i][pBLUE]; Filter_Crn[i] = Corner_Colour[i][pFILTER]; Transm_Crn[i] = Corner_Colour[i][pTRANSM]; // Debug_Info("Crn %d = %lf %lf %lf\n",i,Red_Crn[i],Blue_Crn[i],Green_Crn[i]); } val1 = bilinear(Red_Crn, xcoor, ycoor); val2 = bilinear(Green_Crn, xcoor, ycoor); val3 = bilinear(Blue_Crn, xcoor, ycoor); val4 = bilinear(Filter_Crn, xcoor, ycoor); val5 = bilinear(Transm_Crn, xcoor, ycoor); } if (Image->Interpolation_Type == NORMALIZED_DIST) { no_interpolation(Image, (DBL)ixcoor, (DBL)iycoor - 1, Corner_Colour[0], &Corners_Index[0]); no_interpolation(Image, (DBL)ixcoor + 1, (DBL)iycoor - 1, Corner_Colour[1], &Corners_Index[1]); no_interpolation(Image, (DBL)ixcoor, (DBL)iycoor, Corner_Colour[2], &Corners_Index[2]); no_interpolation(Image, (DBL)ixcoor + 1, (DBL)iycoor, Corner_Colour[3], &Corners_Index[3]); for (i = 0; i < 4; i++) { Red_Crn[i] = Corner_Colour[i][pRED]; Green_Crn[i] = Corner_Colour[i][pGREEN]; Blue_Crn[i] = Corner_Colour[i][pBLUE]; Filter_Crn[i] = Corner_Colour[i][pFILTER]; Transm_Crn[i] = Corner_Colour[i][pTRANSM]; // Debug_Info("Crn %d = %lf %lf %lf\n",i,Red_Crn[i],Blue_Crn[i],Green_Crn[i]); } val1 = norm_dist(Red_Crn, xcoor, ycoor); val2 = norm_dist(Green_Crn, xcoor, ycoor); val3 = norm_dist(Blue_Crn, xcoor, ycoor); val4 = norm_dist(Filter_Crn, xcoor, ycoor); val5 = norm_dist(Transm_Crn, xcoor, ycoor); } colour[pRED] += val1; colour[pGREEN] += val2; colour[pBLUE] += val3; colour[pFILTER] += val4; colour[pTRANSM] += val5; // Debug_Info("Final = %lf %lf %lf\n",val1,val2,val3); // use bilinear for index try average later for (i = 0; i < 4; i++) { Index_Crn[i] = (DBL)Corners_Index[i]; } if (Image->Interpolation_Type == BILINEAR) { *index = (int)(bilinear(Index_Crn, xcoor, ycoor) + 0.5); } if (Image->Interpolation_Type == NORMALIZED_DIST) { *index = (int)(norm_dist(Index_Crn, xcoor, ycoor) + 0.5); } }
void display(void) { #if 1 glViewport(0, 0, gw, gh / 5 * 4); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(80, 1, 1, 400); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); x = current_origin_x + _distance * cos(angle * vl_pi / 180); z = current_origin_z + _distance * sin(angle * vl_pi / 180); float y = bilinear(x, z); Vec3 tmove, ttri[3]; tmove = proj(HTrans4(Vec3(x, y, z)) * HRot4(Vec3(0, -1, 0), angle / 180 * vl_pi) * Vec4(move, 1)); for(int i = 0; i < 3; i++){ ttri[i] = proj(HTrans4(Vec3(x, 0, z)) * HRot4(Vec3(0, -1, 0), angle / 180 * vl_pi) * Vec4(tri[i], 1)); ttri[i][1] = bilinear(ttri[i][0], ttri[i][2]); } // car configuration Vec3 xx, yy, zz, tmp; tmp = ttri[1] - (ttri[0] + ttri[2]) / 2; tmp[1] = 0; yy = norm(cross((ttri[0] - ttri[2]), (ttri[1] - ttri[2]))); xx = norm(tmp - dot(yy, tmp) * yy); zz = cross(xx, yy); float mat[16] = {xx[0], xx[1], xx[2], 0.0, yy[0], yy[1], yy[2], 0.0, zz[0], zz[1], zz[2], 0.0, x, y + 4.5, z, 1.0}; // testing /* cout << "ttri[0] = " << ttri[0] << endl << "ttri[1] = " << ttri[1] << endl << "ttri[2] = " << ttri[2] << endl; cout << "ttri[0] - ttri[2] = " << ttri[0] - ttri[2] << endl << "ttri[1] - ttri[2] = " << ttri[1] - ttri[2] << endl; cout << "cross((ttri[0] - ttri[2]), (ttri[1] - ttri[2])) = " << cross((ttri[0] - ttri[2]), (ttri[1] - ttri[2])) << endl; cout << "yy = norm(cross((ttri[0] - ttri[2]), (ttri[1] - ttri[2])))\n = " << norm(cross((ttri[0] - ttri[2]), (ttri[1] - ttri[2]))) << endl << endl; printf("(%f, %f, %f)\nxx = (%f, %f, %f)\nyy = (%f, %f, %f)\nzz = (%f, %f, %f)\n", x, y, z, xx[0], xx[1], xx[2], yy[0], yy[1], yy[2], zz[0], zz[1], zz[2]); printf("ttri = (%f, %f, %f)\n", ttri[0][0], ttri[0][1], ttri[0][2]); printf("tmp = (%f, %f, %f)\n", tmp[0], tmp[1], tmp[2]); system("CLS"); */ gluLookAt(0, 100, 150, 0, 0, 0, 0, 1, 0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_LIGHTING); glColor3f (1,1,1); terrain(); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glPushMatrix(); glMultMatrixf(mat); glRotatef(-90, 0, -1, 0); glmDraw(car, GLM_MATERIAL | GLM_SMOOTH); glPopMatrix(); glDisable(GL_LIGHTING); #endif #if 1 // map glViewport(gw / 5 * 4 + 1, gh / 5 * 4 + 1, gw / 5, gh / 5); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(80, 1, 1, 400); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 150, 1, 0, 0, 0, 0, 1, 0); glColor3f (1,1,1); terrain(); glPushAttrib(GL_ENABLE_BIT); glColor3f(1, 0, 0); glPointSize(7); glDisable(GL_TEXTURE_2D); glEnable(GL_POINT_SMOOTH); glBegin(GL_POINTS); glVertex3dv(tmove.Ref()); glEnd(); glPopAttrib(); #endif glutSwapBuffers(); }
bool_t H2plus_ff(double lambda, double *chi) { register int k; static bool_t initialize=TRUE; static int index; static double *temp_index; /* --- H2+ Free-Free scattering coefficients in units of 1.0E-49 m^-1 / (H atom/m^3) / (proton/M^3). Stimulated emission is included. This represents the following interaction: H + H^+ + \nu ---> H + H^+ From: D. R. Bates (1952), MNRAS 112, 40-44 Also: R. Mathisen (1984), Master's thesis, Inst. Theor. Astroph., University of Oslo, p. 45 When called the first time (or when initialize==TRUE) the fractional indices for atmospheric temperatures into the temperature table are stored in temp_index. This memory can be freed by calling the routine with lambda==0.0 -- -------------- */ static double lambdaFF[NFF_H2P] = { 0.0, 384.6, 555.6, 833.3, 1111.1, 1428.6, 1666.7, 2000.0, 2500.0, 2857.1, 3333.3, 4000.0, 5000.0, 6666.7, 10000.0}; static double tempFF[NTEMP_H2P] = { 2.5E+03, 3.0E+03, 3.5E+03, 4.0E+03, 5.0E+03, 6.0E+03, 7.0E+03, 8.0E+03, 1.0E+04, 1.2E+04}; static double kappaFF[NFF_H2P * NTEMP_H2P] = { /* --- lambda = 0.0 [nm] -- -------------- */ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, /* --- lambda = 384.6 [nm] -- -------------- */ 0.46, 0.46, 0.42, 0.39, 0.36, 0.33, 0.32, 0.30, 0.27, 0.25, /* --- lambda = 555.6 [nm] -- -------------- */ 0.70, 0.62, 0.59, 0.56, 0.51, 0.43, 0.41, 0.39, 0.35, 0.34, /* --- lambda = 833.3 [nm] -- -------------- */ 0.92, 0.86, 0.80, 0.76, 0.70, 0.64, 0.59, 0.55, 0.48, 0.43, /* --- lambda = 1111.1 [nm] -- -------------- */ 1.11, 1.04, 0.96, 0.91, 0.82, 0.74, 0.68, 0.62, 0.53, 0.46, /* --- lambda = 1428.6 [nm] -- -------------- */ 1.26, 1.19, 1.09, 1.02, 0.90, 0.80, 0.72, 0.66, 0.55, 0.48, /* --- lambda = 1666.7 [nm] -- -------------- */ 1.37, 1.25, 1.15, 1.07, 0.93, 0.83, 0.74, 0.67, 0.56, 0.49, /* --- lambda = 2000.0 [nm] -- -------------- */ 1.44, 1.32, 1.21, 1.12, 0.97, 0.84, 0.75, 0.67, 0.56, 0.48, /* --- lambda = 2500.0 [nm] -- -------------- */ 1.54, 1.39, 1.26, 1.15, 0.98, 0.85, 0.75, 0.67, 0.55, 0.46, /* --- lambda = 2857.1 [nm] -- -------------- */ 1.58, 1.42, 1.27, 1.16, 0.98, 0.84, 0.74, 0.66, 0.54, 0.45, /* --- lambda = 3333.3 [nm] -- -------------- */ 1.62, 1.43, 1.28, 1.15, 0.97, 0.83, 0.72, 0.64, 0.52, 0.44, /* --- lambda = 4000.0 [nm] -- -------------- */ 1.63, 1.43, 1.27, 1.14, 0.95, 0.80, 0.70, 0.62, 0.50, 0.42, /* --- lambda = 5000.0 [nm] -- -------------- */ 1.62, 1.40, 1.23, 1.10, 0.90, 0.77, 0.66, 0.59, 0.48, 0.39, /* --- lambda = 6666.7 [nm] -- -------------- */ 1.55, 1.33, 1.16, 1.03, 0.84, 0.71, 0.60, 0.53, 0.43, 0.36, /* --- lambda = 10000.0 [nm] -- -------------- */ 1.39, 1.18, 1.02, 0.90, 0.73, 0.60, 0.52, 0.46, 0.37, 0.31 }; long Nspace = atmos.Nspace; double T, lambda_index, kappa, *np; if (lambda == 0.0) { /* --- When called with zero wavelength free memory for fractional indices -- -------------- */ if (temp_index) free(temp_index); initialize = TRUE; return FALSE; } if (lambda >= lambdaFF[NFF_H2P-1]) return FALSE; if (initialize) { temp_index = (double *) malloc(Nspace * sizeof(double)); for (k = 0; k < Nspace; k++) { T = atmos.T[k]; if (T <= tempFF[0]) temp_index[k] = 0; else if (T >= tempFF[NTEMP_H2P-1]) temp_index[k] = NTEMP_H2P-1; else { Hunt(NTEMP_H2P, tempFF, T, &index); temp_index[k] = index + (T - tempFF[index]) / (tempFF[index+1] - tempFF[index]); } } initialize = FALSE; } Hunt(NFF_H2P, lambdaFF, lambda, &index); lambda_index = index + (lambda - lambdaFF[index]) / (lambdaFF[index+1] - lambdaFF[index]); np = atmos.H->n[atmos.H->Nlevel-1]; for (k = 0; k < Nspace; k++) { kappa = bilinear(NTEMP_H2P, NFF_H2P, kappaFF, temp_index[k], lambda_index); chi[k] = (atmos.H->n[0][k] * 1.0E-29) * (np[k] * 1.0E-20) * kappa; } return TRUE; }
// a0-a2: numerator coefficients // b0-b2: denominator coefficients // fc: Filter cutoff frequency // fs: sampling rate // k: overall gain factor // coef: pointer to 4 iir coefficients static void szxform(double *a0, double *a1, double *a2, double *b0, double *b1, double *b2, double fc, double fs, double *k, float *coef) { // Calculate a1 and a2 and overwrite the original values prewarp(a1, a2, fc, fs); prewarp(b1, b2, fc, fs); bilinear(*a0, *a1, *a2, *b0, *b1, *b2, k, fs, coef); }
bool_t H2minus_ff(double lambda, double *chi) { register int k; static bool_t initialize=TRUE; static int index; static double *theta_index; /* --- H2-minus Free-Free absorption coefficients (in units of 10E-29 m^5/J). Stimulated emission is included. From: Bell, K. L., (1980) J. Phys. B13, 1859. Also: R. Mathisen (1984), Master's thesis, Inst. Theor. Astroph., University of Oslo, p. 18 When called the first time (or when initialize==TRUE) the fractional indices for atmospheric temperatures into the theta table are stored in theta_index. This memory can be freed by calling the routine with lambda==0.0 -- -------------- */ static double lambdaFF[NFF_H2] = { 0.0, 350.5, 414.2, 506.3, 569.6, 650.9, 759.4, 911.3, 1139.1, 1518.8, 1822.6, 2278.3, 3037.7, 3645.2, 4556.5, 6075.3, 9113.0, 11391.3, 15188.3}; static double thetaFF[NTHETA_H2] = { 0.5, 0.8, 1.0, 1.2, 1.6, 2.0, 2.8, 3.6}; static double kappaFF[NFF_H2 * NTHETA_H2] = { /* --- lambda = 0.0 [nm] -- -------------- */ 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, /* --- lambda = 350.5 [nm] -- -------------- */ 4.17e-02, 6.10e-02, 7.34e-02, 8.59e-02, 1.11e-01, 1.37e-01, 1.87e-01, 2.40e-01, /* --- lambda = 414.2 [nm] -- -------------- */ 5.84e-02, 8.43e-02, 1.01e-01, 1.17e-01, 1.49e-01, 1.82e-01, 2.49e-01, 3.16e-01, /* --- lambda = 506.3 [nm] -- -------------- */ 8.70e-02, 1.24e-01, 1.46e-01, 1.67e-01, 2.10e-01, 2.53e-01, 3.39e-01, 4.27e-01, /* --- lambda = 569.6 [nm] -- -------------- */ 1.10e-01, 1.54e-01, 1.80e-01, 2.06e-01, 2.55e-01, 3.05e-01, 4.06e-01, 5.07e-01, /* --- lambda = 650.9 [nm] -- -------------- */ 1.43e-01, 1.98e-01, 2.30e-01, 2.59e-01, 3.17e-01, 3.75e-01, 4.92e-01, 6.09e-01, /* --- lambda = 759.4 [nm] -- -------------- */ 1.92e-01, 2.64e-01, 3.03e-01, 3.39e-01, 4.08e-01, 4.76e-01, 6.13e-01, 7.51e-01, /* --- lambda = 911.3 [nm] -- -------------- */ 2.73e-01, 3.71e-01, 4.22e-01, 4.67e-01, 5.52e-01, 6.33e-01, 7.97e-01, 9.63e-01, /* --- lambda = 1139.1 [nm] -- -------------- */ 4.20e-01, 5.64e-01, 6.35e-01, 6.97e-01, 8.06e-01, 9.09e-01, 1.11e+00, 1.32e+00, /* --- lambda = 1518.8 [nm] -- -------------- */ 7.36e-01, 9.75e-01, 1.09e+00, 1.18e+00, 1.34e+00, 1.48e+00, 1.74e+00, 2.01e+00, /* --- lambda = 1822.6 [nm] -- -------------- */ 1.05e+00, 1.39e+00, 1.54e+00, 1.66e+00, 1.87e+00, 2.04e+00, 2.36e+00, 2.68e+00, /* --- lambda = 2278.3 [nm] -- -------------- */ 1.63e+00, 2.14e+00, 2.36e+00, 2.55e+00, 2.84e+00, 3.07e+00, 3.49e+00, 3.90e+00, /* --- lambda = 3037.7 [nm] -- -------------- */ 2.89e+00, 3.76e+00, 4.14e+00, 4.44e+00, 4.91e+00, 5.28e+00, 5.90e+00, 6.44e+00, /* --- lambda = 3645.2 [nm] -- -------------- */ 4.15e+00, 5.38e+00, 5.92e+00, 6.35e+00, 6.99e+00, 7.50e+00, 8.32e+00, 9.02e+00, /* --- lambda = 4556.5 [nm] -- -------------- */ 6.47e+00, 8.37e+00, 9.20e+00, 9.84e+00, 1.08e+01, 1.16e+01, 1.28e+01, 1.38e+01, /* --- lambda = 6075.3 [nm] -- -------------- */ 1.15e+01,1.48e+01, 1.63e+01, 1.74e+01, 1.91e+01, 2.04e+01, 2.24e+01, 2.40e+01, /* --- lambda = 9113.0 [nm] -- -------------- */ 2.58e+01, 3.33e+01, 3.65e+01, 3.90e+01, 4.27e+01, 4.54e+01, 4.98e+01, 5.33e+01, /* --- lambda = 11391.3 [nm] -- -------------- */ 4.03e+01, 5.20e+01, 5.70e+01, 6.08e+01, 6.65e+01, 7.08e+01, 7.76e+01, 8.30e+01, /* --- lambda = 15188.3 [nm] -- -------------- */ 7.16e+01, 9.23e+01, 1.01e+02, 1.08e+02, 1.18e+02, 1.26e+02, 1.38e+02, 1.47e+02 }; long Nspace = atmos.Nspace; double theta, pe, lambda_index, kappa, *nH2; if (lambda == 0.0) { /* --- When called with zero wavelength free memory for fractional indices -- -------------- */ if (theta_index) free(theta_index); initialize = TRUE; return FALSE; } if (lambda >= lambdaFF[NFF_H2-1]) return FALSE; if (initialize) { theta_index = (double *) malloc(Nspace * sizeof(double)); for (k = 0; k < Nspace; k++) { theta = THETA0 / atmos.T[k]; if (theta <= thetaFF[0]) theta_index[k] = 0; else if (theta >= thetaFF[NTHETA_H2-1]) theta_index[k] = NTHETA_H2-1; else { Hunt(NTHETA_H2, thetaFF, theta, &index); theta_index[k] = index + (theta - thetaFF[index]) / (thetaFF[index+1] - thetaFF[index]); } } initialize = FALSE; } Hunt(NFF_H2, lambdaFF, lambda, &index); lambda_index = index + (lambda - lambdaFF[index]) / (lambdaFF[index+1] - lambdaFF[index]); nH2 = atmos.H2->n; for (k = 0; k < Nspace; k++) { if (nH2[k] > 0.0) { pe = atmos.ne[k] * KBOLTZMANN * atmos.T[k]; kappa = bilinear(NTHETA_H2, NFF_H2, kappaFF, theta_index[k], lambda_index); chi[k] = (nH2[k] * 1.0E-29) * pe * kappa; } else chi[k] = 0.0; } return TRUE; }
void process( int2 pos ) { // OUTPUT WILL BE : // RED (0) = ACTIVE : Only particles that are on screen / valid // GREEN, BLUE (1,2) = VELOCITY : Motion Vector of the topmost particle // ALPHA (3) = DEPTH : Depth of the topmost particle // --- Convert to screen space, eliminating out of range points --- // Ignore pixels that are not active or have 0 alpha float4 exists = active(); if ( exists.x != 1.0f || ( use_pcolour && particle_colour(3) == 0.0f ) ) return; float4 particle = particles(); // Ignore pixels outside of the input image or limited to the nth position float id = ( pos.y * particles.bounds.width() + pos.x ); if ( !particles.bounds.inside( pos ) || fmod( id, float( reduce ) ) != 0.0f ) return; // Transform the particle to desired location, then to camera local space float4 particleSpace = multVectMatrix( particle, particleTransform ); float4 point_local = multVectMatrix( particleSpace, worldToCamM ); // Check if position is in front of camera if ( point_local.z > 0 ) return; // Transform position to screen space float4 screen_center = multVectMatrix( point_local, perspM ); // Trim points outside of clipping planes if ( use_zclip && ( screen_center.z < -1.0f || 1.0f < screen_center.z ) ) return; // --- Target Position and Depth --- // Fit screen space to NDC space ( 0 to 1 range ), multiply to get centerpoint pixel float ct_x = ( screen_center.x + 1 ) * 0.5f * width + overscan; float ct_y = ( screen_center.y + 1 ) * 0.5f * height + overscan; if ( !dst.bounds.inside( ct_x, ct_y ) ) return; // Normalise desired depth range ( 1 @ cam, 0 @ depth_max ) float zdepth = 1.0f + point_local.z / depth_max; // --- Optional depth masking --- // Clip points beyond the depth mask if ( use_depth && depth_max != 0.0f ) { // Move this to filter size settings? More accurate, slower int depth_x = floor( ( screen_center.x + 1 ) * 0.5f * depth.bounds.width() ); int depth_y = floor( ( screen_center.y + 1 ) * 0.5f * depth.bounds.height() ); float depth_mask = depth( depth_x, depth_y, 0 ); // Use channel_id as picked by user from a channel dropdown (r=0, g=1 etc...) if ( zdepth < depth_mask ) return; } // --- This particle may affect the image, and should be re-evaluated when calculating colour --- dst( pos.x, pos.y, 0 ) = 1.0f; // --- Pixel bounds on screen --- // Add size to create a quad centered on the particle // Can use just bottom left and top right for a non distorted plane float psize = use_psize ? size * particle.w : size; float4 botleft = point_local - float4( psize * filterAspectWidth, psize * filterAspectHeight, 0.0f, 0.0f ); float4 topright = point_local + float4( psize * filterAspectWidth, psize * filterAspectHeight, 0.0f, 0.0f ); // Transform position to screen space float4 screen_bl = multVectMatrix( botleft, perspM ); float4 screen_tr = multVectMatrix( topright, perspM ); // Fit screen space to NDC space ( 0 to 1 range ), multiply to get cornerpoints of particle float bl_x = ( screen_bl.x + 1 ) * 0.5f * width + overscan; float bl_y = ( screen_bl.y + 1 ) * 0.5f * height + overscan; float tr_x = ( screen_tr.x + 1 ) * 0.5f * width + overscan; float tr_y = ( screen_tr.y + 1 ) * 0.5f * height + overscan; // --- Velocity --- float2 out_vel = 0.0f; if ( add_velocity ) { // Calculate position from previous frame, project, and trace screen space vector motion float4 vel = velocity(); float4 prev = particle - vel; float4 next = particle + velocityNext(); // Smooth derivative of the particle at current point float4 dir = prev - next; // Apply velocity length to smoothed direction dir[3] = 0.0f; vel[3] = 0.0f; dir = normalize(dir) * length(vel); // Move new end position to screen space particleSpace = multVectMatrix( particle + dir, particleTransform ); point_local = multVectMatrix( particleSpace, worldToCamM ); screen_center = multVectMatrix( point_local, perspM ); // Calculate screen velocity float last_x = ( screen_center.x + 1 ) * 0.5f * width + overscan; float last_y = ( screen_center.y + 1 ) * 0.5f * height + overscan; out_vel = float2( ct_x - last_x, ct_y - last_y ); } // --- Iteration over affected pixels, set output --- // Range of pixels to be set, starting from bottom left int2 start = int2( floor( bl_x ), floor( bl_y ) ); int2 range = int2( floor( tr_x ), floor( tr_y ) ) - start; // Limit maximum size to safety limit : prevents timeout crashes if ( safety && ( range.x > safety_limit || range.y > safety_limit ) ) { start += int2( max( 0, ( range.x - safety_limit ) / 2 ), max( 0, ( range.y - safety_limit ) / 2 ) ); range = int2( min( safety_limit, range.x ), min( safety_limit, range.y ) ); } for ( int x = 0; x <= range.x; x++ ) { for ( int y = 0; y <= range.y; y++ ) { // Current output pixel int2 out = int2( start.x + x, start.y + y ); if ( dst.bounds.inside( out) ) { // Exit if existing pixel is closer than current pixel float existing_depth = dst( out.x, out.y, 3 ); if ( existing_depth > zdepth ) continue; // --- Filter Image Values --- if ( use_filter ) { // Fit the new size to the filter image, exit if 0 alpha float filterX = ( x / float( range.x ) ) * filterWidth; float filterY = ( y / float( range.y ) ) * filterHeight; float4 filter_value = bilinear( filterImage, filterX, filterY ); if ( filter_value.w <= 0.0f ) continue; } // Multiple passes dst( out.x, out.y, 1 ) = out_vel.x; dst( out.x, out.y, 2 ) = out_vel.y; dst( out.x, out.y, 3 ) = zdepth; } } } }
BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, const F32 width, const F32 height) { if (!mParamsReady) { // All the parameters haven't been set yet (we haven't gotten the message from the sim) return FALSE; } llassert(mSurfacep); if (!mSurfacep || !mSurfacep->getRegion()) { // We don't always have the region yet here.... return FALSE; } S32 x_begin, y_begin, x_end, y_end; x_begin = llround( x * mScaleInv ); y_begin = llround( y * mScaleInv ); x_end = llround( (x + width) * mScaleInv ); y_end = llround( (y + width) * mScaleInv ); if (x_end > mWidth) { x_end = mWidth; } if (y_end > mWidth) { y_end = mWidth; } LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); // For perlin noise generation... const F32 slope_squared = 1.5f*1.5f; const F32 xyScale = 4.9215f; //0.93284f; const F32 zScale = 4; //0.92165f; const F32 z_offset = 0.f; const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus // simple height) // Heights map into textures as 0-1 = first, 1-2 = second, etc. // So we need to compress heights into this range. const S32 NUM_TEXTURES = 4; const F32 xyScaleInv = (1.f / xyScale); const F32 zScaleInv = (1.f / zScale); const F32 inv_width = 1.f/mWidth; // OK, for now, just have the composition value equal the height at the point. for (S32 j = y_begin; j < y_end; j++) { for (S32 i = x_begin; i < x_end; i++) { F32 vec[3]; F32 vec1[3]; F32 twiddle; // Bilinearly interpolate the start height and height range of the textures F32 start_height = bilinear(mStartHeight[SOUTHWEST], mStartHeight[SOUTHEAST], mStartHeight[NORTHWEST], mStartHeight[NORTHEAST], i*inv_width, j*inv_width); // These will be bilinearly interpolated F32 height_range = bilinear(mHeightRange[SOUTHWEST], mHeightRange[SOUTHEAST], mHeightRange[NORTHWEST], mHeightRange[NORTHEAST], i*inv_width, j*inv_width); // These will be bilinearly interpolated LLVector3 location(i*mScale, j*mScale, 0.f); F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; // Step 0: Measure the exact height at this texel vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; vec[2] = height*zScaleInv; // // Choose material value by adding to the exact height a random value // vec1[0] = vec[0]*(0.2222222222f); vec1[1] = vec[1]*(0.2222222222f); vec1[2] = vec[2]*(0.2222222222f); twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component twiddle *= noise_magnitude; F32 scaled_noisy_height = (height + twiddle - start_height) * F32(NUM_TEXTURES) / height_range; scaled_noisy_height = llmax(0.f, scaled_noisy_height); scaled_noisy_height = llmin(3.f, scaled_noisy_height); *(mDatap + i + j*mWidth) = scaled_noisy_height; } } return TRUE; }
bool_t Hminus_ff(double lambda, double *chi) { register int k; static bool_t initialize=TRUE; static int index; static double *theta_index; /* --- H-minus Free-Free coefficients (in units of 1.0E-29 m^5/J) From: J. L. Stilley and J. Callaway (1970), ApJ 160, 245-260 Also: D. Mihalas (1978), p. 102 R. Mathisen (1984), Master's thesis, Inst. Theor. Astroph., University of Oslo. p. 17 When called the first time (or when initialize==TRUE) the fractional indices for atmospheric temperatures into the theta table are stored in theta_index. This memory can be freed by calling the routine with lambda==0.0 -- -------------- */ static double lambdaFF[NFF] = { 0.0, 303.8, 455.6, 506.3, 569.5, 650.9, 759.4, 911.3, 1013.0, 1139.0, 1302.0, 1519.0, 1823.0, 2278.0, 3038.0, 4556.0, 9113.0}; /* --- theta = 5040.0/T -- -------------- */ static double thetaFF[NTHETA] = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0}; static double kappaFF[NFF * NTHETA] = { /* --- lambda = 0.0 [nm] -- -------------- */ 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, /* --- lambda = 303.8 [nm] -- -------------- */ 3.44e-02, 4.18e-02, 4.91e-02, 5.65e-02, 6.39e-02, 7.13e-02, 7.87e-02, 8.62e-02, 9.36e-02, 1.01e-01, 1.08e-01, 1.16e-01, 1.23e-01, 1.30e-01, 1.38e-01, 1.45e-01, /* --- lambda = 455.6 [nm] -- -------------- */ 7.80e-02, 9.41e-02, 1.10e-01, 1.25e-01, 1.40e-01, 1.56e-01, 1.71e-01, 1.86e-01, 2.01e-01, 2.16e-01, 2.31e-01, 2.45e-01, 2.60e-01, 2.75e-01, 2.89e-01, 3.03e-01, /* --- lambda = 506.3 [nm] -- -------------- */ 9.59e-02, 1.16e-01, 1.35e-01, 1.53e-01, 1.72e-01, 1.90e-01, 2.08e-01, 2.25e-01, 2.43e-01, 2.61e-01, 2.78e-01, 2.96e-01, 3.13e-01, 3.30e-01, 3.47e-01, 3.64e-01, /* --- lambda = 569.5 [nm] -- -------------- */ 1.21e-01, 1.45e-01, 1.69e-01, 1.92e-01, 2.14e-01, 2.36e-01, 2.58e-01, 2.80e-01, 3.01e-01, 3.22e-01, 3.43e-01, 3.64e-01, 3.85e-01, 4.06e-01, 4.26e-01, 4.46e-01, /* --- lambda = 650.9 [nm] -- -------------- */ 1.56e-01, 1.88e-01, 2.18e-01, 2.47e-01, 2.76e-01, 3.03e-01, 3.31e-01, 3.57e-01, 3.84e-01, 4.10e-01, 4.36e-01, 4.62e-01, 4.87e-01, 5.12e-01, 5.37e-01, 5.62e-01, /* --- lambda = 759.4 [nm] -- -------------- */ 2.10e-01, 2.53e-01, 2.93e-01, 3.32e-01, 3.69e-01, 4.06e-01, 4.41e-01, 4.75e-01, 5.09e-01, 5.43e-01, 5.76e-01, 6.08e-01, 6.40e-01, 6.72e-01, 7.03e-01, 7.34e-01, /* --- lambda = 911.3 [nm] -- -------------- */ 2.98e-01, 3.59e-01, 4.16e-01, 4.70e-01, 5.22e-01, 5.73e-01, 6.21e-01, 6.68e-01, 7.15e-01, 7.60e-01, 8.04e-01, 8.47e-01, 8.90e-01, 9.32e-01, 9.73e-01, 1.01e+00, /* --- lambda = 1013.0 [nm] -- -------------- */ 3.65e-01, 4.39e-01, 5.09e-01, 5.75e-01, 6.39e-01, 7.00e-01, 7.58e-01, 8.15e-01, 8.71e-01, 9.25e-01, 9.77e-01, 1.03e+00, 1.08e+00, 1.13e+00, 1.18e+00, 1.23e+00, /* --- lambda = 1139.0 [nm] -- -------------- */ 4.58e-01, 5.50e-01, 6.37e-01, 7.21e-01, 8.00e-01, 8.76e-01, 9.49e-01, 1.02e+00, 1.09e+00, 1.15e+00, 1.22e+00, 1.28e+00, 1.34e+00, 1.40e+00, 1.46e+00, 1.52e+00, /* --- lambda = 1302.0 [nm] -- -------------- */ 5.92e-01, 7.11e-01, 8.24e-01, 9.31e-01, 1.03e+00, 1.13e+00, 1.23e+00, 1.32e+00, 1.40e+00, 1.49e+00, 1.57e+00, 1.65e+00, 1.73e+00, 1.80e+00, 1.88e+00, 1.95e+00, /* --- lambda = 1519.0 [nm] -- -------------- */ 7.98e-01, 9.58e-01, 1.11e+00, 1.25e+00, 1.39e+00, 1.52e+00, 1.65e+00, 1.77e+00, 1.89e+00, 2.00e+00, 2.11e+00, 2.21e+00, 2.32e+00, 2.42e+00, 2.51e+00, 2.61e+00, /* --- lambda = 1823.0 [nm] -- -------------- */ 1.14e+00, 1.36e+00, 1.58e+00, 1.78e+00, 1.98e+00, 2.17e+00, 2.34e+00, 2.52e+00, 2.68e+00, 2.84e+00, 3.00e+00, 3.15e+00, 3.29e+00, 3.43e+00, 3.57e+00, 3.70e+00, /* --- lambda = 2278.0 [nm] -- -------------- */ 1.77e+00, 2.11e+00, 2.44e+00, 2.75e+00, 3.05e+00, 3.34e+00, 3.62e+00, 3.89e+00, 4.14e+00, 4.39e+00, 4.63e+00, 4.86e+00, 5.08e+00, 5.30e+00, 5.51e+00, 5.71e+00, /* --- lambda = 3038.0 [nm] -- -------------- */ 3.10e+00, 3.71e+00, 4.29e+00, 4.84e+00, 5.37e+00, 5.87e+00, 6.36e+00, 6.83e+00, 7.28e+00, 7.72e+00, 8.14e+00, 8.55e+00, 8.95e+00, 9.33e+00, 9.71e+00, 1.01e+01, /* --- lambda = 4556.0 [nm] -- -------------- */ 6.92e+00, 8.27e+00, 9.56e+00, 1.08e+01, 1.19e+01, 1.31e+01, 1.42e+01, 1.52e+01, 1.62e+01, 1.72e+01, 1.82e+01, 1.91e+01, 2.00e+01, 2.09e+01, 2.17e+01, 2.25e+01, /* --- lambda = 9113.0 [nm] -- -------------- */ 2.75e+01, 3.29e+01, 3.80e+01, 4.28e+01, 4.75e+01, 5.19e+01, 5.62e+01, 6.04e+01, 6.45e+01, 6.84e+01, 7.23e+01, 7.60e+01, 7.97e+01, 8.32e+01, 8.67e+01, 9.01e+01 }; long Nspace = atmos.Nspace; double theta, pe, lambda_index, kappa; if (lambda == 0.0) { /* --- When called with zero wavelength free memory for fractional indices -- -------------- */ if (theta_index) free(theta_index); initialize = TRUE; return FALSE; } /* --- Use long-wavelength expansion if wavelength beyond 9113 nm - */ if (lambda >= lambdaFF[NFF-1]) return Hminus_ff_long(lambda, chi); if (initialize) { /* --- Store the fractional indices of temperature only the first time around -- -------------- */ theta_index = (double *) malloc(Nspace * sizeof(double)); for (k = 0; k < Nspace; k++) { theta = THETA0 / atmos.T[k]; if (theta <= thetaFF[0]) theta_index[k] = 0; else if (theta >= thetaFF[NTHETA-1]) theta_index[k] = NTHETA - 1; else { Hunt(NTHETA, thetaFF, theta, &index); theta_index[k] = (double) index + (theta - thetaFF[index]) / (thetaFF[index+1] - thetaFF[index]); } } initialize = FALSE; } Hunt(NFF, lambdaFF, lambda, &index); lambda_index = (double) index + (lambda - lambdaFF[index]) / (lambdaFF[index+1] - lambdaFF[index]); for (k = 0; k < Nspace; k++) { pe = atmos.ne[k] * KBOLTZMANN * atmos.T[k]; kappa = bilinear(NTHETA, NFF, kappaFF, theta_index[k], lambda_index); chi[k] = (atmos.H->n[0][k] * 1.0E-29) * pe * kappa; } return TRUE; }