static int convex_hull( /* compute polygon's convex hull */ RREAL vl[][2], int nv, RREAL vlo[][2] /* return value */ ) { int nvo, nvt; RREAL vlt[MAXVERT][2]; double voa, vta; register int i, j; /* start with original polygon */ for (i = nvo = nv; i--; ) { vlo[i][0] = vl[i][0]; vlo[i][1] = vl[i][1]; } voa = poly_area(vlo, nvo); /* compute its area */ for (i = 0; i < nvo; i++) { /* for each output vertex */ for (j = 0; j < i; j++) { vlt[j][0] = vlo[j][0]; vlt[j][1] = vlo[j][1]; } nvt = nvo - 1; /* make poly w/o vertex */ for (j = i; j < nvt; j++) { vlt[j][0] = vlo[j+1][0]; vlt[j][1] = vlo[j+1][1]; } vta = poly_area(vlt, nvt); if (vta >= voa) { /* is simpler poly bigger? */ voa = vta; /* then use it */ for (j = nvo = nvt; j--; ) { vlo[j][0] = vlt[j][0]; vlo[j][1] = vlt[j][1]; } i--; /* next adjust */ } } return(nvo); }
double FuselageXSec::computeArea() { vector< vec3d > pntVec; for ( int i = 0 ; i < num_pnts ; i++ ) { pntVec.push_back( pnts[i] ); } vec3d zero; return poly_area( pntVec, zero ); }
/* float compute_left_area(float * waves, float * cr, int maxi) { int i; float x_left[maxi+2], y_left[maxi+2]; for(i = 0; i <= maxi; i++) { x_left[i] = waves[i]; y_left[i] = cr[i]; } //add final vertex x_left[maxi+1] = waves[maxi]; y_left[maxi+1] = 1.0f; return poly_area(x_left, y_left, maxi+2); } */ float compute_right_area(float * waves, float * cr, int size, int maxi) { float max = get_max(cr, size); printf("max right area:%f\n", max); int i; float x_right [size-maxi+1], y_right[size-maxi+1]; x_right[0] = waves[maxi]; y_right[0] = max; for(i = 0; i < size-maxi; i++) { x_right[i+1] = waves[i+maxi]; y_right[i+1] = cr[i+maxi]; } return poly_area(x_right, y_right, size-maxi+1); }
float compute_left_area(float * waves, float * cr, int maxi) { float max = get_max(cr, maxi+1); printf("max left area:%f\n", max); int i; float x_left[maxi+2], y_left[maxi+2]; for(i = 0; i <= maxi; i++) { x_left[i] = waves[i]; y_left[i] = cr[i]; } //add final vertex x_left[maxi+1] = waves[maxi]; y_left[maxi+1] = max;//1.0f; return poly_area(x_left, y_left, maxi+2); }
char * process_feature ( float * spec, float * waves, float * cr, float * metrics, int size, int depth_norm) { int i, bdci; float m, q, bdc; float * y; y = (float*)malloc(size * sizeof(float)); if(!y) return "malloc failed"; m = (spec[size-1] - spec[0]) / (waves[size-1] - waves[0]); q = spec[0] - m * waves[0]; //compute point on the continuum for each wavelength for(i = 0; i < size; i++) { y[i] = m * waves[i] + q; if(spec[i] > y[i]) spec[i] = y[i]; } //compute continuum removal + flip for(i = 0; i < size; i++) { cr[i] = 1 - (spec[i] / y[i]); } //find bd center bdci = find_max(cr, size); bdc = cr[bdci]; // // either depth or area normalize the curve // if(depth_norm) { //normalize, flip, shift so curve is in [0,1] for(i = 0; i < size; i++) { cr[i] /= bdc; cr[i] = (cr[i]-1.0) * -1.0; } } else { float max = -1.0; float tot_area = poly_area(waves, cr, size); for(i = 0; i < size; i++) { cr[i] /= tot_area; if(cr[i] > max) { max = cr[i]; } } for(i = 0; i < size; i++) cr[i] = (cr[i] * -1.0) + max; } // // compute depth, area_left, area_right, and symmetry // int mini; float depth, area_left, area_right; mini = find_middle_min(spec, size); if(mini == -1) return "find_middle_min returned -1"; depth = 1.0 - spec[mini]/y[mini]; area_left = compute_left_area(waves, cr, bdci); area_right = compute_right_area(waves, cr, size, bdci); printf("mini:bdci => %d, %d\n", bdci, mini); free(y); metrics[0] = m; metrics[1] = q; metrics[2] = depth; metrics[3] = waves[mini]; metrics[4] = area_left + area_right; metrics[5] = area_left; metrics[6] = area_right; //tests /* printf("Test:\n%f,%f,%f,%f,%d,%dn", area_left, area_right, area_left + area_right, poly_area(waves, cr, size), bdci, mini); */ return NULL; }
void test_polygon__area_of_quad(void) { cl_assert(poly_area(quad) == 1.0); cl_assert(poly_area(quad) == poly_area(square) * 2); }
void test_polygon__triangle_area_is_correct_for_unit_square_triangle(void) { // One half base times height on a unit. Hardcore arithmetic. cl_assert(poly_triangle_area(square) == 0.5); cl_assert(poly_triangle_area(square) == poly_area(square)); }
extern void /* add sources smaller than rad to computed subimage */ drawsources( COLOR *pic[], /* subimage pixel value array */ float *zbf[], /* subimage distance array (opt.) */ int x0, /* origin and size of subimage */ int xsiz, int y0, int ysiz ) { RREAL spoly[MAXVERT][2], ppoly[MAXVERT][2]; int nsv, npv; int xmin, xmax, ymin, ymax, x, y; RREAL cxy[2]; double w; RAY sr; register SPLIST *sp; register int i; /* check each source in our list */ for (sp = sphead; sp != NULL; sp = sp->next) { /* clip source poly to subimage */ nsv = box_clip_poly(sp->vl, sp->nv, (double)x0/hres, (double)(x0+xsiz)/hres, (double)y0/vres, (double)(y0+ysiz)/vres, spoly); if (!nsv) continue; /* find common subimage (BBox) */ xmin = x0 + xsiz; xmax = x0; ymin = y0 + ysiz; ymax = y0; for (i = 0; i < nsv; i++) { if ((double)xmin/hres > spoly[i][0]) xmin = spoly[i][0]*hres + FTINY; if ((double)xmax/hres < spoly[i][0]) xmax = spoly[i][0]*hres - FTINY; if ((double)ymin/vres > spoly[i][1]) ymin = spoly[i][1]*vres + FTINY; if ((double)ymax/vres < spoly[i][1]) ymax = spoly[i][1]*vres - FTINY; } /* evaluate each pixel in BBox */ for (y = ymin; y <= ymax; y++) for (x = xmin; x <= xmax; x++) { /* subarea for pixel */ npv = box_clip_poly(spoly, nsv, (double)x/hres, (x+1.)/hres, (double)y/vres, (y+1.)/vres, ppoly); if (!npv) continue; /* no overlap */ convex_center(ppoly, npv, cxy); if ((sr.rmax = viewray(sr.rorg,sr.rdir,&ourview, cxy[0],cxy[1])) < -FTINY) continue; /* not in view */ if (source[sp->sn].sflags & SSPOT && spotout(&sr, source[sp->sn].sl.s)) continue; /* outside spot */ rayorigin(&sr, SHADOW, NULL, NULL); sr.rsrc = sp->sn; rayvalue(&sr); /* compute value */ if (bright(sr.rcol) <= FTINY) continue; /* missed/blocked */ /* modify pixel */ w = poly_area(ppoly, npv) * hres * vres; if (zbf[y-y0] != NULL && sr.rt < 0.99*zbf[y-y0][x-x0]) { zbf[y-y0][x-x0] = sr.rt; } else if (!bigdiff(sr.rcol, pic[y-y0][x-x0], 0.01)) { /* source sample */ scalecolor(pic[y-y0][x-x0], w); continue; } scalecolor(sr.rcol, w); scalecolor(pic[y-y0][x-x0], 1.-w); addcolor(pic[y-y0][x-x0], sr.rcol); } } }
/*********************************************************************** void create_grid_from_file( char *file, int *nlon, int *nlat, double *x, double *y, double *dx, double *dy, double *area, double *angle_dx ) the grid location is defined through ascii file. calculate cell length, cell area and rotation angle ************************************************************************/ void create_grid_from_file( char *file, int *nlon, int *nlat, double *x, double *y, double *dx, double *dy, double *area, double *angle_dx ) { double *xt, *yt, *xc, *yc; double p1[4], p2[4]; int nx, ny, nxp, nyp, ni, nj, i, j, n; int is_uniform; char mesg[256], txt[128]; /************************************************************ identify the grid_file is ascii file or netcdf file, if the file name contains ".nc", it is a netcdf file, otherwise it is ascii file. *********************************************************/ nx = *nlon; ny = *nlat; nxp = nx + 1; nyp = ny + 1; if(strstr(file, ".nc") ) { int fid, vid; ni = *nlon/2; nj = *nlat/2; xc = (double *)malloc((ni+1)*(nj+1)*sizeof(double)); yc = (double *)malloc((ni+1)*(nj+1)*sizeof(double)); xt = (double *)malloc( ni * nj *sizeof(double)); yt = (double *)malloc( ni * nj *sizeof(double)); fid = mpp_open(file, MPP_READ); if(mpp_dim_exist(fid, "grid_xt") ) get_grid_v1(fid, xt, yt, xc, yc); else if(mpp_dim_exist(fid, "rlon") || mpp_dim_exist(fid, "i") ) get_grid_v2(fid, ni, nj, xt, yt, xc, yc); else if(mpp_dim_exist(fid, "lon") ) get_grid_v3(fid, ni, nj, xt, yt, xc, yc); mpp_close(fid); for(j=0; j<nj+1; j++) for(i=0; i<ni+1; i++) { x[j*2*nxp+i*2] = xc[j*(ni+1)+i]; y[j*2*nxp+i*2] = yc[j*(ni+1)+i]; } for(j=0; j<nj; j++) for(i=0; i<ni; i++) { x[(j*2+1)*nxp+i*2+1] = xt[j*ni+i]; y[(j*2+1)*nxp+i*2+1] = yt[j*ni+i]; } /* check if the grid is uniform of not */ is_uniform = 1; for(j=0; j<nj; j++) { for(i=1; i<ni; i++) { if(yt[j*ni+i] != yt[j*ni]) is_uniform = 0; } } for(i=0; i<ni; i++) { for(j=1; j<nj; j++) { if(xt[j*ni+i] != xt[i]) is_uniform = 0; } } if(is_uniform) { for(j=0; j<nj+1; j++) for(i=0; i<ni; i++) { x[j*2*nxp+i*2+1] = xt[i]; y[j*2*nxp+i*2+1] = yc[j*(ni+1)+i]; } for(j=0; j<nj; j++) for(i=0; i<ni+1; i++) { x[(j*2+1)*nxp+i*2] = xc[j*(ni+1)+i]; y[(j*2+1)*nxp+i*2] = yt[j*ni]; } } else { for(j=0; j<nj+1; j++) for(i=0; i<ni; i++) { x[j*2*nxp+i*2+1] = (xc[j*(ni+1)+i]+xc[j*(ni+1)+i+1])*0.5; y[j*2*nxp+i*2+1] = (yc[j*(ni+1)+i]+yc[j*(ni+1)+i+1])*0.5; } for(j=0; j<nj; j++) for(i=0; i<ni+1; i++) { x[(j*2+1)*nxp+i*2] = (xc[j*(ni+1)+i]+xc[(j+1)*(ni+1)+i])*0.5; y[(j*2+1)*nxp+i*2] = (yc[j*(ni+1)+i]+yc[(j+1)*(ni+1)+i])*0.5; } } for(j=0; j<nyp; j++) for(i=0; i<nx; i++) { p1[0] = x[j*nxp+i]*D2R; p2[0] = x[j*nxp+i+1]*D2R; p1[1] = y[j*nxp+i]*D2R; p2[1] = y[j*nxp+i+1]*D2R; dx[j*nx+i] = great_circle_distance(p1, p2); } for(j=0; j<ny; j++) for(i=0; i<nxp; i++) { p1[0] = x[j*nxp+i]*D2R; p2[0] = x[(j+1)*nxp+i]*D2R; p1[1] = y[j*nxp+i]*D2R; p2[1] = y[(j+1)*nxp+i]*D2R; dy[j*nxp+i] = great_circle_distance(p1, p2); } for(j=0; j<ny; j++) for(i=0; i<nx; i++) { p1[0] = x[j*nxp+i]*D2R; p1[1] = x[j*nxp+i+1]*D2R; p1[2] = x[(j+1)*nxp+i+1]*D2R; p1[3] = x[(j+1)*nxp+i]*D2R; p2[0] = y[j*nxp+i]*D2R; p2[1] = y[j*nxp+i+1]*D2R; p2[2] = y[(j+1)*nxp+i+1]*D2R; p2[3] = y[(j+1)*nxp+i]*D2R; area[j*nx+i] = poly_area(p1, p2, 4); } /* currently set angle to 0 */ for(j=0; j<nyp; j++) for(i=0; i<nxp; i++) angle_dx[j*nxp+i] = 0; free(xt); free(yt); free(xc); free(yc); } else { create_grid_from_text_file(file, nlon, nlat, x, y, dx, dy, area, angle_dx ); } }; /* create_grid_from_file */
/*********************************************************************** void create_grid_from_file( char *file, int *nlon, int *nlat, double *x, double *y, double *dx, double *dy, double *area, double *angle_dx ) the grid location is defined through ascii file. calculate cell length, cell area and rotation angle ************************************************************************/ void create_grid_from_file( char *file, int *nlon, int *nlat, double *x, double *y, double *dx, double *dy, double *area, double *angle_dx ) { double *xb, *yb, *xt, *yt, *xc, *yc; double p1[4], p2[4]; int nx, ny, nxp, nyp, ni, nj, i, j, n; FILE *pFile; char mesg[256], txt[128]; /************************************************************ identify the grid_file is ascii file or netcdf file, if the file name contains ".nc", it is a netcdf file, otherwise it is ascii file. *********************************************************/ nx = *nlon; ny = *nlat; nxp = nx + 1; nyp = ny + 1; if(strstr(file, ".nc") ) { int fid, vid; ni = *nlon/2; nj = *nlat/2; xc = (double *)malloc((ni+1)*(nj+1)*sizeof(double)); yc = (double *)malloc((ni+1)*(nj+1)*sizeof(double)); xt = (double *)malloc( ni * nj *sizeof(double)); yt = (double *)malloc( ni * nj *sizeof(double)); fid = mpp_open(file, MPP_READ); vid = mpp_get_varid(fid, "grid_lon"); mpp_get_var_value(fid, vid, xc); vid = mpp_get_varid(fid, "grid_lat"); mpp_get_var_value(fid, vid, yc); vid = mpp_get_varid(fid, "grid_lont"); mpp_get_var_value(fid, vid, xt); vid = mpp_get_varid(fid, "grid_latt"); mpp_get_var_value(fid, vid, yt); mpp_close(fid); for(j=0; j<nj+1; j++) for(i=0; i<ni+1; i++) { x[j*2*nxp+i*2] = xc[j*(ni+1)+i]; y[j*2*nxp+i*2] = yc[j*(ni+1)+i]; } for(j=0; j<nj; j++) for(i=0; i<ni; i++) { x[(j*2+1)*nxp+i*2+1] = xt[j*ni+i]; y[(j*2+1)*nxp+i*2+1] = yt[j*ni+i]; } for(j=0; j<nj+1; j++) for(i=0; i<ni; i++) { x[j*2*nxp+i*2+1] = (xc[j*(ni+1)+i]+xc[j*(ni+1)+i+1])*0.5; y[j*2*nxp+i*2+1] = (yc[j*(ni+1)+i]+yc[j*(ni+1)+i+1])*0.5; } for(j=0; j<nj; j++) for(i=0; i<ni+1; i++) { x[(j*2+1)*nxp+i*2] = (xc[j*(ni+1)+i]+xc[(j+1)*(ni+1)+i])*0.5; y[(j*2+1)*nxp+i*2] = (yc[j*(ni+1)+i]+yc[(j+1)*(ni+1)+i])*0.5; } for(j=0; j<nyp; j++) for(i=0; i<nx; i++) { p1[0] = x[j*nxp+i]; p2[0] = x[j*nxp+i+1]; p1[1] = y[j*nxp+i]; p2[1] = y[j*nxp+i+1]; dx[j*nx+i] = great_circle_distance(p1, p2); } for(j=0; j<ny; j++) for(i=0; i<nxp; i++) { p1[0] = x[j*nxp+i]; p2[0] = x[(j+1)*nxp+i]; p1[1] = y[j*nxp+i]; p2[1] = y[(j+1)*nxp+i]; dy[j*nxp+i] = great_circle_distance(p1, p2); } for(j=0; j<ny; j++) for(i=0; i<nx; i++) { p1[0] = x[j*nxp+i]; p1[1] = x[j*nxp+i+1]; p1[2] = x[(j+1)*nxp+i+1]; p1[3] = x[(j+1)*nxp+i]; p2[0] = y[j*nxp+i]; p2[1] = y[j*nxp+i+1]; p2[2] = y[(j+1)*nxp+i+1]; p2[3] = y[(j+1)*nxp+i]; area[j*nx+i] = poly_area(p1, p2, 4); } /* currently set angle to 0 */ for(j=0; j<nyp; j++) for(i=0; i<nxp; i++) angle_dx[j*nxp+i] = 0; free(xt); free(yt); free(xc); free(yc); } else { pFile = fopen (file,"r"); if(!pFile) { strcpy(mesg, "RegularSphericalGrid: Can not open ascii file "); strcat(mesg,file); mpp_error(mesg); } fscanf(pFile, "%s%*[^\n]",txt); /* header line (ignored) */ xb = (double *) malloc(nxp*sizeof(double)); yb = (double *) malloc(nyp*sizeof(double)); for(i=0;i<nxp;i++) fscanf(pFile, "%lg", xb+i); /* longitude */ fscanf(pFile, "%s%*[^\n]",txt); /* header line (ignored) */ for(j=0;j<nyp;j++) fscanf(pFile, "%lg", yb+j); /* latitude */ fclose(pFile); n=0; for(j=0; j<nyp; j++) { for(i=0; i<nxp; i++) { x[n] = xb[i]; y[n] = yb[j]; angle_dx[n++] = 0; } } /* zonal length */ n = 0; for(j=0; j<nyp; j++) { for(i=0; i<nx; i++ ) { dx[n++] = spherical_dist(x[j*nxp+i], y[j*nxp+i], x[j*nxp+i+1], y[j*nxp+i+1] ); } } /* meridinal length */ n = 0; for(j=0; j<ny; j++) { for(i=0; i<nxp; i++ ) { dy[n++] = spherical_dist(x[j*nxp+i], y[j*nxp+i], x[(j+1)*nxp+i], y[(j+1)*nxp+i] ); } } /* cell area */ n = 0; for(j=0; j<ny; j++) { for(i=0; i<nx; i++ ) { area[n++] = box_area(x[j*nxp+i]*D2R, y[j*nxp+i]*D2R, x[(j+1)*nxp+i+1]*D2R, y[(j+1)*nxp+i+1]*D2R ); } } free(xb); free(yb); } }; /* create_grid_from_file */