1 %% =============================================================================
2 %% Fichier : mp-solid.mp
3 %% =============================================================================
4 %% Le fichier spatial d'Anthony Phan m'a permis de mettre certaines choses au
10 %% Constantes ------------------------------------------------------------------
13 c := 57.29578; % conversion d'un radian en degrés
15 color rouge, vert, bleu, jaune, noir, blanc, orange, rose, violet, ciel,
16 cielfonce, orangevif, gris, marron;
24 cielfonce = 0.9*(0.25,1,1);
26 orangevif = (1,0.25,0.1);
41 vardef Norm primary z =
42 abs (abs(Xpart z, Ypart z), Zpart z)
46 let Ypart = greenpart;
50 string typerepre,pointilles;
53 vardef Initialisation(expr r,t,p,d)=
70 vardef Oeil=(Rho*Aux7,Rho*Aux8,Rho*Aux2)
73 vardef sin(expr t) = sind(c*t) enddef;
75 vardef cos(expr t) = cosd(c*t) enddef;
77 vardef tan(expr t) = sin(t)/cos(t) enddef;
79 vardef exp(expr x) = mexp(256)**x enddef;
81 vardef Exp primary x = mexp(256)**x enddef;
83 vardef ln(expr t) = mlog(t)/256 enddef;
85 vardef log(expr t) = ln(t)/ln(10) enddef;
87 vardef ch(expr x)=(exp(x)+exp (-x))/2 enddef;
89 vardef sh(expr x)=(exp(x)-exp(-x))/2 enddef;
91 vardef th(expr x)=sh(x)/ch(x) enddef;
93 vardef arcsin(expr x)=%Définition mathématique en radian
94 pi*angle((sqrt(1-x**2),x))/180
97 vardef arccos(expr x)=%Définition mathématique en radian
98 pi*angle((x,sqrt(1-x**2)))/180
101 vardef arctan(expr x)=arcsin(x/(1++x))
108 %Coordonnées dans le repère Oeil
109 vardef GCoord(expr N)=
110 (-Xpart(N)*Aux1+Ypart(N)*Aux3,-Xpart(N)*Aux5-Ypart(N)*Aux6+Zpart(N)*Aux4,-Xpart(N)*Aux7-Ypart(N)*Aux8-Zpart(N)*Aux2+Rho)
113 unit:=1;%pour les mises à l'échelle :) Merci pst-solides3d
115 vardef Projette(expr M)=
116 %if typerepre="proj":
117 % unit*(DE*(Xpart(GCoord(M)/Zpart(GCoord(M))),(Ypart(GCoord(M))/Zpart(GCoord(M)))))
118 %elseif typerepre="persp":
119 unit*(DE*(Xpart(GCoord(M)),Ypart(GCoord(M))))
124 color Origine,Unitex,Unitey,Unitez;
129 drawoptions(dashed dashpattern(on 12bp off 6bp on 3bp off 6bp));
130 drawarrow Projette(Origine)--Projette(Unitex) withcolor blue;
131 drawarrow Projette(Origine)--Projette(Unitey) withcolor vert;
132 drawarrow Projette(Origine)--Projette(Unitez);
136 vardef TraceAxesD(expr xd,yd,zd)=
137 drawoptions(dashed dashpattern(on12bp off6bp on3bp off6bp));;
138 drawarrow Projette((0,0,0))--Projette((xd,0,0));
139 drawarrow Projette((0,0,0))--Projette((0,yd,0));
140 drawarrow Projette((0,0,0))--Projette((0,0,zd));
142 label(btex $x$ etex,Projette((xd+0.3,0,0)));
143 label(btex $y$ etex,Projette((0,yd+0.3,0)));
144 label(btex $z$ etex,Projette((0,0,zd+0.3)));
147 vardef TraceAxesDD(expr xd,yd,zd,xf,yf,zf)=
148 drawoptions(dashed evenly);
149 draw Projette((0,0,0))--Projette((xd,0,0));
150 draw Projette((0,0,0))--Projette((0,yd,0));
151 draw Projette((0,0,0))--Projette((0,0,zd));
153 drawarrow Projette((xd,0,0))--Projette((xf,0,0));
154 drawarrow Projette((0,yd,0))--Projette((0,yf,0));
155 drawarrow Projette((0,0,zd))--Projette((0,0,zf));
156 label(btex $x$ etex,Projette((xf+0.3,0,0)));
157 label(btex $y$ etex,Projette((0,yf+0.3,0)));
158 label(btex $z$ etex,Projette((0,0,zf+0.3)));
161 primarydef u Vectprod v =
162 (Ypart u * Zpart v - Zpart u * Ypart v,
163 Zpart u * Xpart v - Xpart u * Zpart v,
164 Xpart u * Ypart v - Ypart u * Xpart v)
167 vardef Normal(expr vecun,vecde,vectr)=
170 P1:=redpart(vecde-vecun);
171 P2:=greenpart(vecde-vecun);
172 P3:=bluepart(vecde-vecun);
173 Q1:=redpart(vectr-vecun);
174 Q2:=greenpart(vectr-vecun);
175 Q3:=bluepart(vectr-vecun);
176 aa=(P2*Q3-Q2*P3,P3*Q1-Q3*P1,P1*Q2-Q1*P2);
180 vardef ProduitScalaire(expr wec,mor)=
181 %Mexp(Mlog redpart(wec) Mmul Mlog redpart(mor))+Mexp(Mlog greenpart(wec) Mmul Mlog greenpart(mor))+Mexp(Mlog bluepart(wec) Mmul Mlog bluepart(mor))
182 Xpart(wec)*Xpart(mor)+Ypart(wec)*Ypart(mor)+Zpart(wec)*Zpart(mor)
184 %pour les rotations et translations
186 vardef RotX(expr ptx)=
187 (Xpart(ptx),Ypart(ptx)*cosd(angx)-Zpart(ptx)*sind(angx),Ypart(ptx)*sind(angx)+Zpart(ptx)*cosd(angx))
190 vardef RotY(expr ptx)=
191 (Xpart(ptx)*cosd(angy)+Zpart(ptx)*sind(angy),Ypart(ptx),-Xpart(ptx)*sind(angy)+Zpart(ptx)*cosd(angy))
194 vardef RotZ(expr ptx)=
195 (Xpart(ptx)*cosd(angz)-Ypart(ptx)*sind(angz),Xpart(ptx)*sind(angz)+Ypart(ptx)*cosd(angz),Zpart(ptx))
198 vardef RotXYZ(expr ptx)=
199 RotZ(RotY(RotX(ptx)))
208 vardef VT(expr t)=Fp(t)/Norm(Fp(t))
211 vardef VN(expr t)=Fd(t)/Norm(Fd(t))
214 vardef VBN(expr t)=VT(t) Vectprod VN(t)
219 pair coinbg,coinbd,coinhd,coinhg;
222 def feuille(expr xa,ya,xb,yb) =
223 feuillet := (xa,ya)--(xa,yb)--(xb,yb)--(xb,ya)--cycle;
229 z.so=(xpart(coinbg/1cm),ypart(coinbg/1cm));
230 z.ne=(xpart(coinhd/1cm),ypart(coinhd/1cm));
232 extra_endfig := "clip currentpicture to feuillet;" & extra_endfig;
235 def figureespace(expr xa,ya,xb,yb) =
238 feuille(xa,ya,xb,yb);
239 _tfig:= if (xb-xa)>(yb-ya): xb-xa else: yb-ya fi;
247 def QS(expr ndeb,nfin)=
253 for i=(ndeb+1) upto nfin:
256 x:=cpt[m];cpt[m]:=cpt[i];cpt[i]:=x;
259 x:=cpt[m];cpt[m]:=cpt[ndeb];cpt[ndeb]:=x;
274 vardef DessineObjetNew=
276 %on détermine les zmax dans le repère spatial de l'écran
278 Fc[k].iso:=(0,0,0) for l=1 upto ns[k][0]:
281 Fc[k].iso:=Fc[k].iso/ns[k][0];
284 %ALT[k]=-Zpart(GCoord(Fc[k].iso));
286 for l=1 upto ns[k][0]:
287 t:=-Zpart(GCoord(Fc[k][l]));
295 %On trie suivant les zmax
300 draw for l=1 upto ns[cpt[k]][0]:
301 Projette(Fc[cpt[k]][l])--
303 cycle if Vue[cpt[k]]=false: dashed evenly fi;
309 fill for l=1 upto ns[cpt[k]][0]:
310 Projette(Fc[cpt[k]][l])--
314 lumin(cpt[k])*Hsvtorgb(((cpt[k]/apj)*360,satu,lum))
316 lumin(cpt[k])*outcolor
319 draw for l=1 upto ns[cpt[k]][0]:
320 Projette(Fc[cpt[k]][l])--
326 fill for l=1 upto ns[cpt[k]][0]:
327 Projette(Fc[cpt[k]][l])--
332 lumin(cpt[k])*Hsvtorgb(((cpt[k]/apj)*360,satu,lum))
334 lumin(cpt[k])*outcolor
337 lumin(cpt[k])*incolor
340 draw for l=1 upto ns[cpt[k]][0]:
341 Projette(Fc[cpt[k]][l])--
350 color Fc[][];%représente les sommets des différentes faces;
352 invnormale=1;%Parfois dans la lecture des fichiers OFF, il est nécessaire d'opposer la normale pour obtenir un bon intérieur-extérieur
353 boolean OFF,OBJ;%pour utiliser la lumière "correctement"
357 vardef LectureOFF(expr nomsolide)=
359 %Détermination du nombre de sommets et de faces.
361 s_=readfrom nomsolide;
365 t_ := if ss1="%": 0 else: 1 fi;
367 ss[incr t_] := loptok s_;
372 NbS:=round(Mexp Mlog_str ss1);
373 NF:=round(Mexp Mlog_str ss2);
374 message("Il y a "&decimal(NbS)&" sommets.");
375 message("Il y a "&decimal(NF)&" faces au total.");
376 %Détermination des coordonnées des sommets
377 message("Création des sommets.");
378 s_:=readfrom nomsolide;
381 s_:=readfrom nomsolide;
384 n_ := if ss1="%": 0 else: 1 fi;
386 ss[incr n_] := loptok s_;
391 Sommet[k]:=(Mexp ((Mlog_str ss1) Mdiv (Mlog echelle)),Mexp ((Mlog_str ss3) Mdiv (Mlog echelle)),Mexp ((Mlog_str ss2) Mdiv (Mlog echelle)));
392 %Sommet[k]:=(Mexp (Mlog_str ss1),Mexp (Mlog_str ss3),Mexp (Mlog_str ss2))/echelle;
393 %Sommet[k]:=(Mexp (Mlog_str ss1)/echelle,Mexp (Mlog_str ss3)/echelle,Mexp (Mlog_str ss2)/echelle);
397 s_:=readfrom nomsolide;
400 n_ := if ss1="%": 0 else: 1 fi;
402 ss[incr n_] := loptok s_;
407 Sommet[k]:=(Mexp ((Mlog_str ss1) Mdiv (Mlog echelle)),Mexp ((Mlog_str ss3) Mdiv (Mlog echelle)),Mexp ((Mlog_str ss2) Mdiv (Mlog echelle)));
408 %Sommet[k]:=(Mexp (Mlog_str ss1),Mexp (Mlog_str ss3),Mexp (Mlog_str ss2))/echelle;
409 %Sommet[k]:=(Mexp (Mlog_str ss1)/echelle,Mexp (Mlog_str ss3)/echelle,Mexp (Mlog_str ss2)/echelle);
412 message("Création des faces.");
413 %Détermination des faces
416 for nf=-4000 upto (-4000+NF)-1:
417 s_:=readfrom nomsolide;
420 n_ := if ss1="%": 0 else: 1 fi;
422 ss[incr n_] := loptok s_;
428 ns[apj][0]:=Mexp Mlog_str ss1;%pour savoir le nb de sommets par face
429 for nl=1 upto ns[apj][0]:
430 Fc[apj][nl]:=Sommet[round(Mexp Mlog_str ss[nl+1])];
433 cc:=invnormale*Normal(Fc[apj][1],Fc[apj][2],Fc[apj][3]);
434 if (ProduitScalaire(dd,cc)>=0):
445 message("Faces vues déterminees : il y en a "&decimal(nbfvues)&".");
450 vardef LectureOBJ(expr nomfichier)=
457 s_:=readfrom nomfichier;
463 ss[incr n_] := loptok s_;
466 Sommet[nbss]:=(Mexp((Mlog_str ss1) Mdiv (Mlog echelle)),Mexp ((Mlog_str ss3) Mdiv (Mlog echelle)),Mexp ((Mlog_str ss2) Mdiv (Mlog echelle)));
471 ss[incr n_] := loptok s_;
475 for k=1 upto ns[apj][0]:
477 Fc[apj][ns[apj][0]-k+1] := Sommet[round(Mexp(Mlog_str ss[k]))]
478 %if unknown OTFc.@[apj][OTFc.@[apj].nb-k+1]:
479 % show OTFc.@[apj][OTFc.@[apj].nb-k+1];
482 Fc[apj][k] := Sommet[round(Mexp(Mlog_str ss[k]))]
483 %if unknown OTFc.@[apj][k]:
484 % show OTFc.@[apj][k];
488 if ProduitScalaire(Oeil-Fc[apj][1],Normal(Fc[apj][1],Fc[apj][2],Fc[apj][3]))>=0:
502 closefrom nomfichier;
509 vardef Tube(expr Fn,dp,ds,rayon,tmin,nbp,pas)=%f,f',f'',rayon du tube,paramètre départ,nb points, pas
512 scantokens("vardef F(expr t)="&Fn&" enddef;");
513 scantokens("vardef Fp(expr t)="&dp&" enddef;");
514 scantokens("vardef Fd(expr t)="&ds&" enddef;");
516 %nb point sur le cercle
520 G[l][k]=F(tmin+l*pas)+rayon*(cosd(k*(360/nb))*VN(tmin+l*pas)+sind(k*(360/nb))*VBN(tmin+l*pas));
529 Fc[apj][2]:=G[l][k+1];
530 Fc[apj][3]:=G[l+1][k+1];
531 Fc[apj][4]:=G[l+1][k];
532 Fc[apj].iso:=(Fc[apj][1]+Fc[apj][2]+Fc[apj][3]+Fc[apj][4])/4;
533 ALT[apj]:=-Zpart(GCoord(Fc[apj][1]));
540 Projette(Fc[cpt[k]][l])--
542 cycle withcolor if arcenciel: lumin(cpt[k])*Hsvtorgb((floor((cpt[k]/apj)*360),satu,lum))
543 else: lumin(cpt[k])*outcolor fi;
545 Projette(Fc[cpt[k]][l])--
547 cycle withpen pencircle scaled0.25bp;
554 %pour les tubes new :)
555 vardef T(expr t)=Fp(t)
558 vardef VTn(expr t)=if Norm(T(t))=0:
568 __VN=T(t) Vectprod ((T(t+nn)-T(t-nn))/2);
572 __VN:=__VN/Norm(__VN);
573 if ProduitScalaire(VNbisprec[t-nn],__VN)>0:
574 _VNBis=__VN/Norm(__VN)
576 _VNBis=-(__VN/Norm(__VN))
583 vardef VBNn(expr t)=VTn(t) Vectprod VNn(t)
586 vardef Tuben(expr Fn,dp,rayon,tmin,nbp,pas)=%f,f',f'',rayon du tube,paramètre départ,nb points, pas
589 scantokens("vardef F(expr t)="&Fn&" enddef;");
590 scantokens("vardef Fp(expr t)="&dp&" enddef;");
592 %nb point sur le cercle
595 %pour gérer le "flip" aux points d'inflexion
597 VNbisprec[tmin-nn]=T(tmin-nn) Vectprod ((T(tmin)-T(tmin-2*nn))/2);
602 G[l][k]=F(tmin+l*pas)+rayon*(cosd(k*ang)*VNn(tmin+l*pas)+sind(k*ang)*VBNn(tmin+l*pas));
611 Fc[apj][2]:=G[l][k+1];
612 Fc[apj][3]:=G[l+1][k+1];
613 Fc[apj][4]:=G[l+1][k];
614 Fc[apj].iso:=(Fc[apj][1]+Fc[apj][2]+Fc[apj][3]+Fc[apj][4])/4;
615 ALT[apj]:=-Zpart(GCoord(Fc[apj].iso));
622 Projette(Fc[cpt[k]][l])--
624 cycle withcolor if arcenciel: lumin(cpt[k])*Hsvtorgb((floor((cpt[k]/apj)*360),satu,lum))
625 else: lumin(cpt[k])*outcolor fi;
627 Projette(Fc[cpt[k]][l])--
629 cycle withpen pencircle scaled0.25bp;
636 vardef Fonction(expr fn,tmin,tmax,pas)=%fonction
637 scantokens("vardef F(expr t)="&fn&" enddef;");
641 for k=tmin+pas step pas until tmax:
647 color outcolor,incolor,outcolorbis;
652 vardef Sparam(expr fn,umin,umax,upas,vmin,vmax,vpas)=%fonction
655 scantokens("vardef Famille(expr u,v)="&fn&" enddef;");
658 %On crée les facettes et on calcule la profondeur en Z.
659 for k=umin step upas until umax:
660 for l=vmin step vpas until vmax:
663 Fc[apj][1]:=Image(Famille(k+upas,l));
664 Fc[apj][2]:=Image(Famille(k,l));
665 Fc[apj][3]:=Image(Famille(k,l+vpas));
666 Fc[apj][4]:=Image(Famille(k+upas,l+vpas));
667 Fc[apj].iso:=(Fc[apj][1]+Fc[apj][3])/2;%(Fc[apj][1]+Fc[apj][2]+Fc[apj][3]+Fc[apj][4])/4;
668 ALT[apj]:=-Zpart(GCoord(Fc[apj].iso));
669 if ProduitScalaire(Oeil-Fc[apj].iso,invnormale*Normal(Fc[apj].iso,Fc[apj][1],Fc[apj][2]))>=0:
676 %On range les faces par un QS en fonction de leur profondeur
678 %On affiche toutes les faces par ordre décroissant de profondeur.
682 Projette(Fc[cpt[k]][l])--
684 cycle withcolor if Vue[cpt[k]]:
685 if arcenciel: lumin(cpt[k])*Hsvtorgb((floor((cpt[k]/apj)*360),satu,lum))
686 else: lumin(cpt[k])*outcolor fi
687 else:lumin(cpt[k])*incolor fi;
689 Projette(Fc[cpt[k]][l])--
698 vardef Revolution(expr fn,umin,umax,upas,vmin,vmax,vpas)=
699 Sparam("(xpart(point(u) of "&fn&")*cos(v),xpart(point(u) of "&fn&")*sin(v),ypart(point(u) of "&fn&"))",umin,umax,upas,vmin,vmax,vpas)
702 boolean traits;%sur une idée d'Herbert Voss à propos de pst-solides :)
703 %sert à désactiver le tracer des traits
704 %15/07/08:pour l'instant implanter uniquement pour les surfaces en z
707 boolean arcenciel;%pour essayer d'obtenir des dégradés tels que pst-solides :)
713 vardef SurfZ(expr fn,xmin,xmax,ymin,ymax,nblignes,nbpoints)=
719 scantokens("vardef Fz(expr X,Y)="&fn&" enddef;");
721 IncX:=(xmax-xmin)/nbpoints;
722 IncY:=(ymax-ymin)/nblignes;
723 color Yc[][],Xc[][],Fc[][];
724 for ligne=0 upto nblignes:
727 Yc[ligne][0]=(x,y,Fz(x,y));
728 for k=1 upto nbpoints:
729 Yc[ligne][k]=((xmin+k*IncX,y,Fz(xmin+k*IncX,y)));
732 %for ligne=0 step 3 until nbpoints:
733 % x:=xmax-ligne*IncX;
734 % for k=0 step 3 until nblignes:
735 % Xc[ligne div 3][k div 3]=(x,ymin+k*IncY,Fz(x,ymin+k*IncY));
738 for k=0 upto (nblignes-1):
739 for l=0 step 3 until (nbpoints-3):
742 Fc[apj][1]:=Yc[k][l];
743 Fc[apj][2]:=Yc[k][l+3];
744 Fc[apj][3]:=Yc[k+1][l+3];
745 Fc[apj][4]:=Yc[k+1][l];
746 Fc[apj].iso:=(Fc[apj][1]+Fc[apj][2]+Fc[apj][3]+Fc[apj][4])/4;
747 ALT[apj]:=-Zpart(GCoord(Fc[apj].iso));
748 if ProduitScalaire(Oeil-Fc[apj].iso,Normal(Fc[apj].iso,Fc[apj][2],Fc[apj][1]))>=0:
755 %On range les faces par un QS en fonction de leur profondeur
757 %On affiche toutes les faces par ordre décroissant de profondeur.
759 pickup pencircle scaled 0.25bp;
762 Projette(Fc[cpt[k]][l])--
764 cycle withcolor if Vue[cpt[k]]:
765 if arcenciel: lumin(cpt[k])*Hsvtorgb((floor((cpt[k]/apj)*360),satu,lum))
766 else:lumin(cpt[k])*outcolor fi
767 else: lumin(cpt[k])*incolor fi;
770 Projette(Fc[cpt[k]][l])--
781 vardef ObjetCube(expr ar)=
793 ns[1][0]:=4;Fc[1][1]:=Sommet1;Fc[1][2]:=Sommet2;Fc[1][3]:=Sommet3;Fc[1][4]:=Sommet4;
794 ns[2][0]:=4;Fc[2][1]:=Sommet4;Fc[2][2]:=Sommet3;Fc[2][3]:=Sommet8;Fc[2][4]:=Sommet5;
795 ns[3][0]:=4;Fc[3][1]:=Sommet1;Fc[3][2]:=Sommet4;Fc[3][3]:=Sommet5;Fc[3][4]:=Sommet6;
796 ns[4][0]:=4;Fc[4][1]:=Sommet5;Fc[4][2]:=Sommet8;Fc[4][3]:=Sommet7;Fc[4][4]:=Sommet6;
797 ns[5][0]:=4;Fc[5][1]:=Sommet2;Fc[5][2]:=Sommet7;Fc[5][3]:=Sommet8;Fc[5][4]:=Sommet3;
798 ns[6][0]:=4;Fc[6][1]:=Sommet1;Fc[6][2]:=Sommet6;Fc[6][3]:=Sommet7;Fc[6][4]:=Sommet2;
800 %Détermination des faces
805 cc:=invnormale*Normal(Fc[nf][1],Fc[nf][2],Fc[nf][3]);
806 if (ProduitScalaire(dd,cc)>=0):
814 %coloriage et lumière
815 vardef Hsvtorgb(expr CC)=%CC couleur donnée en hsv d'après http://en.wikipedia.org/wiki/HSL_color_space
818 SSw:=floor(Xpart(CC)/60);
820 SSf:=(Xpart(CC)/60)-floor(SSw);
824 SSq:=SSv*(1-SSf*SSs);
825 SSt:=SSv*(1-(1-SSf)*SSs);
826 if SSh=0: $=(SSv,SSt,SSp) elseif SSh=1:$=(SSq,SSv,SSp) elseif SSh=2:$=(SSp,SSv,SSt) elseif SSh=3:$=(SSp,SSq,SSv) elseif SSh=4:$=(SSt,SSp,SSv) elseif SSh=5:$=(SSv,SSp,SSq) fi;
830 marron=Hsvtorgb((60,1,0.3));
840 vardef lumin(expr nbt)=
847 uu=Lumiere-Fc[nbt].iso;
849 vv=invnormalelum*Normal(Fc[nbt].iso,Fc[nbt][1],Fc[nbt][2]);
853 if (surfz) or (Spar) or (OFF) or (OBJ):
854 $=intensite*abs(ProduitScalaire(vv,uu))
856 $=intensite*(ProduitScalaire(vv,uu));
868 %%Transparence fait par Anthony Phan
869 picture alphapict_; alphapict_=nullpicture;
870 color fillcolor; fillcolor=gris;
871 fgalpha := 0.5; % usual alpha parameter
872 bgalpha:= 1; % alpha parameter with respect to the background
874 vardef transparence expr c =
875 alphapict_ := nullpicture;
876 alphafill_(currentpicture, c);
877 addto currentpicture also alphapict_;
880 def alphafill_(expr p, c) =
882 save p_, xmax_, xmin_, ymax_, ymin_; picture p_;
884 (xmin_, ymin_) = llcorner c; (xmax_, ymax_) = urcorner c;
885 addto p_ contour c withcolor bgalpha[background, fillcolor];
887 numeric xmin__, xmax__, ymin__, ymax__;
888 (xmin__, ymin__) = llcorner p__; (xmax__, ymax__) = urcorner p__;
889 if (xmax__<= xmin_) or (xmin__ >= xmax_):
891 if (ymax__<= ymin_) or (ymin__ >= ymax_):
893 if (not clipped p__) and (not bounded p__):
894 addto p_ also p__ withcolor
895 fgalpha[(redpart p__, greenpart p__, bluepart p__),
898 begingroup save alphapict_;
899 picture alphapict_; alphapict_ = nullpicture;
900 alphafill_(p__, pathpart p__);
901 addto p_ also alphapict_;
908 addto alphapict_ also p_;