#! /usr/bin/gawk -f # Last edited on 2023-09-05 11:51:20 by stolfi # Caller must define (with "-v") the variables {szx}, {szy}, {lwd}, and {rad}. # The latter must be greater than {lwd/2}. BEGIN{ ro = rad + lwd/2 oval_path(szx, szy, ro, +1); printf "m %+.3f,%+.3f\n", lwd, lwd; ri = rad - lwd/2 oval_path(szx - 2*lwd, szy - 2*lwd, ri, -1); printf "m %+.3f,%+.3f\n", -lwd, -lwd; } function oval_path(szx,szy,rr,dir,wx,wy) { wx = szx - 2*rr wy = szy - 2*rr if (dir == +1) { printf "m %+.3f,%+.3f\n", rr, 0; oval_side(wx, +1,0, 0,+1, rr); oval_side(wy, 0,+1, -1,0, rr); oval_side(wx, -1,0, 0,-1, rr); oval_side(wy, 0,-1, +1,0, rr); printf "m %+.3f,%+.3f\n", -rr, 0; } else { printf "m %+.3f,%+.3f\n", 0,rr; oval_side(wy, 0,+1, +1,0, rr); oval_side(wx, +1,0, 0,-1, rr); oval_side(wy, 0,-1, -1,0, rr); oval_side(wx, -1,0, 0,+1, rr); printf "m %+.3f,%+.3f\n", 0,-rr; } printf "Z\n" } function oval_side(m,dx,dy,ex,ey,rr, dm,dc,ds,em,ec,es,a,b) { # Draws a side of the oval from the current corner point {p} # to the point {q = p+(m+rr)*(dx,dy)+rr*(ex,ey)}, skipping the initial curve and # adding the final curve with radius {rr} - turning towards # the direction {(ex,ey)} which must be orthogonal to {(dx,dy)}. # Leaves the current point at {q}. a = 0.7; b = 1-a; printf "l %+.3f,%+.3f\n", m*dx, m*dy; printf "c %+.3f,%+.3f %+.3f,%+.3f %+.3f,%+.3f\n", \ dx*a*rr, dy*a*rr, dx*rr + ex*b*rr, dy*rr + ey*b*rr, dx*rr + ex*rr, dy*rr + ey*rr; printf "\n" }