input TEX;

outputtemplate := "%j-%c.ps";

u := 1cm;

vardef create_sample(suffix z)(expr n) =
    save rectangle,minimum,maximum,zero_minimum,zero_maximum,zero_bb, _oldpic, _p;
    picture _oldpic, _p;
    % save currentpicture and redirect drawing to a fresh picture
    _oldpic := currentpicture;
    currentpicture := nullpicture;

    path rectangle;
    rectangle := z1 -- z2 -- z3 -- z4 -- cycle;

    pair minimum, maximum;
    minimum := llcorner rectangle;
    maximum := urcorner rectangle;

    pair zero_minimum, zero_maximum, zero_bb;
    zero_minimum := (min(xpart minimum, 0), min(ypart minimum, 0));
    zero_maximum := (max(xpart maximum, 0), max(ypart maximum, 0));
    zero_bb := zero_maximum - zero_minimum;

    numeric Nx, Ny, sc;
    Nx := 6; Ny := 6;
    sc := 1;
    forever:
        exitif (xpart zero_bb) / sc <= Nx;
        exitif (ypart zero_bb) / sc <= Ny;
        show ("sc: " & decimal(sc) & " " & decimal((xpart zero_bb) / sc) & " " & decimal((ypart zero_bb) / sc));

        sc := sc * 2;
        exitif (xpart zero_bb) / sc <= Nx;
        exitif (ypart zero_bb) / sc <= Ny;
        show ("sc: " & decimal(sc) & " " & decimal((xpart zero_bb) / sc) & " " & decimal((ypart zero_bb) / sc));

        sc := sc * 2.5;
        exitif (xpart zero_bb) / sc <= Nx;
        exitif (ypart zero_bb) / sc <= Ny;
        show ("sc: " & decimal(sc) & " " & decimal((xpart zero_bb) / sc) & " " & decimal((ypart zero_bb) / sc));

        sc := sc * 2;
    endfor;

    zero_minimum := zero_minimum / sc;
    zero_maximum := zero_maximum / sc;

    zero_minimum := zero_minimum - (.3, .3);
    zero_maximum := zero_maximum + (.3, .3);

    pair zz[];
    for i := 1 upto 4:
        zz[i] = z[i] * u / sc;
    endfor;

    %fill .5*(zz1 + zz2) .. .5*(zz2 + zz3) .. .5*(zz3 + zz4) .. .5*(zz4 + zz1) .. cycle withcolor .8white;
    for i := 1 upto 4:
        draw zz[i] -- zz[(i mod 4) + 1] withpen pencircle scaled 2;
    endfor;
    fill fullcircle xscaled abs(zz2-zz1) yscaled abs(zz4-zz1) rotated angle(zz2-zz1) shifted .5(zz1 + zz3) withcolor .5white;
    pair f[];
    if abs(zz2-zz1) >= abs(zz4-zz1):
        f[1] := (.5(abs(zz2-zz1) +-+ abs(zz4-zz1)), 0);
    else:
        f[1] := (0, .5(abs(zz4-zz1) +-+ abs(zz2-zz1)));
    fi;
    f2 := -f1;
    for i := 1 upto 2:
        drawdot (f[i] rotated angle(zz2-zz1) shifted .5(zz1 + zz3)) withpen pencircle scaled 2;
    endfor;

    path line;
    numeric i;
    for i = ceiling(xpart zero_minimum) upto floor(xpart zero_maximum):
        line := (i * u, ypart zero_minimum * u) -- (i * u, ypart zero_maximum * u);
        if i = 0:
            drawarrow line withpen pencircle scaled 1.5;
        else:
            draw line dashed evenly;
        fi;
        if (i = 1) or (i = -1) or (i = 0):
            label.llft(TEX("$" & decimal(sc * i) & "$"), (i * u, 0));
        fi;
    endfor;

    for i = ceiling(ypart zero_minimum) upto floor(ypart zero_maximum):
        line := (xpart zero_minimum * u, i * u) -- (xpart zero_maximum * u, i * u);
        if i = 0:
            drawarrow line withpen pencircle scaled 1.5;
        else:
            draw line dashed evenly;
        fi;
        if (i = 1) or (i = -1):
            label.llft(TEX("$" & decimal(sc * i) & "$"), (0, i * u));
        fi;
    endfor;

    picture l;
    for i := 1 upto 4:
        l := TEX("$P_{" & decimal(i) & "}$");
        if ypart z[i] = ypart minimum:
            label.bot(l, zz[i]);
        elseif ypart z[i] = ypart maximum:
            label.top(l, zz[i]);
        elseif xpart z[i] = xpart minimum:
            label.lft(l, zz[i]);
        else:
            label.rt(l, zz[i]);
        fi;
    endfor;
    
    % capture the drawn picture, restore old currentpicture, stamp the captured picture into it
    _p := currentpicture shifted -llcorner(currentpicture);
    currentpicture := _oldpic;
    addto currentpicture also _p;

    % return the captured picture
    _p
enddef;

beginfig(1);
    z1 = (1, 1);
    z2 = (4, 1);
    z3 = (4, 4);
    z4 = (1, 4);
    draw create_sample(z)(4);
endfig;

beginfig(2);
    z1 = (0, -1);
    z2 = (-2, 13);
    z3 = (-30, 9);
    z4 = (-28, -5);
    draw create_sample(z)(4);
endfig;

bye
