//旋转卡壳求两个凸包的最近点对,使用时要调用min(RC(p,np,q,np),RC(q,nq,p,np)); Type Rotating_Calipers(Point *p,int np,Point *q,int nq){ int sp = 0,sq = 0; for(int i = 0;i<np;i++) if(sign(p[i].y-p[sp].y)<0) sp = i; for(int i = 0;i<nq;i++) if(sign(q[i].y-q[sq].y)>0) sq = i; double tmp,ans = INF; p[np] = p[0],q[nq] = q[0]; for(int i = 0;i<np;i++){ while(sign(tmp = Cross(p[sp],p[sp+1],q[sq])-Cross(p[sp],p[sp+1],q[sq+1]))<0) sq = (sq+1)%nq; if(sign(tmp)>0){ ans = min(ans,DistanceToSegMent(q[sq],SegMent(p[sp],p[sp+1]))); }else{ SegMent segp(p[sp],p[sp+1]),segq(q[sq],q[sq+1]); ans = min(ans,DistanceToSegMent(p[sp],segq)); ans = min(ans,DistanceToSegMent(p[sp+1],segq)); ans = min(ans,DistanceToSegMent(q[sq],segp)); ans = min(ans,DistanceToSegMent(q[sq+1],segp)); } sp = (sp+1)%np; } return ans; }
void IMG_createslice(Image_t *img, const char *name, uaddr_t addr) { assert(img != NULL); #if 1 //printf("creating slice for %s\n", name); // Create module if not created yet sqlq_t sqsel(img->db, "SELECT modid FROM tab_module WHERE name = @N"); sqsel.bind_str(1, name); int modid = sqsel.answer(); if (modid == 0) { sqlq_t ssi(img->db, "INSERT INTO tab_module(name) VALUES(@A)"); ssi.bind_str(1, name); ssi.run(); modid = sqsel.answer(); if (modid == 0) { printf("ERROR\n"); } } // get segment for this slice sqlq_t segq(img->db, "SELECT segid FROM tab_segment WHERE address <= @A AND address + size > @B"); segq.bind_int(1, addr); segq.bind_int(2, addr); int segid = segq.answer(); if (segid == 0) { return; } // adjust previous slices' sizes int secid = uaddr_sec(addr); int secsize = IMG_getsecsize(img, secid); uaddr_t secstart = uaddr_mk(secid, 0); uaddr_t secend = uaddr_mk(secid, secsize); // passa por todos os slices deste seg sqlq_t sq(img->db, "SELECT address,size FROM tab_modslice WHERE address >= @A AND address < @B ORDER BY address ASC"); sq.bind_int(1, secstart); sq.bind_int(2, secend); int size = secend - addr; while(sq.step()) { int this_start = sq.col_int(0); int this_size = sq.col_int(1); int this_end = this_start + this_size; if (this_end <= addr) { // do nothing // Achei um slice antes do meu que tem que ser cortado } else if (this_start < addr && this_end > addr) { //if (this_start > addr) { // muda o size do atual sqlq_t upd(img->db, "update tab_modslice set size=@a where address=@b"); uaddr_t this_new_end = addr; int this_new_size = this_new_end - this_start; upd.bind_int(1, this_new_size); upd.bind_int(2, this_start); if (!upd.run()) { printf("; update slice size error\n"); } //size = this_end - addr; //break; // Achei um slice depois do meu, entao vou me aparar } else if (addr < this_start) { size = this_start - addr; break; } else { printf("SLICE POSITIONING ERROR\n"); } } // Insert this slice sqlq_t ins(img->db, "INSERT INTO tab_modslice(address, size, module, segment) VALUES(@A, @B, @C, @D)"); ins.bind_int(1, addr); ins.bind_int(2, size); ins.bind_int(3, modid); ins.bind_int(4, segid); if (!ins.run()) { printf("; Create slice error\n"); } else { //printf("; Created slice %s\n", name); } #endif #if 0 sqlq_t s(img->db, "INSERT INTO tab_modslice(address, size, module, segment) VALUES(@A, @B, @C, @D, @E, @F)"); s.bind_str(1, name); s.bind_str(2, sclass); s.bind_int(3, align); s.bind_int(4, use); s.bind_int(5, addr); s.bind_int(6, priority); if (!s.run()) { printf("; Create segment error\n"); } else { printf("; Created segment %s\n", name); } #endif }