1*37da2899SCharles.Forsythimplement Polyfill; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsythinclude "sys.m"; 4*37da2899SCharles.Forsyth sys: Sys; 5*37da2899SCharles.Forsythinclude "draw.m"; 6*37da2899SCharles.Forsyth draw: Draw; 7*37da2899SCharles.Forsyth Point, Rect, Image, Endsquare: import draw; 8*37da2899SCharles.Forsythinclude "math/polyfill.m"; 9*37da2899SCharles.Forsyth 10*37da2899SCharles.Forsyth∞: con 16r7fffffff; 11*37da2899SCharles.Forsyth 12*37da2899SCharles.Forsythinit() 13*37da2899SCharles.Forsyth{ 14*37da2899SCharles.Forsyth sys = load Sys Sys->PATH; 15*37da2899SCharles.Forsyth draw = load Draw Draw->PATH; 16*37da2899SCharles.Forsyth} 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsythinitzbuf(r: Rect): ref Zstate 19*37da2899SCharles.Forsyth{ 20*37da2899SCharles.Forsyth if(sys == nil) 21*37da2899SCharles.Forsyth init(); 22*37da2899SCharles.Forsyth s := ref Zstate; 23*37da2899SCharles.Forsyth s.r = r; 24*37da2899SCharles.Forsyth s.xlen = r.dx(); 25*37da2899SCharles.Forsyth s.ylen = r.dy(); 26*37da2899SCharles.Forsyth s.xylen = s.xlen*s.ylen; 27*37da2899SCharles.Forsyth s.zbuf0 = array[s.xylen] of int; 28*37da2899SCharles.Forsyth s.zbuf1 = array[s.xylen] of int; 29*37da2899SCharles.Forsyth return s; 30*37da2899SCharles.Forsyth} 31*37da2899SCharles.Forsyth 32*37da2899SCharles.Forsythclearzbuf(s: ref Zstate) 33*37da2899SCharles.Forsyth{ 34*37da2899SCharles.Forsyth b0 := s.zbuf0; 35*37da2899SCharles.Forsyth b1 := s.zbuf1; 36*37da2899SCharles.Forsyth n := s.xylen; 37*37da2899SCharles.Forsyth for(i := 0; i < n; i++) 38*37da2899SCharles.Forsyth b0[i] = b1[i] = ∞; 39*37da2899SCharles.Forsyth} 40*37da2899SCharles.Forsyth 41*37da2899SCharles.Forsythsetzbuf(s: ref Zstate, zd: int) 42*37da2899SCharles.Forsyth{ 43*37da2899SCharles.Forsyth b0 := s.zbuf0; 44*37da2899SCharles.Forsyth b1 := s.zbuf1; 45*37da2899SCharles.Forsyth n := s.xylen; 46*37da2899SCharles.Forsyth for(i := 0; i < n; i++) 47*37da2899SCharles.Forsyth b0[i] = b1[i] = zd; 48*37da2899SCharles.Forsyth} 49*37da2899SCharles.Forsyth 50*37da2899SCharles.ForsythSeg: adt 51*37da2899SCharles.Forsyth{ 52*37da2899SCharles.Forsyth p0: Point; 53*37da2899SCharles.Forsyth p1: Point; 54*37da2899SCharles.Forsyth num: int; 55*37da2899SCharles.Forsyth den: int; 56*37da2899SCharles.Forsyth dz: int; 57*37da2899SCharles.Forsyth dzrem: int; 58*37da2899SCharles.Forsyth z: int; 59*37da2899SCharles.Forsyth zerr: int; 60*37da2899SCharles.Forsyth d: int; 61*37da2899SCharles.Forsyth}; 62*37da2899SCharles.Forsyth 63*37da2899SCharles.Forsythfillline(dst: ref Image, left: int, right: int, y: int, src: ref Image, p: Point) 64*37da2899SCharles.Forsyth{ 65*37da2899SCharles.Forsyth p.x += left; 66*37da2899SCharles.Forsyth p.y += y; 67*37da2899SCharles.Forsyth dst.line((left, y), (right, y), Endsquare, Endsquare, 0, src, p); 68*37da2899SCharles.Forsyth} 69*37da2899SCharles.Forsyth 70*37da2899SCharles.Forsythfilllinez(dst: ref Image, left: int, right: int, y: int, z: int, e: int, dx: int, k: int, zbuf0: array of int, zbuf1: array of int, src: ref Image, p: Point) 71*37da2899SCharles.Forsyth{ 72*37da2899SCharles.Forsyth prevx := ∞; 73*37da2899SCharles.Forsyth for(x := left; x <= right; x++){ 74*37da2899SCharles.Forsyth if(z+e < zbuf0[k] || (z-e <= zbuf1[k] && x != right && prevx != ∞)){ 75*37da2899SCharles.Forsyth zbuf0[k] = z-e; 76*37da2899SCharles.Forsyth zbuf1[k] = z+e; 77*37da2899SCharles.Forsyth if(prevx == ∞) 78*37da2899SCharles.Forsyth prevx = x; 79*37da2899SCharles.Forsyth } 80*37da2899SCharles.Forsyth else if(prevx != ∞){ 81*37da2899SCharles.Forsyth fillline(dst, prevx, x-1, y, src, p); 82*37da2899SCharles.Forsyth prevx = ∞; 83*37da2899SCharles.Forsyth } 84*37da2899SCharles.Forsyth z += dx; 85*37da2899SCharles.Forsyth k++; 86*37da2899SCharles.Forsyth } 87*37da2899SCharles.Forsyth if(prevx != ∞) 88*37da2899SCharles.Forsyth fillline(dst, prevx, right, y, src, p); 89*37da2899SCharles.Forsyth} 90*37da2899SCharles.Forsyth 91*37da2899SCharles.Forsythfillpoly(dst: ref Image, vert: array of Point, w: int, src: ref Image, sp: Point, zstate: ref Zstate, dc: int, dx: int, dy: int) 92*37da2899SCharles.Forsyth{ 93*37da2899SCharles.Forsyth p0: Point; 94*37da2899SCharles.Forsyth i: int; 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth nvert := len vert; 97*37da2899SCharles.Forsyth if(nvert == 0) 98*37da2899SCharles.Forsyth return; 99*37da2899SCharles.Forsyth fixshift := 0; 100*37da2899SCharles.Forsyth seg := array[nvert+2] of ref Seg; 101*37da2899SCharles.Forsyth if(seg == nil) 102*37da2899SCharles.Forsyth return; 103*37da2899SCharles.Forsyth segtab := array[nvert+1] of ref Seg; 104*37da2899SCharles.Forsyth if(segtab == nil) 105*37da2899SCharles.Forsyth return; 106*37da2899SCharles.Forsyth 107*37da2899SCharles.Forsyth sp.x = (sp.x - vert[0].x) >> fixshift; 108*37da2899SCharles.Forsyth sp.y = (sp.y - vert[0].y) >> fixshift; 109*37da2899SCharles.Forsyth p0 = vert[nvert-1]; 110*37da2899SCharles.Forsyth if(!fixshift) { 111*37da2899SCharles.Forsyth p0.x <<= 1; 112*37da2899SCharles.Forsyth p0.y <<= 1; 113*37da2899SCharles.Forsyth } 114*37da2899SCharles.Forsyth for(i = 0; i < nvert; i++) { 115*37da2899SCharles.Forsyth segtab[i] = ref Seg; 116*37da2899SCharles.Forsyth segtab[i].p0 = p0; 117*37da2899SCharles.Forsyth p0 = vert[i]; 118*37da2899SCharles.Forsyth if(!fixshift) { 119*37da2899SCharles.Forsyth p0.x <<= 1; 120*37da2899SCharles.Forsyth p0.y <<= 1; 121*37da2899SCharles.Forsyth } 122*37da2899SCharles.Forsyth segtab[i].p1 = p0; 123*37da2899SCharles.Forsyth segtab[i].d = 1; 124*37da2899SCharles.Forsyth } 125*37da2899SCharles.Forsyth if(!fixshift) 126*37da2899SCharles.Forsyth fixshift = 1; 127*37da2899SCharles.Forsyth 128*37da2899SCharles.Forsyth xscan(dst, seg, segtab, nvert, w, src, sp, zstate, dc, dx, dy, fixshift); 129*37da2899SCharles.Forsyth} 130*37da2899SCharles.Forsyth 131*37da2899SCharles.Forsythmod(x: int, y: int): int 132*37da2899SCharles.Forsyth{ 133*37da2899SCharles.Forsyth z: int; 134*37da2899SCharles.Forsyth 135*37da2899SCharles.Forsyth z = x%y; 136*37da2899SCharles.Forsyth if((z^y) > 0 || z == 0) 137*37da2899SCharles.Forsyth return z; 138*37da2899SCharles.Forsyth return z + y; 139*37da2899SCharles.Forsyth} 140*37da2899SCharles.Forsyth 141*37da2899SCharles.Forsythsdiv(x: int, y: int): int 142*37da2899SCharles.Forsyth{ 143*37da2899SCharles.Forsyth if((x^y) >= 0 || x == 0) 144*37da2899SCharles.Forsyth return x/y; 145*37da2899SCharles.Forsyth return (x+((y>>30)|1))/y-1; 146*37da2899SCharles.Forsyth} 147*37da2899SCharles.Forsyth 148*37da2899SCharles.Forsythsmuldivmod(x: int, y: int, z: int): (int, int) 149*37da2899SCharles.Forsyth{ 150*37da2899SCharles.Forsyth mod: int; 151*37da2899SCharles.Forsyth vx: int; 152*37da2899SCharles.Forsyth 153*37da2899SCharles.Forsyth if(x == 0 || y == 0) 154*37da2899SCharles.Forsyth return (0, 0); 155*37da2899SCharles.Forsyth vx = x; 156*37da2899SCharles.Forsyth vx *= y; 157*37da2899SCharles.Forsyth mod = vx % z; 158*37da2899SCharles.Forsyth if(mod < 0) 159*37da2899SCharles.Forsyth mod += z; 160*37da2899SCharles.Forsyth if((vx < 0) == (z < 0)) 161*37da2899SCharles.Forsyth return (vx/z, mod); 162*37da2899SCharles.Forsyth return (-((-vx)/z), mod); 163*37da2899SCharles.Forsyth} 164*37da2899SCharles.Forsyth 165*37da2899SCharles.Forsythxscan(dst: ref Image, seg: array of ref Seg, segtab: array of ref Seg, nseg: int, wind: int, src: ref Image, spt: Point, zstate: ref Zstate, dc: int, dx: int, dy: int, fixshift: int) 166*37da2899SCharles.Forsyth{ 167*37da2899SCharles.Forsyth y, maxy, x, x2, onehalf: int; 168*37da2899SCharles.Forsyth ep, next, p, q, s: int; 169*37da2899SCharles.Forsyth n, i, iy, cnt, ix, ix2, minx, maxx, zinc, k, zv: int; 170*37da2899SCharles.Forsyth pt: Point; 171*37da2899SCharles.Forsyth sp: ref Seg; 172*37da2899SCharles.Forsyth 173*37da2899SCharles.Forsyth er := (abs(dx)+abs(dy)+1)/2; 174*37da2899SCharles.Forsyth zr := zstate.r; 175*37da2899SCharles.Forsyth xlen := zstate.xlen; 176*37da2899SCharles.Forsyth zbuf0 := zstate.zbuf0; 177*37da2899SCharles.Forsyth zbuf1 := zstate.zbuf1; 178*37da2899SCharles.Forsyth s = 0; 179*37da2899SCharles.Forsyth p = 0; 180*37da2899SCharles.Forsyth for(i=0; i<nseg; i++) { 181*37da2899SCharles.Forsyth sp = seg[p] = segtab[s]; 182*37da2899SCharles.Forsyth if(sp.p0.y == sp.p1.y){ 183*37da2899SCharles.Forsyth s++; 184*37da2899SCharles.Forsyth continue; 185*37da2899SCharles.Forsyth } 186*37da2899SCharles.Forsyth if(sp.p0.y > sp.p1.y) { 187*37da2899SCharles.Forsyth pt = sp.p0; 188*37da2899SCharles.Forsyth sp.p0 = sp.p1; 189*37da2899SCharles.Forsyth sp.p1 = pt; 190*37da2899SCharles.Forsyth sp.d = -sp.d; 191*37da2899SCharles.Forsyth } 192*37da2899SCharles.Forsyth sp.num = sp.p1.x - sp.p0.x; 193*37da2899SCharles.Forsyth sp.den = sp.p1.y - sp.p0.y; 194*37da2899SCharles.Forsyth sp.dz = sdiv(sp.num, sp.den) << fixshift; 195*37da2899SCharles.Forsyth sp.dzrem = mod(sp.num, sp.den) << fixshift; 196*37da2899SCharles.Forsyth sp.dz += sdiv(sp.dzrem, sp.den); 197*37da2899SCharles.Forsyth sp.dzrem = mod(sp.dzrem, sp.den); 198*37da2899SCharles.Forsyth p++; 199*37da2899SCharles.Forsyth s++; 200*37da2899SCharles.Forsyth } 201*37da2899SCharles.Forsyth n = p; 202*37da2899SCharles.Forsyth if(n == 0) 203*37da2899SCharles.Forsyth return; 204*37da2899SCharles.Forsyth seg[p] = nil; 205*37da2899SCharles.Forsyth qsortycompare(seg, p); 206*37da2899SCharles.Forsyth 207*37da2899SCharles.Forsyth onehalf = 0; 208*37da2899SCharles.Forsyth if(fixshift) 209*37da2899SCharles.Forsyth onehalf = 1 << (fixshift-1); 210*37da2899SCharles.Forsyth 211*37da2899SCharles.Forsyth minx = dst.clipr.min.x; 212*37da2899SCharles.Forsyth maxx = dst.clipr.max.x; 213*37da2899SCharles.Forsyth 214*37da2899SCharles.Forsyth y = seg[0].p0.y; 215*37da2899SCharles.Forsyth if(y < (dst.clipr.min.y << fixshift)) 216*37da2899SCharles.Forsyth y = dst.clipr.min.y << fixshift; 217*37da2899SCharles.Forsyth iy = (y + onehalf) >> fixshift; 218*37da2899SCharles.Forsyth y = (iy << fixshift) + onehalf; 219*37da2899SCharles.Forsyth maxy = dst.clipr.max.y << fixshift; 220*37da2899SCharles.Forsyth k = (iy-zr.min.y)*xlen; 221*37da2899SCharles.Forsyth zv = dc+iy*dy; 222*37da2899SCharles.Forsyth 223*37da2899SCharles.Forsyth ep = next = 0; 224*37da2899SCharles.Forsyth 225*37da2899SCharles.Forsyth while(y<maxy) { 226*37da2899SCharles.Forsyth for(q = p = 0; p < ep; p++) { 227*37da2899SCharles.Forsyth sp = seg[p]; 228*37da2899SCharles.Forsyth if(sp.p1.y < y) 229*37da2899SCharles.Forsyth continue; 230*37da2899SCharles.Forsyth sp.z += sp.dz; 231*37da2899SCharles.Forsyth sp.zerr += sp.dzrem; 232*37da2899SCharles.Forsyth if(sp.zerr >= sp.den) { 233*37da2899SCharles.Forsyth sp.z++; 234*37da2899SCharles.Forsyth sp.zerr -= sp.den; 235*37da2899SCharles.Forsyth if(sp.zerr < 0 || sp.zerr >= sp.den) 236*37da2899SCharles.Forsyth sys->print("bad ratzerr1: %d den %d dzrem %d\n", sp.zerr, sp.den, sp.dzrem); 237*37da2899SCharles.Forsyth } 238*37da2899SCharles.Forsyth seg[q] = sp; 239*37da2899SCharles.Forsyth q++; 240*37da2899SCharles.Forsyth } 241*37da2899SCharles.Forsyth 242*37da2899SCharles.Forsyth for(p = next; seg[p] != nil; p++) { 243*37da2899SCharles.Forsyth sp = seg[p]; 244*37da2899SCharles.Forsyth if(sp.p0.y >= y) 245*37da2899SCharles.Forsyth break; 246*37da2899SCharles.Forsyth if(sp.p1.y < y) 247*37da2899SCharles.Forsyth continue; 248*37da2899SCharles.Forsyth sp.z = sp.p0.x; 249*37da2899SCharles.Forsyth (zinc, sp.zerr) = smuldivmod(y - sp.p0.y, sp.num, sp.den); 250*37da2899SCharles.Forsyth sp.z += zinc; 251*37da2899SCharles.Forsyth if(sp.zerr < 0 || sp.zerr >= sp.den) 252*37da2899SCharles.Forsyth sys->print("bad ratzerr2: %d den %d ratdzrem %d\n", sp.zerr, sp.den, sp.dzrem); 253*37da2899SCharles.Forsyth seg[q] = sp; 254*37da2899SCharles.Forsyth q++; 255*37da2899SCharles.Forsyth } 256*37da2899SCharles.Forsyth ep = q; 257*37da2899SCharles.Forsyth next = p; 258*37da2899SCharles.Forsyth 259*37da2899SCharles.Forsyth if(ep == 0) { 260*37da2899SCharles.Forsyth if(seg[next] == nil) 261*37da2899SCharles.Forsyth break; 262*37da2899SCharles.Forsyth iy = (seg[next].p0.y + onehalf) >> fixshift; 263*37da2899SCharles.Forsyth y = (iy << fixshift) + onehalf; 264*37da2899SCharles.Forsyth k = (iy-zr.min.y)*xlen; 265*37da2899SCharles.Forsyth zv = dc+iy*dy; 266*37da2899SCharles.Forsyth continue; 267*37da2899SCharles.Forsyth } 268*37da2899SCharles.Forsyth 269*37da2899SCharles.Forsyth zsort(seg, ep); 270*37da2899SCharles.Forsyth 271*37da2899SCharles.Forsyth for(p = 0; p < ep; p++) { 272*37da2899SCharles.Forsyth sp = seg[p]; 273*37da2899SCharles.Forsyth cnt = 0; 274*37da2899SCharles.Forsyth x = sp.z; 275*37da2899SCharles.Forsyth ix = (x + onehalf) >> fixshift; 276*37da2899SCharles.Forsyth if(ix >= maxx) 277*37da2899SCharles.Forsyth break; 278*37da2899SCharles.Forsyth if(ix < minx) 279*37da2899SCharles.Forsyth ix = minx; 280*37da2899SCharles.Forsyth cnt += sp.d; 281*37da2899SCharles.Forsyth p++; 282*37da2899SCharles.Forsyth sp = seg[p]; 283*37da2899SCharles.Forsyth for(;;) { 284*37da2899SCharles.Forsyth if(p == ep) { 285*37da2899SCharles.Forsyth sys->print("xscan: fill to infinity"); 286*37da2899SCharles.Forsyth return; 287*37da2899SCharles.Forsyth } 288*37da2899SCharles.Forsyth cnt += sp.d; 289*37da2899SCharles.Forsyth if((cnt&wind) == 0) 290*37da2899SCharles.Forsyth break; 291*37da2899SCharles.Forsyth p++; 292*37da2899SCharles.Forsyth sp = seg[p]; 293*37da2899SCharles.Forsyth } 294*37da2899SCharles.Forsyth x2 = sp.z; 295*37da2899SCharles.Forsyth ix2 = (x2 + onehalf) >> fixshift; 296*37da2899SCharles.Forsyth if(ix2 <= minx) 297*37da2899SCharles.Forsyth continue; 298*37da2899SCharles.Forsyth if(ix2 > maxx) 299*37da2899SCharles.Forsyth ix2 = maxx; 300*37da2899SCharles.Forsyth filllinez(dst, ix, ix2, iy, zv+ix*dx, er, dx, k+ix-zr.min.x, zbuf0, zbuf1, src, spt); 301*37da2899SCharles.Forsyth } 302*37da2899SCharles.Forsyth y += (1<<fixshift); 303*37da2899SCharles.Forsyth iy++; 304*37da2899SCharles.Forsyth k += xlen; 305*37da2899SCharles.Forsyth zv += dy; 306*37da2899SCharles.Forsyth } 307*37da2899SCharles.Forsyth} 308*37da2899SCharles.Forsyth 309*37da2899SCharles.Forsythzsort(seg: array of ref Seg, ep: int) 310*37da2899SCharles.Forsyth{ 311*37da2899SCharles.Forsyth done: int; 312*37da2899SCharles.Forsyth s: ref Seg; 313*37da2899SCharles.Forsyth q, p: int; 314*37da2899SCharles.Forsyth 315*37da2899SCharles.Forsyth if(ep < 20) { 316*37da2899SCharles.Forsyth # bubble sort by z - they should be almost sorted already 317*37da2899SCharles.Forsyth q = ep; 318*37da2899SCharles.Forsyth do { 319*37da2899SCharles.Forsyth done = 1; 320*37da2899SCharles.Forsyth q--; 321*37da2899SCharles.Forsyth for(p = 0; p < q; p++) { 322*37da2899SCharles.Forsyth if(seg[p].z > seg[p+1].z) { 323*37da2899SCharles.Forsyth s = seg[p]; 324*37da2899SCharles.Forsyth seg[p] = seg[p+1]; 325*37da2899SCharles.Forsyth seg[p+1] = s; 326*37da2899SCharles.Forsyth done = 0; 327*37da2899SCharles.Forsyth } 328*37da2899SCharles.Forsyth } 329*37da2899SCharles.Forsyth } while(!done); 330*37da2899SCharles.Forsyth } else { 331*37da2899SCharles.Forsyth q = ep-1; 332*37da2899SCharles.Forsyth for(p = 0; p < q; p++) { 333*37da2899SCharles.Forsyth if(seg[p].z > seg[p+1].z) { 334*37da2899SCharles.Forsyth qsortzcompare(seg, ep); 335*37da2899SCharles.Forsyth break; 336*37da2899SCharles.Forsyth } 337*37da2899SCharles.Forsyth } 338*37da2899SCharles.Forsyth } 339*37da2899SCharles.Forsyth} 340*37da2899SCharles.Forsyth 341*37da2899SCharles.Forsythycompare(s0: ref Seg, s1: ref Seg): int 342*37da2899SCharles.Forsyth{ 343*37da2899SCharles.Forsyth y0, y1: int; 344*37da2899SCharles.Forsyth 345*37da2899SCharles.Forsyth y0 = s0.p0.y; 346*37da2899SCharles.Forsyth y1 = s1.p0.y; 347*37da2899SCharles.Forsyth 348*37da2899SCharles.Forsyth if(y0 < y1) 349*37da2899SCharles.Forsyth return -1; 350*37da2899SCharles.Forsyth if(y0 == y1) 351*37da2899SCharles.Forsyth return 0; 352*37da2899SCharles.Forsyth return 1; 353*37da2899SCharles.Forsyth} 354*37da2899SCharles.Forsyth 355*37da2899SCharles.Forsythzcompare(s0: ref Seg, s1: ref Seg): int 356*37da2899SCharles.Forsyth{ 357*37da2899SCharles.Forsyth z0, z1: int; 358*37da2899SCharles.Forsyth 359*37da2899SCharles.Forsyth z0 = s0.z; 360*37da2899SCharles.Forsyth z1 = s1.z; 361*37da2899SCharles.Forsyth 362*37da2899SCharles.Forsyth if(z0 < z1) 363*37da2899SCharles.Forsyth return -1; 364*37da2899SCharles.Forsyth if(z0 == z1) 365*37da2899SCharles.Forsyth return 0; 366*37da2899SCharles.Forsyth return 1; 367*37da2899SCharles.Forsyth} 368*37da2899SCharles.Forsyth 369*37da2899SCharles.Forsythqsortycompare(a : array of ref Seg, n : int) 370*37da2899SCharles.Forsyth{ 371*37da2899SCharles.Forsyth i, j : int; 372*37da2899SCharles.Forsyth t : ref Seg; 373*37da2899SCharles.Forsyth 374*37da2899SCharles.Forsyth while(n > 1) { 375*37da2899SCharles.Forsyth i = n>>1; 376*37da2899SCharles.Forsyth t = a[0]; a[0] = a[i]; a[i] = t; 377*37da2899SCharles.Forsyth i = 0; 378*37da2899SCharles.Forsyth j = n; 379*37da2899SCharles.Forsyth for(;;) { 380*37da2899SCharles.Forsyth do 381*37da2899SCharles.Forsyth i++; 382*37da2899SCharles.Forsyth while(i < n && ycompare(a[i], a[0]) < 0); 383*37da2899SCharles.Forsyth do 384*37da2899SCharles.Forsyth j--; 385*37da2899SCharles.Forsyth while(j > 0 && ycompare(a[j], a[0]) > 0); 386*37da2899SCharles.Forsyth if(j < i) 387*37da2899SCharles.Forsyth break; 388*37da2899SCharles.Forsyth t = a[i]; a[i] = a[j]; a[j] = t; 389*37da2899SCharles.Forsyth } 390*37da2899SCharles.Forsyth t = a[0]; a[0] = a[j]; a[j] = t; 391*37da2899SCharles.Forsyth n = n-j-1; 392*37da2899SCharles.Forsyth if(j >= n) { 393*37da2899SCharles.Forsyth qsortycompare(a, j); 394*37da2899SCharles.Forsyth a = a[j+1:]; 395*37da2899SCharles.Forsyth } else { 396*37da2899SCharles.Forsyth qsortycompare(a[j+1:], n); 397*37da2899SCharles.Forsyth n = j; 398*37da2899SCharles.Forsyth } 399*37da2899SCharles.Forsyth } 400*37da2899SCharles.Forsyth} 401*37da2899SCharles.Forsyth 402*37da2899SCharles.Forsythqsortzcompare(a : array of ref Seg, n : int) 403*37da2899SCharles.Forsyth{ 404*37da2899SCharles.Forsyth i, j : int; 405*37da2899SCharles.Forsyth t : ref Seg; 406*37da2899SCharles.Forsyth 407*37da2899SCharles.Forsyth while(n > 1) { 408*37da2899SCharles.Forsyth i = n>>1; 409*37da2899SCharles.Forsyth t = a[0]; a[0] = a[i]; a[i] = t; 410*37da2899SCharles.Forsyth i = 0; 411*37da2899SCharles.Forsyth j = n; 412*37da2899SCharles.Forsyth for(;;) { 413*37da2899SCharles.Forsyth do 414*37da2899SCharles.Forsyth i++; 415*37da2899SCharles.Forsyth while(i < n && zcompare(a[i], a[0]) < 0); 416*37da2899SCharles.Forsyth do 417*37da2899SCharles.Forsyth j--; 418*37da2899SCharles.Forsyth while(j > 0 && zcompare(a[j], a[0]) > 0); 419*37da2899SCharles.Forsyth if(j < i) 420*37da2899SCharles.Forsyth break; 421*37da2899SCharles.Forsyth t = a[i]; a[i] = a[j]; a[j] = t; 422*37da2899SCharles.Forsyth } 423*37da2899SCharles.Forsyth t = a[0]; a[0] = a[j]; a[j] = t; 424*37da2899SCharles.Forsyth n = n-j-1; 425*37da2899SCharles.Forsyth if(j >= n) { 426*37da2899SCharles.Forsyth qsortzcompare(a, j); 427*37da2899SCharles.Forsyth a = a[j+1:]; 428*37da2899SCharles.Forsyth } else { 429*37da2899SCharles.Forsyth qsortzcompare(a[j+1:], n); 430*37da2899SCharles.Forsyth n = j; 431*37da2899SCharles.Forsyth } 432*37da2899SCharles.Forsyth } 433*37da2899SCharles.Forsyth} 434*37da2899SCharles.Forsyth 435*37da2899SCharles.Forsythabs(n: int): int 436*37da2899SCharles.Forsyth{ 437*37da2899SCharles.Forsyth if(n < 0) 438*37da2899SCharles.Forsyth return -n; 439*37da2899SCharles.Forsyth return n; 440*37da2899SCharles.Forsyth} 441