static void compute_extents (pixman_f_transform_t *trans, double *sx, double *sy) { double min_x, max_x, min_y, max_y; pixman_f_vector_t v[4] = { { { 1, 1, 1 } }, { { -1, 1, 1 } }, { { -1, -1, 1 } }, { { 1, -1, 1 } }, }; pixman_f_transform_point (trans, &v[0]); pixman_f_transform_point (trans, &v[1]); pixman_f_transform_point (trans, &v[2]); pixman_f_transform_point (trans, &v[3]); min_x = min4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]); max_x = max4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]); min_y = min4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]); max_y = max4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]); *sx = (max_x - min_x) / 2.0; *sy = (max_y - min_y) / 2.0; }
// _TrackMouse void TestView::_TrackMouse(BPoint where) { BRect before; BRect after; bool invalidate = false; switch (fTracking) { case TRACKING_SOURCE: before = fSourceRect; fSourceRect.right = where.x; fSourceRect.bottom = where.y; after = fSourceRect; invalidate = true; break; case TRACKING_DEST: before = fDestRect; fDestRect.right = where.x; fDestRect.bottom = where.y; after = fDestRect; invalidate = true; break; } if (invalidate) { BRect dirty(min4(before.left, before.right, after.left, after.right), min4(before.top, before.bottom, after.top, after.bottom), max4(before.left, before.right, after.left, after.right), max4(before.top, before.bottom, after.top, after.bottom)); Invalidate(dirty); } }
void FloatRect::fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3) { float left = min4(p0.x(), p1.x(), p2.x(), p3.x()); float top = min4(p0.y(), p1.y(), p2.y(), p3.y()); float right = max4(p0.x(), p1.x(), p2.x(), p3.x()); float bottom = max4(p0.y(), p1.y(), p2.y(), p3.y()); setLocationAndSizeFromEdges(left, top, right, bottom); }
FloatRect FloatQuad::boundingBox() const { float left = min4(m_p1.x(), m_p2.x(), m_p3.x(), m_p4.x()); float top = min4(m_p1.y(), m_p2.y(), m_p3.y(), m_p4.y()); float right = max4(m_p1.x(), m_p2.x(), m_p3.x(), m_p4.x()); float bottom = max4(m_p1.y(), m_p2.y(), m_p3.y(), m_p4.y()); return FloatRect(left, top, right - left, bottom - top); }
static void icvCalcFMM(const CvMat *f, CvMat *t, CvPriorityQueueFloat *Heap, bool negate) { int i, j, ii = 0, jj = 0, q; float dist; while (Heap->Pop(&ii,&jj)) { unsigned known=(negate)?CHANGE:KNOWN; CV_MAT_ELEM(*f,uchar,ii,jj) = (uchar)known; for (q=0; q<4; q++) { i=0; j=0; if (q==0) {i=ii-1; j=jj;} else if(q==1) {i=ii; j=jj-1;} else if(q==2) {i=ii+1; j=jj;} else {i=ii; j=jj+1;} if ((i<=0)||(j<=0)||(i>f->rows)||(j>f->cols)) continue; if (CV_MAT_ELEM(*f,uchar,i,j)==INSIDE) { dist = min4(FastMarching_solve(i-1,j,i,j-1,f,t), FastMarching_solve(i+1,j,i,j-1,f,t), FastMarching_solve(i-1,j,i,j+1,f,t), FastMarching_solve(i+1,j,i,j+1,f,t)); CV_MAT_ELEM(*t,float,i,j) = dist; CV_MAT_ELEM(*f,uchar,i,j) = BAND; Heap->Push(i,j,dist); } } }
static inline double contrast(double a, double b, double c, double d) { const double min = min4(a, b, c, d); const double max = max4(a, b, c, d); return (max - min) / (max + min); }
int damerauLevenshtein(const char *s, const char *t) { int i, j, distance, cost; int n = strlen(s); int m = strlen(t); int INF = n + m; int *d = malloc((sizeof(int))*(n+2)*(m+2)); d[0] = INF; for(i = 0; i <= n; i++) { d[((n+2)*1) + i+1] = i; d[((n+2)*0) + i+1] = INF; } for(j = 0; j <= m; j++) { d[((n+2)*(j+1)) + 1] = j; d[((n+2)*(j+1)) + 0] = INF; } int DS[256]; for(i = 0; i < sizeof(char)*256; i++) { DS[i] = 0; } for(i = 1; i <= n; i++) { int DT = 0; for(j = 1; j <= m; j++) { int tj = (unsigned char)t[j-1]; int i1 = DS[tj]; int j1 = DT; int diff = s[i-1] - t[j-1]; if (diff == 0){ cost = 0; DT = j; } else cost = 1; int substitution = d[((n+2)*j) + i] + cost; int insertion = d[((n+2)*j) + i+1] + 1; int deletion = d[((n+2)*(j+1)) + i] + 1; int transposition = d[((n+2)*j1) + i1] + (i-i1-1) + 1 + (j-j1-1); d[((n+2)*(j+1)) + i+1] = min4( substitution, insertion, deletion, transposition); } int si = (unsigned char)s[i-1]; DS[si] = i; } distance = d[((n+2)*(m+1)) + (n+1)]; free(d); return distance; }
int _tmain(int argc, _TCHAR* argv[]) { printf("Avg: %i\n", int_avg(4, 5, 6)); printf("Avg: %i\n", short_avg(4, 5, 6)); printf("Sgn: %i\n", sgn(-1)); printf("Max2: %i\n", max2(8, 6)); printf("Max3: %i\n", max3(3, 5, 1)); printf("Kladne: %i\n", kladne(3, 5, 0)); printf("Min4: %i\n", min4(-2, 3, 4, 5)); system("PAUSE"); return 0; }
// _ControlPointRect BRect PathManipulator::_ControlPointRect(int32 index, uint32 mode) const { BRect rect(0.0, 0.0, -1.0, -1.0); if (index >= 0) { BPoint p, pIn, pOut; fPath->GetPointsAt(index, p, pIn, pOut); switch (mode) { case MOVE_POINT: case TOGGLE_SHARP: case REMOVE_POINT: case CLOSE_PATH: rect.Set(p.x, p.y, p.x, p.y); rect.InsetBy(-POINT_EXTEND, -POINT_EXTEND); break; case MOVE_POINT_IN: case TOGGLE_SHARP_IN: case REMOVE_POINT_IN: rect.Set(pIn.x, pIn.y, pIn.x, pIn.y); rect.InsetBy(-CONTROL_POINT_EXTEND, -CONTROL_POINT_EXTEND); break; case MOVE_POINT_OUT: case TOGGLE_SHARP_OUT: case REMOVE_POINT_OUT: rect.Set(pOut.x, pOut.y, pOut.x, pOut.y); rect.InsetBy(-CONTROL_POINT_EXTEND, -CONTROL_POINT_EXTEND); break; case SELECT_POINTS: rect.Set(min4(p.x, pIn.x, pOut.x, pOut.x), min4(p.y, pIn.y, pOut.y, pOut.y), max4(p.x, pIn.x, pOut.x, pOut.x), max4(p.y, pIn.y, pOut.y, pOut.y)); rect.InsetBy(-POINT_EXTEND, -POINT_EXTEND); break; } } return rect; }
int compute(int n) { int i; cost[n-1][0]+=cost[n-1][1]; cost[n-2][2]+=cost[n-1][1]; cost[n-2][1]+=min3(cost[n-1][1],cost[n-1][0],cost[n-2][2]); cost[n-2][0]+=min3(cost[n-1][1],cost[n-1][0],cost[n-2][1]); for(i=n-3; i>=0; i--) { cost[i][2]+=min2(cost[i+1][1],cost[i+1][2]); cost[i][1]+=min4(cost[i+1][0],cost[i+1][1],cost[i+1][2],cost[i][2]); cost[i][0]+=min3(cost[i+1][0],cost[i+1][1],cost[i][1]); } return cost[0][1]; }
/* Notes: * [1] Whether or not a block is planned is controlled by the bf->replannable * setting (set TRUE if it should be). Replan flags are checked during the * backwards pass and prune the replan list to include only the the latest * blocks that require planning * * In normal operation the first block (currently running block) is not * replanned, but may be for feedholds and feed overrides. In these cases * the prep routines modify the contents of the mr buffer and re-shuffle * the block list, re-enlisting the current bf buffer with new parameters. * These routines also set all blocks in the list to be replannable so the * list can be recomputed regardless of exact stops and previous replanning * optimizations. * * [2] The mr_flag is used to tell replan to account for mr buffer's exit velocity (Vx) * mr's Vx is always found in the provided bf buffer. Used to replan feedholds */ static void _plan_block_list(mpBuf_t *bf, uint8_t *mr_flag) { mpBuf_t *bp = bf; // Backward planning pass. Find first block and update the braking velocities. // At the end *bp points to the buffer before the first block. while ((bp = mp_get_prev_buffer(bp)) != bf) { if (bp->replannable == false) { break; } bp->braking_velocity = min(bp->nx->entry_vmax, bp->nx->braking_velocity) + bp->delta_vmax; } // forward planning pass - recomputes trapezoids in the list from the first block to the bf block. while ((bp = mp_get_next_buffer(bp)) != bf) { if ((bp->pv == bf) || (*mr_flag == true)) { bp->entry_velocity = bp->entry_vmax; // first block in the list *mr_flag = false; } else { bp->entry_velocity = bp->pv->exit_velocity; // other blocks in the list } bp->cruise_velocity = bp->cruise_vmax; bp->exit_velocity = min4( bp->exit_vmax, bp->nx->entry_vmax, bp->nx->braking_velocity, (bp->entry_velocity + bp->delta_vmax) ); mp_calculate_trapezoid(bp); // test for optimally planned trapezoids - only need to check various exit conditions if ( ( (fp_EQ(bp->exit_velocity, bp->exit_vmax)) || (fp_EQ(bp->exit_velocity, bp->nx->entry_vmax)) ) || ( (bp->pv->replannable == false) && (fp_EQ(bp->exit_velocity, (bp->entry_velocity + bp->delta_vmax))) ) ) { bp->replannable = false; } } // finish up the last block move bp->entry_velocity = bp->pv->exit_velocity; bp->cruise_velocity = bp->cruise_vmax; bp->exit_velocity = 0; mp_calculate_trapezoid(bp); }
int main(){ char str[501]; int t,R,C,i,j,k,ans; for(i=2;i<=23;i++){ if(prime[i]==0) for(j=i*i;j<=500;j+=i){ prime[j]=1; } } scanf("%d",&t); while(t--){ ans=0; scanf("%d%d",&R,&C); for(i=1;i<=R;i++){ scanf("%s",str); for(j=0;j<C;j++){ if(str[j]=='^') val[i][j+1]=1; else val[i][j+1]=0; } } k=min2(R,C); if(k<=4){ printf("0\n"); continue; } setzero(left,R,C); setzero(right,R,C); setzero(up,R,C); setzero(bottom,R,C); for(i=2;i<R;i++){ for(j=1;j<C;j++){ if(val[i][j]==1) left[i][j+1]=left[i][j]+1; } } for(i=2;i<R;i++){ for(j=C;j>=2;j--){ if(val[i][j]==1) right[i][j-1]=right[i][j]+1; } } for(j=2;j<C;j++){ for(i=1;i<R;i++){ if(val[i][j]==1) up[i+1][j]=up[i][j]+1; } } // set bottom for(j=2;j<C;j++){ for(i=R;i>1;i--){ if(val[i][j]==1) bottom[i-1][j]=bottom[i][j]+1; } } for(i=2;i<=R-2;i++){ for(j=2;j<=C-2;j++){ if(val[i][j]==1){ k=min4(up[i][j],right[i][j],left[i][j],bottom[i][j]); ans+=cprime[k]; } } } printf("%d\n",ans); } return 0; }
// _DragStateFor //! where is expected in canvas view coordinates DragState* TransformBox::_DragStateFor(BPoint where, float canvasZoom) { DragState* state = NULL; // convert to canvas zoom level // // the conversion is necessary, because the "hot regions" // around a point should be the same size no matter what // zoom level the canvas is displayed at float inset = INSET / canvasZoom; // priorities: // transformation center point has highest priority ?!? if (point_point_distance(where, fPivot) < inset) state = fOffsetCenterState; if (!state) { // next, the inner area of the box // for the following calculations // we can apply the inverse transformation to all points // this way we have to consider BRects only, not transformed polygons BPoint lt = fLeftTop; BPoint rb = fRightBottom; BPoint w = where; InverseTransform(&w); InverseTransform(<); InverseTransform(&rb); // next priority has the inside of the box BRect iR(lt, rb); float hInset = min_c(inset, max_c(0, (iR.Width() - inset) / 2.0)); float vInset = min_c(inset, max_c(0, (iR.Height() - inset) / 2.0)); iR.InsetBy(hInset, vInset); if (iR.Contains(w)) state = fTranslateState; } if (!state) { // next priority have the corners float dLT = point_point_distance(fLeftTop, where); float dRT = point_point_distance(fRightTop, where); float dLB = point_point_distance(fLeftBottom, where); float dRB = point_point_distance(fRightBottom, where); float d = min4(dLT, dRT, dLB, dRB); if (d < inset) { if (d == dLT) state = fDragLTState; else if (d == dRT) state = fDragRTState; else if (d == dLB) state = fDragLBState; else if (d == dRB) state = fDragRBState; } } if (!state) { // next priority have the sides float dL = point_line_dist(fLeftTop, fLeftBottom, where, inset); float dR = point_line_dist(fRightTop, fRightBottom, where, inset); float dT = point_line_dist(fLeftTop, fRightTop, where, inset); float dB = point_line_dist(fLeftBottom, fRightBottom, where, inset); float d = min4(dL, dR, dT, dB); if (d < inset) { if (d == dL) state = fDragLState; else if (d == dR) state = fDragRState; else if (d == dT) state = fDragTState; else if (d == dB) state = fDragBState; } } if (!state) { BPoint lt = fLeftTop; BPoint rb = fRightBottom; BPoint w = where; InverseTransform(&w); InverseTransform(<); InverseTransform(&rb); // check inside of the box again BRect iR(lt, rb); if (iR.Contains(w)) { state = fTranslateState; } else { // last priority has the rotate state state = fRotateState; } } return state; }
Intervall operator*(Intervall a, Intervall b){ return Intervall(min4(a.inf*b.inf,a.inf*b.sup,a.sup*b.inf,a.sup*b.sup),max4(a.inf*b.inf,a.inf*b.sup,a.sup*b.inf,a.sup*b.sup)); }
vector<squares::pair> squares::bound_box_detect() { vector<pair> collision_susp; priority_queue<points,vector<points>,points_compare_x> posi_x; vector<points> boundbox_info; for(int i=0;i<position.size();i++) { points sq; sq.posi_x=max4(position[i].pos[0].x,position[i].pos[1].x,position[i].pos[2].x, position[i].pos[3].x)+dynamics[i].x.x; sq.posi_y=max4(position[i].pos[0].y,position[i].pos[1].y,position[i].pos[2].y, position[i].pos[3].y)+dynamics[i].x.y; sq.square_no=i; sq.end=true; posi_x.push(sq); boundbox_info.push_back(sq); sq.posi_x=min4(position[i].pos[0].x,position[i].pos[1].x,position[i].pos[2].x, position[i].pos[3].x)+dynamics[i].x.x; sq.posi_y=min4(position[i].pos[0].y,position[i].pos[1].y,position[i].pos[2].y, position[i].pos[3].y)+dynamics[i].x.y; sq.square_no=i; sq.end=false; posi_x.push(sq); boundbox_info.push_back(sq); } list<int> conflict_list; list<int>::iterator conflict_list_itr=conflict_list.begin(); priority_queue<points,vector<points>,points_compare_x> posi_y; while(posi_x.size()) { if(posi_x.top().end==false) conflict_list.push_back(posi_x.top().square_no); if(posi_x.top().end==true) { conflict_list_itr=conflict_list.begin(); for(int i=0;i<conflict_list.size();i++) { posi_y.push(boundbox_info[*conflict_list_itr*2]); posi_y.push(boundbox_info[*conflict_list_itr*2+1]); conflict_list_itr++; } list<int> conflict_list_y; list<int>::iterator conflict_list_y_itr=conflict_list_y.begin(); pair pair_temp(posi_x.top().square_no,0); while(posi_y.size()) { if(posi_y.top().end==false) conflict_list_y.push_back(posi_y.top().square_no); if(posi_y.top().end==true) { conflict_list_y.push_back(posi_y.top().square_no); while(conflict_list_y_itr!=conflict_list_y.end()) { pair_temp.b=*conflict_list_y_itr; collision_susp.push_back(pair_temp); conflict_list_y_itr++; } } posi_y.pop(); } conflict_list_itr=conflict_list.begin(); conflict_list.remove(posi_x.top().square_no); } posi_x.pop(); } return collision_susp; }
BYTE ExploredMask::make_mask_id( int xLoc, int yLoc ) { BYTE retMaskId = 0; err_when( xLoc < 0 || yLoc < 0 || xLoc >= MAX_WORLD_X_LOC || yLoc >= MAX_WORLD_Y_LOC ); BYTE cVisitLevel; BYTE nwMin, neMin, swMin, seMin; Location *cLocPtr; cVisitLevel = (cLocPtr = world.get_loc( xLoc, yLoc ))->visit_level; if( yLoc <= 0 ) { Location *sLocPtr = world.get_loc( xLoc, yLoc+1); BYTE sVisitLevel = sLocPtr->visit_level; if( xLoc <= 0 ) { BYTE eVisitLevel = (cLocPtr+1)->visit_level; BYTE seVisitLevel = (sLocPtr+1)->visit_level; nwMin = cVisitLevel; neMin = min(cVisitLevel, eVisitLevel ); swMin = min(cVisitLevel, sVisitLevel ); seMin = min4(cVisitLevel, seVisitLevel, sVisitLevel, eVisitLevel); } else if( xLoc >= MAX_WORLD_X_LOC-1 ) { BYTE wVisitLevel = (cLocPtr-1)->visit_level; BYTE swVisitLevel = (sLocPtr-1)->visit_level; nwMin = min( cVisitLevel, wVisitLevel ); neMin = cVisitLevel; swMin = min4( cVisitLevel, swVisitLevel, sVisitLevel, wVisitLevel ); seMin = min( cVisitLevel, sVisitLevel ); } else { BYTE wVisitLevel = (cLocPtr-1)->visit_level; BYTE eVisitLevel = (cLocPtr+1)->visit_level; BYTE swVisitLevel = (sLocPtr-1)->visit_level; BYTE seVisitLevel = (sLocPtr+1)->visit_level; nwMin = min( cVisitLevel, wVisitLevel ); neMin = min( cVisitLevel, eVisitLevel ); swMin = min4( cVisitLevel, swVisitLevel, sVisitLevel, wVisitLevel ); seMin = min4(cVisitLevel, seVisitLevel, sVisitLevel, eVisitLevel); } } else if( yLoc >= MAX_WORLD_Y_LOC-1 ) { Location *nLocPtr = world.get_loc( xLoc, yLoc-1); BYTE nVisitLevel = nLocPtr->visit_level; if( xLoc <= 0 ) { BYTE neVisitLevel = (nLocPtr+1)->visit_level; BYTE eVisitLevel = (cLocPtr+1)->visit_level; nwMin = min( cVisitLevel, nVisitLevel ); neMin = min4( cVisitLevel, neVisitLevel, nVisitLevel, eVisitLevel ); swMin = cVisitLevel; seMin = min( cVisitLevel, eVisitLevel ); } else if( xLoc >= MAX_WORLD_X_LOC-1 ) { BYTE nwVisitLevel = (nLocPtr-1)->visit_level; BYTE wVisitLevel = (cLocPtr-1)->visit_level; nwMin = min4( cVisitLevel, nwVisitLevel, nVisitLevel, wVisitLevel ); neMin = min( cVisitLevel, nVisitLevel ); swMin = min( cVisitLevel, wVisitLevel ); seMin = cVisitLevel; } else { BYTE nwVisitLevel = (nLocPtr-1)->visit_level; BYTE neVisitLevel = (nLocPtr+1)->visit_level; BYTE wVisitLevel = (cLocPtr-1)->visit_level; BYTE eVisitLevel = (cLocPtr+1)->visit_level; nwMin = min4( cVisitLevel, nwVisitLevel, nVisitLevel, wVisitLevel ); neMin = min4( cVisitLevel, neVisitLevel, nVisitLevel, eVisitLevel); swMin = min( cVisitLevel, wVisitLevel ); seMin = min( cVisitLevel, eVisitLevel ); } } else { Location *nLocPtr = world.get_loc( xLoc, yLoc-1); Location *sLocPtr = world.get_loc( xLoc, yLoc+1); BYTE nVisitLevel = nLocPtr->visit_level; BYTE sVisitLevel = sLocPtr->visit_level; if( xLoc <= 0 ) { BYTE neVisitLevel = (nLocPtr+1)->visit_level; BYTE eVisitLevel = (cLocPtr+1)->visit_level; BYTE seVisitLevel = (sLocPtr+1)->visit_level; nwMin = min( cVisitLevel, nVisitLevel ); neMin = min4( cVisitLevel, neVisitLevel, nVisitLevel, eVisitLevel ); swMin = min( cVisitLevel, sVisitLevel ); seMin = min4( cVisitLevel, seVisitLevel, sVisitLevel, eVisitLevel ); } else if( xLoc >= MAX_WORLD_X_LOC-1 ) { BYTE nwVisitLevel = (nLocPtr-1)->visit_level; BYTE wVisitLevel = (cLocPtr-1)->visit_level; BYTE swVisitLevel = (sLocPtr-1)->visit_level; nwMin = min4( cVisitLevel, nwVisitLevel, nVisitLevel, wVisitLevel ); neMin = min( cVisitLevel, nVisitLevel ); swMin = min4( cVisitLevel, swVisitLevel, sVisitLevel, wVisitLevel ); seMin = min( cVisitLevel, sVisitLevel ); } else { BYTE nwVisitLevel = (nLocPtr-1)->visit_level; BYTE neVisitLevel = (nLocPtr+1)->visit_level; BYTE wVisitLevel = (cLocPtr-1)->visit_level; BYTE eVisitLevel = (cLocPtr+1)->visit_level; BYTE swVisitLevel = (sLocPtr-1)->visit_level; BYTE seVisitLevel = (sLocPtr+1)->visit_level; nwMin = min4( cVisitLevel, nwVisitLevel, nVisitLevel, wVisitLevel ); neMin = min4( cVisitLevel, neVisitLevel, nVisitLevel, eVisitLevel ); swMin = min4( cVisitLevel, swVisitLevel, sVisitLevel, wVisitLevel ); seMin = min4( cVisitLevel, seVisitLevel, sVisitLevel, eVisitLevel ); } } if( nwMin >= EXPLORED_VISIBILITY ) { if( config.fog_of_war && nwMin < FULL_VISIBILITY-FRAMES_PER_DAY-1 ) retMaskId |= 1; // fog else retMaskId |= 2; // fully explored } if( neMin >= EXPLORED_VISIBILITY ) { if( config.fog_of_war && neMin < FULL_VISIBILITY-FRAMES_PER_DAY-1 ) retMaskId |= 1 << 2; // fog else retMaskId |= 2 << 2; // fully explored } if( swMin >= EXPLORED_VISIBILITY ) { if( config.fog_of_war && swMin < FULL_VISIBILITY-FRAMES_PER_DAY-1 ) retMaskId |= 1 << 4; // fog else retMaskId |= 2 << 4; // fully explored } if( seMin >= EXPLORED_VISIBILITY ) { if( config.fog_of_war && seMin < FULL_VISIBILITY-FRAMES_PER_DAY-1 ) retMaskId |= 1 << 6; // fog else retMaskId |= 2 << 6; // fully explored } return retMaskId; }
static int proj_to_sr(const char *infile, const char *outfile, double pixel_size) { int ii, jj, kk; const float_image_sample_method_t sampling_method = FLOAT_IMAGE_SAMPLE_METHOD_BILINEAR; // overall algorithm: // 1. find extents in time/slant space // 2. for each pixel in output, resample in input space meta_parameters *inMeta = meta_read(infile); int nl = inMeta->general->line_count; int ns = inMeta->general->sample_count; if (!inMeta->projection && !inMeta->transform) asfPrintError("Expected a projection/transform block!\n"); if (!inMeta->state_vectors) asfPrintError("Input data does not have state vectors!\n"); //asfPrintStatus("Converting %s to slant range...\n", infile); // first, find extents in time/slant space // do this by projecting image corners to time/slant int tl_x=0, tl_y=0; int tr_x=ns-1, tr_y=0; int bl_x=0, bl_y=nl-1; int br_x=ns-1, br_y=nl-1; // we have to find the "real" corners of the image // do this using the first band of the input image as a reference if (inMeta->general->band_count == 1) asfPrintStatus("Tiling the input image...\n"); else asfPrintStatus("Tiling the reference band of the input image...\n"); FloatImage *in = float_image_new_from_metadata(inMeta, infile); // find top left pixel -- TOP-most non-no-data pixel in the image for (ii=0; ii<nl; ++ii) for (jj=0; jj<ns; ++jj) { double val = float_image_get_pixel(in, jj, ii); if (val != inMeta->general->no_data && val != 0.0) { tl_x = jj; tl_y = ii; goto found_tl; } } asfPrintError("Couldn't find top-left pixel! Entire image no data?\n"); found_tl: // find top right pixel -- RIGHT-most non-no-data pixel in the image for (jj=ns-1; jj>=0; --jj) for (ii=0; ii<nl; ++ii) { double val = float_image_get_pixel(in, jj, ii); if (val != inMeta->general->no_data && val != 0.0) { tr_x = jj; tr_y = ii; goto found_tr; } } asfPrintError("Couldn't find top-right pixel! Entire image no data?\n"); found_tr: // find bottom left pixel -- LEFT-most non-no-data pixel in the image for (jj=0; jj<ns; ++jj) for (ii=nl-1; ii>=0; --ii) { double val = float_image_get_pixel(in, jj, ii); if (val != inMeta->general->no_data && val != 0.0) { bl_x = jj; bl_y = ii; goto found_bl; } } asfPrintError("Couldn't find bottom-left pixel! Entire image no data?\n"); found_bl: // find bottom right pixel -- BOTTOM-most non-no-data pixel in the image for (ii=nl-1; ii>=0; --ii) for (jj=ns-1; jj>=0; --jj) { double val = float_image_get_pixel(in, jj, ii); if (val != inMeta->general->no_data && val != 0.0) { br_x = jj; br_y = ii; goto found_br; } } asfPrintError("Couldn't find bottom-right pixel! Entire image no data?\n"); found_br: asfPrintStatus("Determining image extents in time/slant coordinates.\n"); //asfPrintStatus("Corners are at: TL (%d,%d)\n", tl_y, tl_x); //asfPrintStatus(" (line,sample) TR (%d,%d)\n", tr_y, tr_x); //asfPrintStatus(" BL (%d,%d)\n", bl_y, bl_x); //asfPrintStatus(" BR (%d,%d)\n", br_y, br_x); double tl_time, tl_slant; double tr_time, tr_slant; double bl_time, bl_slant; double br_time, br_slant; meta_get_timeSlantDop(inMeta, tl_y, tl_x, &tl_time, &tl_slant, NULL); meta_get_timeSlantDop(inMeta, tr_y, tr_x, &tr_time, &tr_slant, NULL); meta_get_timeSlantDop(inMeta, bl_y, bl_x, &bl_time, &bl_slant, NULL); meta_get_timeSlantDop(inMeta, br_y, br_x, &br_time, &br_slant, NULL); //asfPrintStatus("Corners are at: TL (%f,%f)\n", tl_time, tl_slant); //asfPrintStatus(" (time,slant) TR (%f,%f)\n", tr_time, tr_slant); //asfPrintStatus(" BL (%f,%f)\n", bl_time, bl_slant); //asfPrintStatus(" BR (%f,%f)\n", br_time, br_slant); double slant_start = min4(tl_slant, tr_slant, bl_slant, br_slant); double slant_end = max4(tl_slant, tr_slant, bl_slant, br_slant); double time_min = min4(tl_time, tr_time, bl_time, br_time); double time_max = max4(tl_time, tr_time, bl_time, br_time); double slant_incr; double time_start, time_end, time_incr; int onl, ons; if (pixel_size > 0) { slant_incr = pixel_size; ons = (slant_end - slant_start) / slant_incr; if (inMeta->sar) { // in this case, the original data has a SAR block, we will use the // same azimuth time per pixel. time_incr = inMeta->sar->azimuth_time_per_pixel; // we always want to be DECREASING in time // latest time is on top (line 1), earliest on bottom (line ONL) if (time_incr > 0) { time_incr = -time_incr; inMeta->sar->azimuth_time_per_pixel = -inMeta->sar->azimuth_time_per_pixel; } time_start = time_max; time_end = time_min; onl = (time_end - time_start) / time_incr; } else { // here, no sar block in the original data, just make a square // image with decreasing time onl = ons; time_incr = (time_min - time_max) / (double)onl; time_start = time_max; time_end = time_min; } } else { // not provided a slant range pixel size, we'll figure something out if (inMeta->sar) { // use the same azimuth time per pixel. time_incr = inMeta->sar->azimuth_time_per_pixel; // we always want to be DECREASING in time // latest time is on top (line 1), earliest on bottom (line ONL) if (time_incr > 0) { time_incr = -time_incr; inMeta->sar->azimuth_time_per_pixel = -inMeta->sar->azimuth_time_per_pixel; } time_start = time_max; time_end = time_min; onl = (time_end - time_start) / time_incr; } else { // no info... determine azimuth time per pixel by keeping // the height the same as in the original image onl = nl; time_incr = (time_min - time_max) / (double)onl; time_start = time_max; time_end = time_min; } // make it square, to get the slant range pixel size ons = onl; pixel_size = slant_incr = (slant_end - slant_start) / (double)ons; } asfRequire(onl > 0, "Internal Error: Invalid output line count: %d\n", onl); asfRequire(ons > 0, "Internal Error: Invalid output sample count: %d\n", ons); asfPrintStatus(" Slant range values: %f -> %f\n", slant_start, slant_end); asfPrintStatus(" Slant range pixel size: %f\n", pixel_size); asfPrintStatus(" Time values: %f -> %f\n", time_start, time_end); asfPrintStatus(" Output Image will be %5d x %5d LxS\n", onl, ons); asfPrintStatus(" (Input Image was %5d x %5d LxS)\n", nl, ns); // generate a grid over the image, to generate our splines // this grid size seems to work pretty well... int n = 120; asfPrintStatus("Creating %dx%d mapping grid...\n", n, n); // changed how these are calculated, so that the spline will cover // the entire value range double time_grid_incr = fabs(time_end - time_start) / (double)(n-1); if (time_incr < 0) time_grid_incr = -time_grid_incr; double slant_grid_incr = fabs(slant_end - slant_start) / (double)(n-1); if (slant_incr < 0) slant_grid_incr = -slant_grid_incr; // allocating memory for the splines, and the arrays to generate them gsl_interp_accel **samp_accels = MALLOC(sizeof(gsl_interp_accel *) * n); gsl_spline **samp_splines = MALLOC(sizeof(gsl_spline *) * n); gsl_interp_accel **line_accels = MALLOC(sizeof(gsl_interp_accel *) * n); gsl_spline **line_splines = MALLOC(sizeof(gsl_spline *) * n); double *slant_in = MALLOC(sizeof(double)*n); double *line_out = MALLOC(sizeof(double)*n); double *samp_out = MALLOC(sizeof(double)*n); // an alias -- use the same array (to save memory -- these are not used // at the same time), but create an alias for it, so it is not so confusing double *time_in = slant_in; //double max_err = 0; // set up the vertical splines for (jj=0; jj<n; ++jj) { double slant = slant_start + jj*slant_grid_incr; for (ii=0; ii<n; ++ii) { // splines need strictly increasing range variables if (time_grid_incr > 0) time_in[ii] = time_start + ii*time_grid_incr; else time_in[ii] = time_end - ii*time_grid_incr; ts2ls(inMeta, time_in[ii], slant, &line_out[ii], &samp_out[ii]); //printf("time: %f, slant: %f ==> line: %f, samp %f\n", // time_in[ii], slant, line_out[ii], samp_out[ii]); } samp_accels[jj] = gsl_interp_accel_alloc(); samp_splines[jj] = gsl_spline_alloc(gsl_interp_cspline, n); gsl_spline_init(samp_splines[jj], time_in, samp_out, n); line_accels[jj] = gsl_interp_accel_alloc(); line_splines[jj] = gsl_spline_alloc(gsl_interp_cspline, n); gsl_spline_init(line_splines[jj], time_in, line_out, n); } // now, we're on to the resampling stage.. loop through output pixels asfPrintStatus("Generating slant range image...\n"); double no_data_value = meta_is_valid_double(inMeta->general->no_data) ? inMeta->general->no_data : 0; // keep track of error sizes double max_error = 0; double avg_error = 0; int count = 0; // these stride values allow us to track when we're in between grid points int ii_n = onl/n; int jj_n = ons/n; int ii_n2 = ii_n/2; int jj_n2 = jj_n/2; // set up output metadata meta_parameters *outMeta = meta_read(infile); if (outMeta->transform) { FREE(outMeta->transform); outMeta->transform = NULL; } if (outMeta->projection) { FREE(outMeta->projection); outMeta->projection = NULL; } outMeta->general->line_count = onl; outMeta->general->sample_count = ons; if (!outMeta->sar) outMeta->sar = meta_sar_init(); outMeta->sar->image_type = 'S'; outMeta->sar->azimuth_time_per_pixel = time_incr; assert(outMeta->sar->azimuth_time_per_pixel < 0); outMeta->sar->time_shift = time_start; outMeta->general->y_pixel_size = inMeta->sar->azimuth_time_per_pixel / time_incr * inMeta->general->y_pixel_size; assert(outMeta->general->y_pixel_size > 0); outMeta->sar->slant_range_first_pixel = slant_start; outMeta->general->x_pixel_size = slant_incr; outMeta->sar->line_increment = outMeta->sar->sample_increment = 1; outMeta->general->start_sample = outMeta->general->start_line = 0; outMeta->general->no_data = no_data_value; char **band_name = extract_band_names(inMeta->general->bands, inMeta->general->band_count); // now generate output image char *img_file = appendExt(outfile, ".img"); float *out = MALLOC(sizeof(float) * ons); for (kk=0; kk<inMeta->general->band_count; ++kk) { if (inMeta->general->band_count != 1) asfPrintStatus("Working on band: %s\n", band_name[kk]); // for the 2nd and higher bands, free the band from the previous iteration, // and read in the next band from the input image if (kk>0) { float_image_free(in); asfPrintStatus("Loading input...\n"); in = float_image_band_new_from_metadata(inMeta, kk, infile); } FILE *ofp = FOPEN(img_file, kk==0 ? "wb" : "ab"); asfPrintStatus("Generating output...\n"); for (ii=0; ii<onl; ++ii) { asfLineMeter(ii,onl); double time = time_start + ii * time_incr; // set up horizontal splines for this row gsl_interp_accel *samp_accel = gsl_interp_accel_alloc(); gsl_spline *samp_spline = gsl_spline_alloc(gsl_interp_cspline, n); gsl_interp_accel *line_accel = gsl_interp_accel_alloc(); gsl_spline *line_spline = gsl_spline_alloc(gsl_interp_cspline, n); //printf("time: %f slant: %f\n", time, slant_start); for (jj=0; jj<n; ++jj) { slant_in[jj] = slant_start + jj * slant_grid_incr; //printf("time: %f slant: %f\n", time, slant_in[jj]); samp_out[jj] = gsl_spline_eval_check(samp_splines[jj], time, samp_accels[jj]); line_out[jj] = gsl_spline_eval_check(line_splines[jj], time, line_accels[jj]); //printf("samp_out: %f line_out: %f\n", samp_out[jj], line_out[jj]); } gsl_spline_init(samp_spline, slant_in, samp_out, n); gsl_spline_init(line_spline, slant_in, line_out, n); // use the splines to produce output pixels for (jj=0; jj<ons; ++jj) { double slant = slant_start + jj * slant_incr; double samp = gsl_spline_eval_check(samp_spline, slant, samp_accel); double line = gsl_spline_eval_check(line_spline, slant, line_accel); // check the spline every so often (halfway between grid points) // only do this on band #1 (the reference band) if (kk==0 && ii%ii_n2==0 && ii%ii_n!=0 && jj%jj_n2==0 && jj%jj_n!=0) { double samp_real, line_real; ts2ls(inMeta, time, slant, &line_real, &samp_real); double err = (line-line_real)*(line-line_real) + (samp-samp_real)*(samp-samp_real); //printf("(%d,%d) -- Actual: (%f,%f) Splined: (%f,%f)\n", // ii, jj, line_real, samp_real, line, samp); if (err > max_error) max_error = err; avg_error += err; ++count; } // now interpolate within the original image // if we are outside, use "no_data" from metadata double val = no_data_value; if (line > 0 && line < nl-1 && samp > 0 && samp < ns-1) val = float_image_sample(in, samp, line, sampling_method); out[jj] = (float)val; } gsl_interp_accel_free(samp_accel); gsl_spline_free(samp_spline); gsl_interp_accel_free(line_accel); gsl_spline_free(line_spline); put_float_line(ofp, outMeta, ii, out); } fclose(ofp); } // free the last band of the input float_image_free(in); FREE(slant_in); FREE(line_out); FREE(samp_out); for (ii=0; ii<n; ++ii) { gsl_interp_accel_free(samp_accels[ii]); gsl_spline_free(samp_splines[ii]); gsl_interp_accel_free(line_accels[ii]); gsl_spline_free(line_splines[ii]); } FREE(samp_accels); FREE(samp_splines); FREE(line_accels); FREE(line_splines); FREE(out); for (kk=0; kk<inMeta->general->band_count; ++kk) FREE(band_name[kk]); FREE(band_name); // see how bad our errors were avg_error /= (double)count; asfPrintStatus("Model max error: %f, avg: %f\n", max_error, avg_error); double thresh = 0.1; if (max_error > 100*thresh) asfPrintError("Maximum error exceeded threshold: %f > %f\n", max_error, 100*thresh); else if (avg_error > 10*thresh) asfPrintError("Average error exceeded threshold: %f > %f\n", avg_error, 10*thresh); if (max_error > 10*thresh) asfPrintWarning("Maximum error exceeds threshold: %f > %f\n", max_error, 10*thresh); if (avg_error > thresh) asfPrintWarning("Average error exceeds threshold: %f > %f\n", avg_error, thresh); char *meta_file = appendExt(outfile, ".meta"); asfPrintStatus("Writing %s\n", meta_file); meta_write(outMeta, meta_file); free(meta_file); free(img_file); meta_free(outMeta); meta_free(inMeta); return 0; //success }
void transform_setup_source_rect(struct transformation *t) { int i; struct coord screen[4]; struct point screen_pnt[4]; struct point_rect *pr; struct map_selection *ms,*msm,*next,**msm_last; ms=t->map_sel; while (ms) { next=ms->next; g_free(ms); ms=next; } t->map_sel=NULL; msm_last=&t->map_sel; ms=t->screen_sel; while (ms) { msm=g_new0(struct map_selection, 1); *msm=*ms; pr=&ms->u.p_rect; screen_pnt[0].x=pr->lu.x; /* left upper */ screen_pnt[0].y=pr->lu.y; screen_pnt[1].x=pr->rl.x; /* right upper */ screen_pnt[1].y=pr->lu.y; screen_pnt[2].x=pr->rl.x; /* right lower */ screen_pnt[2].y=pr->rl.y; screen_pnt[3].x=pr->lu.x; /* left lower */ screen_pnt[3].y=pr->rl.y; if (t->ddd) { struct coord_geo_cart tmp,cg[8]; struct coord c; int valid=0; unsigned char edgenodes[]={ 0,1, 1,2, 2,3, 3,0, 4,5, 5,6, 6,7, 7,4, 0,4, 1,5, 2,6, 3,7}; for (i = 0 ; i < 8 ; i++) { transform_screen_to_3d(t, &screen_pnt[i%4], (i >= 4 ? t->zfar:t->znear), &tmp); transform_apply_inverse_matrix(t, &tmp, &cg[i]); } msm->u.c_rect.lu.x=0; msm->u.c_rect.lu.y=0; msm->u.c_rect.rl.x=0; msm->u.c_rect.rl.y=0; for (i = 0 ; i < 12 ; i++) { if (transform_zplane_intersection(&cg[edgenodes[i*2]], &cg[edgenodes[i*2+1]], HOG(*t), &tmp) == 1) { c.x=tmp.x*(1 << t->scale_shift)+t->map_center.x; c.y=tmp.y*(1 << t->scale_shift)+t->map_center.y; dbg(1,"intersection with edge %d at 0x%x,0x%x\n",i,c.x,c.y); if (valid) coord_rect_extend(&msm->u.c_rect, &c); else { msm->u.c_rect.lu=c; msm->u.c_rect.rl=c; valid=1; } dbg(1,"rect 0x%x,0x%x - 0x%x,0x%x\n",msm->u.c_rect.lu.x,msm->u.c_rect.lu.y,msm->u.c_rect.rl.x,msm->u.c_rect.rl.y); } } } else { for (i = 0 ; i < 4 ; i++) { transform_reverse(t, &screen_pnt[i], &screen[i]); dbg(1,"map(%d) %d,%d=0x%x,0x%x\n", i,screen_pnt[i].x, screen_pnt[i].y, screen[i].x, screen[i].y); } msm->u.c_rect.lu.x=min4(screen[0].x,screen[1].x,screen[2].x,screen[3].x); msm->u.c_rect.rl.x=max4(screen[0].x,screen[1].x,screen[2].x,screen[3].x); msm->u.c_rect.rl.y=min4(screen[0].y,screen[1].y,screen[2].y,screen[3].y); msm->u.c_rect.lu.y=max4(screen[0].y,screen[1].y,screen[2].y,screen[3].y); } dbg(1,"%dx%d\n", msm->u.c_rect.rl.x-msm->u.c_rect.lu.x, msm->u.c_rect.lu.y-msm->u.c_rect.rl.y); *msm_last=msm; msm_last=&msm->next; ms=ms->next; } }