input geometriesyr16 figure(0,0,17u,19u); trace papierisometrique withcolor gris; fin; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Lego boxes by Anthony Phan. % file: lego.mp % last modification: January 29, 2001. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Licence? Feel-free-to-send-me-a-postcard % % Anthony Phan, % % D\'epartement de Math\'ematiques, % SP2MI, T\'el\'eport 2, % Boulevard Marie et Pierre Curie, % BP 30179, % F-86962 Futuroscope-Chasseneuil cedex. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %animation=1; magnification=2; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Roegel macros for animation % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% FROM: %% version 1.0, 8 April 1998 %% {\bf Denis Roegel} ({\tt roegel@loria.fr}) %% This package provides definitions enabling the manipulation %% and animation of 3-dimensional objects. %% Such objects can be included in a \TeX{} file or used on web pages %% for instance. See the documentation enclosed in the distribution for %% more details. numeric xmin_,ymin_,xmax_,ymax_; def compute_bbox= if known xmin_: xmin_:=min(xmin_,xpart(llcorner(currentpicture))); ymin_:=min(ymin_,ypart(llcorner(currentpicture))); xmax_:=max(xmax_,xpart(urcorner(currentpicture))); ymax_:=max(ymax_,ypart(urcorner(currentpicture))); else: xmin_=xpart(llcorner(currentpicture)); ymin_=ypart(llcorner(currentpicture)); xmax_=xpart(urcorner(currentpicture)); ymax_=ypart(urcorner(currentpicture)); fi; enddef; boolean show_animation_parameters; show_animation_parameters=false; numeric paper_height; paper_height=29.7; % paper height in cm % show bounding box of an animation, in PostScript points % and parameters for animation script vardef show_animation_bbox= save trx,try,h,w,delta,pnmx,pnmy,pnmw,pnmh,res; res=36; % 36 dots per inch in bitmap w=xmax_-xmin_;h=ymax_-ymin_; if show_animation_parameters: message "animation bbox: (llx=" & decimal round(xmin_) & ",lly=" & decimal round(ymin_) & ",w=" & decimal round(w) & ",h=" & decimal round(h) & ")"; fi; if xmin_ <=20: trx=50-xmin_;else: trx=0;fi; if ymin_ <=20: try=50-ymin_;else: try=0;fi; if show_animation_parameters: message "translate parameters: " & decimal round(trx) & " " & decimal round(try); fi; xmin_:=xmin_+trx;ymin_:=ymin_+try; delta=10; pnmx=round(xmin_*(res/72)-delta); pnmy=round((paper_height/2.54*72-ymin_-h)*(res/72)-delta); pnmw=round(w*(res/72)+2*delta); pnmh=round(h*(res/72)+2*delta); if show_animation_parameters: message "pnmcut parameters (with -r36): " & decimal pnmx & " " & decimal pnmy & " " & decimal pnmw & " " & decimal pnmh; fi; write_script(round(trx),round(try), pnmx,pnmy,pnmw,pnmh,res,jobname,"create_animation.sh"); enddef; %%\newpage %%\title{Creation of a shell script to automate the animation} % This is UNIX targetted and may need to be customized. vardef write_script(expr trx,try,xmin,ymin,w,h,res,output,file)= save s; string s; def write_to_file(text arg)=write arg to file; enddef; write_to_file("#! /bin/sh"); write_to_file(""); write_to_file("/bin/rm -f "&output&".log"); write_to_file("for i in `ls "&output&".*| grep '"&output&".[0-9]'`;do"); if false: "endfor" fi % indentation hack for meta-mode.el write_to_file("echo $i"); write_to_file("echo '=============='"); s:="awk < $i '{print} /^%%Page: /{print "&ditto; s:=s&decimal trx&" "&decimal try&" translate\n"&ditto&"}' > $i.ps"; write_to_file(s); % ghostscript PostScript into ppm s:="gs -sDEVICE=ppmraw -sPAPERSIZE=a4 -dNOPAUSE "; s:=s&"-r"&decimal res &" -sOutputFile=$i.ppm -q -- $i.ps"; write_to_file(s); write_to_file("/bin/rm -f $i.ps"); % possible alternative: % |s:="mogrify -compress -crop " & decimal(w) & "x" & decimal(h);| % |s:=s&"+"& decimal(xmin) &"+"&decimal(ymin);| % |s:=s&" -colors 64 -format gif $i.ppm";| s:="ppmquant 64 $i.ppm | pnmcut "& decimal(xmin) &" "&decimal(ymin); s:=s&" "&decimal(w)&" "&decimal(h) &" | "; s:=s&"ppmtogif > `expr $i.ppm : '\(.*\)ppm'`gif"; write_to_file(s); write_to_file("/bin/rm -f $i.ppm"); write_to_file("done"); write_to_file("/bin/rm -f "&output&".gif"); s:="gifmerge -255,255,255 -10 -l1000 "; s:=s&output&".*.gif > "&output&".gif"; write_to_file(s); write_to_file("/bin/rm -f "&output&".*.gif"); write_to_file(EOF);% end of file enddef; %%\newpage %%\title{Standard animation definitions} % These definitions produce {\it one\/} image of some kind. extra_endfig:="compute_bbox"; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Personal part % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Les figures d\'efinies par ce programme % repr\'esente une tentative de programmation % tridimensionnelle avec MetaPost. Les trucs % essentiels sont l'usage d'un rep\`ere par % lequel s'effectue la projection sur le plan, % et l'affichage des faces dans le plan dont % le contour est orient\'e positivement qui % corespondent alors \`a des faces visibles. % % Le niveau math\'ematique correspondant % \`a ce programme devrait \^etre le niveau % premier cycle en sciences. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Param\`etres de projection % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Rep\`ere initial pair e_x,e_y,e_z,e_xi,e_yi,e_zi; e_xi=sqrt 0.5*dir 210; e_yi=sqrt 0.5*dir -30; e_zi=sqrt 0.5*dir 90; % trois coordonn\'ees du vecteur de profondeur, % il v\'erifie depth_xi*e_xi+depth_yi*e_yi+depth_zi*e_zi=(0,0); depth_xi:=-1; depth_yi:=-1; depth_zi:=-1; % Param\`etres d'\'eclairement % vecteur unitaire de l'origine \`a la source lumineuse light_xi=0; light_yi=0; light_zi=1; % r\'eglage du contraste light_min=0.25; light_max=1; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Param\`etres, unit\'es et mesures essentielles % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% color currentcolor; currentcolor=red; lego_unit :=magnification*0.8cm; % official lego_height :=1.2lego_unit; % official lego_plate_height:=0.4lego_unit; % official lego_thickness :=1/6lego_unit; lego_eps :=1/20lego_unit; lego_overshoot :=lego_plate_height-lego_thickness;%0.2133lego_unit; lego_diam :=lego_unit-2lego_thickness; lego_Diam :=(sqrt 2)*lego_unit-lego_diam; cyl_steps :=60; path upper_path, lower_path, temp_path; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Rotation du rep\`ere initial % selon des pr\'etendus angles d'Euler. % avec d\'etermination des facteurs d'ensoleillement. % et des facteurs de profondeur... % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% vardef euler(expr theta,phi,psi)= save ctheta,stheta,cphi,sphi,cpsi,spsi; ctheta=cosd theta; stheta=sind theta; cphi=cosd phi; sphi=sind phi; cpsi=cosd psi; spsi=sind psi; % e_x:= cphi*ctheta*e_xi + cphi*stheta*e_yi + sphi*e_zi; e_y:=-(cpsi*stheta+spsi*sphi*ctheta)*e_xi + (cpsi*ctheta-spsi*sphi*stheta)*e_yi + spsi*cphi*e_zi; e_z:=(spsi*stheta-cpsi*sphi*ctheta)*e_xi - (spsi*ctheta+cpsi*sphi*stheta)*e_yi + cpsi*cphi*e_zi; % light_x:= cphi*ctheta*light_xi + cphi*stheta*light_yi + sphi*light_zi; light_y:=-(cpsi*stheta+spsi*sphi*ctheta)*light_xi + (cpsi*ctheta-spsi*sphi*stheta)*light_yi + spsi*cphi*light_zi; light_z:=(spsi*stheta-cpsi*sphi*ctheta)*light_xi - (spsi*ctheta+cpsi*sphi*stheta)*light_yi + cpsi*cphi*light_zi; % depth_x:= cphi*ctheta*depth_xi + cphi*stheta*depth_yi + sphi*depth_zi; depth_y:=-(cpsi*stheta+spsi*sphi*ctheta)*depth_xi + (cpsi*ctheta-spsi*sphi*stheta)*depth_yi + spsi*cphi*depth_zi; depth_z:=(spsi*stheta-cpsi*sphi*ctheta)*depth_xi - (spsi*ctheta+cpsi*sphi*stheta)*depth_yi + cpsi*cphi*depth_zi; enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Nous ne remplissons une face que % si elle est orient\'ee positivement. % L'argument ``factor'' correspond \`a % l'\'eclairement. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% def fill_special(expr p,factor)= if turningnumber p>=0: fill p withcolor mycolor factor fi enddef; vardef mycolor expr factor= ((0.5*(1+factor))[light_min,light_max])*currentcolor enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % D\'etermination de l'ordre d'affichage (cylindres) % sur une ligne, sur un rectangle... % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% def ordered_row(expr e_n,e_m,depth_n,n)= if depth_n<0: for $=1 step 1 until n: row_command(e_n,e_m,$); endfor else: for $=n step -1 until 1: row_command(e_n,e_m,$); endfor fi enddef; def ordered_rows(expr depth_n,depth_m,n,m)= if depth_n<0: if depth_m<0: if depth_n0: fill_special(z1--z2--z3--z4--cycle,light_z); let row_command=teton_command; ordered_rows(depth_x,depth_y,n,m); else: let row_command=teton_command; ordered_rows(depth_x,depth_y,n,m); fill_special(z4'''--z3'''--z2'''--z1'''--cycle,-light_z); fill_special(z1''--z1'''--z2'''--z2''--cycle,light_y); fill_special(z3''--z3'''--z4'''--z4''--cycle,-light_y); fill_special(z1''--z4''--z4'''--z1'''--cycle,light_x); fill_special(z2''--z2'''--z3'''--z3''--cycle,-light_x); if (n>1) and (m>1): let row_command=cyl_command; ordered_rows(depth_x,depth_y,n-1,m-1); else: if (n>1) and (m=1): let row_command=stick_command; ordered_row(e_x,e_y,depth_x,n-1); fi if (n=1) and (m>1): let row_command=stick_command; ordered_row(e_y,e_x,depth_y,m-1); fi fi fill_special(z4'--z3'--z2'--z1'--z4'--z4''--z1''--z2'' --z3''--z4''--cycle,-light_z); fi % % faces lat\'erales externes % fill_special(z1--z1'--z2'--z2--cycle,-light_y); fill_special(z3--z3'--z4'--z4--cycle,light_y); fill_special(z1--z4--z4'--z1'--cycle,-light_x); fill_special(z2--z2'--z3'--z3--cycle,light_x); enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % On produit maintenant les figures \`a l'aide % d'une boucle si la variable animation est connue, % ou une seule figure sinon. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if known animation: for $=0 upto 99: beginfig($+100); "Brique lego"; euler($*3.6,0*3.6,-$*3.6); lego_box(4,1,0.75white); endfig; endfor show_animation_bbox; else: beginfig(2); "Brique lego"; euler(90,0,0); lego_box(4,2,0.5[jaune,blanc]); endfig; fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Every good thing comes to an % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end. end