#PYTHON hatWrapper '''For more info: https://udel.edu/~mm/hat/ The famous 1981 hat can be drawn as originally shown in the old magazine ads, or you can choose number of slices and pixel width of hat. Having chosen width, height is calculated to maintain a 320x200 ratio. Mike Markowski, mike.ab3ap@gmail.com Oct 2023 ''' import hpprime as h import linalg as la import math as m fg=0x00ff00; bg=0x000000 # Fond memories of CRTs. :-) g0=0 # Default graphic variable. def main(): h.fillrect(g0,0,0,320,240,bg,bg) # Clear screen. scrX=320 # Default width, pixels. nSlices=64 # Default number of slices, -nSlices to nSlices-1. while True: h.eval('drawmenu("Hat", "Cuts", "Width", "", "Clear", "Exit")') m = mousePt() # Get user screen tap coordinates. b = softPick(m) # -1 if not a soft menu tap. if b == 0: hat(scrX,nSlices) elif b == 1: nSlices=cuts() elif b == 2: scrX=hatWidth() elif b == 4: h.fillrect(g0,0,0,320,240,bg,bg) # Clear screen. elif b == 5: break def cuts(): n = h.eval('input(S,"Number of Slices","n=","Hat slices, -n to n",64,64);S') h.fillrect(g0,0,0,320,240,bg,bg) # Clear screen. return n def hat(scrX=320,nSlices=64): # Original values from Commodore PET ad. x0=320; y0=200 # Screen res math originally targeted. r0=144 # Radius of hat. h0=56 # Height of hat. n0=64 # Number of slices,2x64 total. a0=3*la.pi/2 # Max angle of sinusoidal to revolve,270 deg. # New values for any size hat. scrY=round(scrX*y0/x0) # Height,using old screen ratio. hatHgt=h0/y0*scrY # New hat height. hatRad=r0/x0*scrX # New hat radius. stagger=n0/x0*scrX # Scale layer stagger for fake 3d. xf=a0/hatRad # Radians per vertical point on hat. # Make the hat! h.fillrect(g0,0,0,320,240,bg,bg) # Clear screen. for zSlice in la.arange(-1,1,1/nSlices): # Slices, back to front. z=zSlice*hatRad # -hatRad to hatRad. xl=round(m.sqrt(hatRad**2 - z**2)) # Endpoints of hat, this slice. for x in range(-xl,xl+1): # Step through points on slice. # Hat-like surface of revolution. xt=xf*m.sqrt(x**2 + z**2) # Dist along hat's sinusoid. y=(m.sin(xt) + 0.4*m.sin(xt*3)) * hatHgt # Pt on surf of hat. # Stagger layer for fake 3d. x1=x + stagger*zSlice + scrX/2 y1=y - stagger*zSlice + scrY/2 y1=scrY - y1 # Flip vertically. h.pixon(g0,x1,y1,fg) h.line(g0,x1,y1+1,x1,scrY-1,bg) # Erase previous slice. def hatWidth(): n = h.eval('input(W,"Hat Width","n=","Image width, pixels (320 max)",320,320);W') h.fillrect(g0,0,0,320,240,bg,bg) # Clear screen. return n def mousePt(): while h.eval('MOUSE(1)')>=0: pass # Clear event queue. while True: m = h.eval('MOUSE') # m is [[...], [...]] if len(m[0]) > 0: # Non-empty after mouse click. return m[0] # [x, y, xOrig, yOrig, type] def softPick(pt): # pt is [x, y, xOrig, yOrig, type] x,y = pt[0], pt[1] if y<220: return -1 # Not in soft menu region. if x<= 52: return 0 if x<=105: return 1 if x<=158: return 2 if x<=211: return 3 if x<=264: return 4 return 5 main() #end EXPORT hat() BEGIN PYTHON(hatWrapper); END;