Advertisement
Guest User

Untitled

a guest
Aug 12th, 2018
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. %!PS-Adobe-2.0
  2. %%BoundingBox: 0 0 400 400
  3.  
  4. %%Page: 1 1
  5. 1.5 setlinewidth
  6.  
  7. /width 400 def % Largeur du dessin
  8. % point de fuite du dessin (Changez `y` pour voir le dessin se transformer, ex : 150)
  9. /perspectivex width 2 div def
  10. /perspectivey 165 def
  11.  
  12. % Note : On suppose l'horizon à 140 pour le reste du programme (tout les calculs lié sont déjà fait)
  13. % Note : On suppose la hauteur constante pour une determination des constantes "magiques" plus facile, alors que le programme s'adapte en largeur (cependant pas de maniere parfaite)
  14. % Il est recommandé de lire les fonctions dans le sens dans lequelles elles sont dessinées (voir tout en bas du fichier)
  15.  
  16. /pavage { % Pavage (lignes bleues sur le sol)
  17.     gsave
  18.         % Clip sur le rectangle du bas
  19.         newpath
  20.             0 0 moveto
  21.             width 0 rlineto
  22.             0 140 rlineto % 140 -> horizon
  23.             0 width sub 0 rlineto
  24.         closepath
  25.         clip
  26.        
  27.         18 1 40 { % Lignes horizontales, je commence a 18 car les lignes d'avants sont hors du cadre
  28.             /i exch def
  29.             /i i dup mul def % i = i^2
  30.            
  31.             % y = 250*(1 - 323.395 / i), la constante magique "323.395" a été determinée à la main en faisant de petits changements
  32.             % Mais ce qui est interessant c'est que la distance entres les lignes horizontales est proportionnelle à 1/x comme d'apres les loi de la perspective
  33.            
  34.             /y 250 1 323.395 i div sub mul def
  35.             newpath
  36.                 0 y moveto
  37.                 width 0 rlineto
  38.             closepath
  39.            
  40.             37 255 div                         % r = (37) / 255 (Le color picker que j'utilisais pour trouver les couleurs me les donnait dans le format entier)
  41.             132 y 2 div add 255 div            % g = (132 + y/2) / 255 (g tend vers 255 quand y tends vers +inf)
  42.             1                                  % b = 1
  43.             setrgbcolor
  44.            
  45.             4 y 75 div sub setlinewidth % width = 4 - y/75 (les lignes sont de plus en plus fines quand y augmente)
  46.             stroke
  47.         } for
  48.        
  49.        
  50.         -10 1 20 { % Lignes verticales (qui partent du point de perspective et vont vers l'infini)
  51.             /i exch def
  52.            
  53.             % x = -295 + i*90, autrement dit chaque ligne est espacée de 90 pixels au niveau de y = 0 (c'est le deuxième point)
  54.             /x -295 i 90 mul add def
  55.            
  56.             /lastx perspectivex def
  57.             /lasty perspectivey def
  58.            
  59.             % Le for suivant est une technique pour faire une ligne en couleur dégradée
  60.             % On décompose la ligne en sous parties (ici de 1% de la taille de base) que l'on dessine bout par bout avec une couleur qui varie
  61.             0 .01 1.01 {
  62.                 /ratio exch def % ratio correspond à l'étape (il varie entre 0 et 1 par step de 0.01)
  63.                
  64.                 /newx perspectivex 1 ratio sub mul x ratio mul add def % new = perspectivex * (1-ratio) + x * ratio, interpolation linéaire (car c'est une droite) entre x et perspectivex
  65.                 /newy perspectivey 1 ratio sub mul def                 % idem entre 0 et perspectivey
  66.                
  67.                 newpath
  68.                     lastx lasty moveto
  69.                     newx newy lineto
  70.                 closepath % On dessine le petit bout..
  71.                
  72.                 37 255 div                          % r = 37 / 255
  73.                 132 newy 100 div 50 mul add 255 div % g = (132 + 50*newy/100) (même formule que pour les lignes horizontales)
  74.                 1                                   % b = 1
  75.                 setrgbcolor
  76.                
  77.                 2.5 newy 140 div sub setlinewidth % linewidth = 2.5 - newy/140 (La taille des lignes diminue quand y augmente)
  78.                 stroke
  79.                
  80.                 /lastx newx def % On se rappelle des coordonnées actuelles
  81.                 /lasty newy def
  82.             } for
  83.         } for
  84.     grestore
  85. } def
  86.  
  87. /arbre { % utilisation : x y x2 y2 recur arbre luminance
  88.     /luminance exch def % Eclaircissement de l'arbre
  89.     5 dict begin        % On fait un dict car on va utiliser "arbre" recursivement, donc on veut définir les variables comme locales
  90.         /recur exch def     % Valeur de recursion, qui baisse de branche en branche
  91.         /y2 exch def        % Point d'arrivée
  92.         /x2 exch def
  93.         /y exch def         % Point de départ
  94.         /x exch def
  95.        
  96.         /diffx x2 x sub def % Vecteur de différence (arrivee-depart)
  97.         /diffy y2 y sub def
  98.        
  99.         /normx 0 diffy sub def % Normal au ve cteur de différence (utilisé pour les branches filles)
  100.         /normy diffx def
  101.        
  102.        
  103.         newpath % On set le path avec les coordonnées données
  104.             x y moveto
  105.             x2 y2 lineto
  106.         closepath
  107.        
  108.         % Pour le dessin de la branche je le décompose en deux strokes, l'exterieur et l'interieur qui ont deux couleurs différente
  109.        
  110.         /linewidth 3 recur add def % linewidth = 3 + recur .. quand recur est grand c'est qu'on est haut dans l'arbre (pres du tronc), donc les lignes sont plus epaisses
  111.        
  112.         gsave
  113.             linewidth setlinewidth
  114.             232 luminance add 255 div % r = (232 + luminance) / 255 On voit que luminance est utilisé pour ajuster la luminosité (une grande valeur va rendre l'arbre plus blanc
  115.             45 luminance add 255 div  % g = ( 45 + luminance) / 255
  116.             89 luminance add 255 div  % b = ( 89 + luminance) / 255
  117.             setrgbcolor
  118.             stroke % Premier trait (trait exterieur)
  119.         grestore
  120.         linewidth 1.5 div setlinewidth % Taille du second trait = 2/3*linewidth
  121.        
  122.         50 recur 25 mul add luminance add 255 div  % r = ( 50 + recur*25 + luminance) / 255 Les feuilles sont moins rouge que le tronc
  123.         255 recur 25 mul sub luminance add 255 div % g = (255 - recur*25 + luminance) / 255 Les feuilles sont plus vertes que les branches
  124.         50 luminance add 255 div                   % b = ( 50            + luminance) / 255 on garde la meme teinte de bleu
  125.         setrgbcolor
  126.         stroke
  127.        
  128.         recur 0 ge % On recursionne si recur >= 0
  129.         {
  130.             % On définit les coordonnées "d'envoie" en faisant la moyenne du vecteur de différence et de la normale, ce qui est censé donner un angle de 45 degrés
  131.             % Note : On fait une petite multiplication par 0.95 pour faire un arbre un peu plus compact (la taille de la branche d'après décroit exponentiellement)
  132.             /sendx x2 diffx normx add 2 div 0.95 mul add def % sendx = x2 + (diffx + normx) / 2 * 0.95
  133.             /sendy y2 diffy normy add 2 div 0.95 mul add def % sendy = y2 + (diffy + normy) / 2 * 0.95
  134.             x2 y2 sendx sendy recur 1 sub luminance arbre % On fait la branche avec une recursion = recursion-1
  135.            
  136.             /normx 0 normx sub def % On oppose la normale pour faire une branche dans l'autre sens
  137.             /normy 0 normy sub def % normey = -normey
  138.            
  139.             /sendx x2 diffx normx add 2 div 0.95 mul add def % sendx = x2 + (diffx + normx) / 2 * 0.95 (meme calcul)
  140.             /sendy y2 diffy normy add 2 div 0.95 mul add def % sendy = y2 + (diffy + normy) / 2 * 0.95
  141.             x2 y2 sendx sendy recur 1 sub luminance arbre % On envoie la deuxieme branche
  142.         } if
  143.     end % On relache les variables locales
  144. } def
  145.  
  146. /arbres {
  147.  
  148.     % Pour aligner les arbres selon la perspective (Et donc faire une sorte d'allée) j'ai utilisé le meme code que le tracé des lignes verticales pour le pavage.
  149.  
  150.    
  151.     /i 2 def % On prend la deuxieme ligne
  152.    
  153.     /x -295 i 90 mul add def
  154.    
  155.     /lastx perspectivex def
  156.     /lasty perspectivey def
  157.     /size 10 def % Taille de l'arbre
  158.    
  159.    
  160.     .25 .35 1.01 { % Meme code que les lignes.. sauf qu'on mets 3 arbres au lieu de 100 petits bouts
  161.         /ratio exch def
  162.        
  163.         /newx perspectivex 1 ratio sub mul x ratio mul add def
  164.         /newy perspectivey 1 ratio sub mul def
  165.  
  166.         /size size 30 add def % Les arbres qui sont plus pres de nous sont plus gros
  167.  
  168.         newx newy newx newy size add 5 ratio 5 mul add 105 size sub arbre % On note le recur = 5 + ratio * 5, les arbres plus pres de nous sont plus complexes
  169.                                                                           % Ainsi que le luminance = 105 - size, les arbres plus petits sont plus clairs (ils sont aussi plus loin)
  170.        
  171.     } for
  172.    
  173.     /i 9 def % On fait exactement le meme code pour une autre rangée (ici la 9e)
  174.    
  175.     /x -295 i 90 mul add def
  176.    
  177.     /lastx perspectivex def
  178.     /lasty perspectivey def
  179.     /size 10 def
  180.     .25 .35 1 {
  181.         /ratio exch def
  182.        
  183.         /newx perspectivex 1 ratio sub mul x ratio mul add def
  184.         /newy perspectivey 1 ratio sub mul def
  185.  
  186.         /size size 30 add def
  187.  
  188.         newx newy newx newy size add 5 ratio 5 mul add 105 size sub arbre
  189.     } for
  190. } def
  191.  
  192. /spirale {
  193.     /size exch def      % Nombre d'itérations a effectuer (angle total)
  194.     /speed exch def     % Inverse de la vitesse à laquelle la spirale s'éloigne du centre
  195.     /baseangle exch def % Décalage d'angle
  196.    
  197.     /basey exch def     % Point centrale de la spirale
  198.     /basex exch def
  199.     gsave
  200.         basex basey moveto % On va au point centrale
  201.         /dist 0 def % On est a 0 du centre au début
  202.        
  203.         /lastangle 0 def
  204.         /lastdist 0 def
  205.        
  206.        
  207.         0 3 size { % On itere en degré 3 par 3
  208.            
  209.             /angle exch baseangle add def % Angle = baseangle + stack (qui correspond a l'iteration)
  210.             /dist angle speed div def % dist = angle / speed
  211.            
  212.             newpath
  213.                 basex lastangle cos lastdist mul add % x = basex + cos(lastangle)*lastdist
  214.                 basey lastangle sin lastdist mul add % y = basey + sin(lastangle)*lastdist
  215.                 moveto
  216.                
  217.                 basex angle cos dist mul add % x = basex + cos(angle)*dist
  218.                 basey angle sin dist mul add % y = basey + sin(angle)*dist
  219.                 lineto
  220.             closepath
  221.            
  222.             2 setlinewidth % Largeur de la spirale
  223.            
  224.             /ratio 1 angle size div sub def % Le ratio correspond a la distance du centre
  225.             ratio .05 le {/ratio 0 def} if % if(ratio < 0.05) ratio = 0
  226.            
  227.             /ratio ratio dup dup mul mul def % ratio = ratio^3 (la transition est donc cubique pour un dégradé plus agréable)
  228.            
  229.             /y basey angle sin dist mul add def % y = basey + sin(angle)*dist
  230.             % y est utilisé pour le calcul des couleurs
  231.            
  232.             % Calcul de la couleur de la spirale par interpolation en utilisant ratio
  233.            
  234.             % r = ratio*couleur + (1-ratio)*couleur2
  235.             % Ici couleur est une constante et couleur2 correspond a la couleur de fond
  236.             % Ainsi, plus la spirale s'éloigne du centre plus elle prend la couleur du fond (ratio tends vers 0)
  237.            
  238.             238 255 div ratio mul % r = 238 / 255 (couleur au centre de la spirale)
  239.             .1 170 y sub 170 div y 50 mul sin 50 div add add 1 ratio sub mul % Couleur de fond qui dépend de y
  240.             % Voir la fonction "fond" pour la formule traduite en infix
  241.             add
  242.        
  243.             % Idem pour le bleu
  244.             98 255 div ratio mul
  245.             .1 1 ratio sub mul % Couleur de fond
  246.             add
  247.            
  248.             % Et pour le vert
  249.             139 255 div ratio mul
  250.             188 255 108 sub y 300 div mul sub 255 div 1 ratio sub mul % Couleur de fond
  251.             add
  252.             setrgbcolor
  253.            
  254.             stroke % On dessine le petit bout
  255.             /lastangle angle def
  256.             /lastdist dist def
  257.         } for
  258.     grestore
  259. } def
  260.  
  261. /aureole { % Correspond à la spirale derrière le soleil
  262.     gsave
  263.         newpath % On clip sur la partie supérieur
  264.             0 400 moveto
  265.             width 0 rlineto
  266.             0 -260 rlineto
  267.             0 width sub 0 rlineto
  268.         closepath
  269.         clip
  270.         width 2 div 170 0 50 12000 spirale % On dessine la spirale avec comme paramètres :
  271.         % x (centre) = width/2
  272.         % y (centre) = 170
  273.         % baseangle = 0
  274.         % speed = 50
  275.         % size = 12000 (l'angle va varier de 0 à 12000)
  276.     grestore
  277. } def
  278.  
  279. /point % Dessine un point sur le dessin aux coordonnées x, y
  280. {
  281.     /y exch def % Arguments
  282.     /x exch def
  283.     newpath
  284.         x y moveto
  285.         x .5 add y lineto
  286.     closepath % Petite ligne horizontale de taille 0.5
  287.     1 setgray
  288.     .5 setlinewidth
  289.     stroke
  290. } def
  291.  
  292. /couleurfond { % Renvoie la couleur de fond en fonction de y
  293.     1 dict begin
  294.         /y exch def
  295.         .1 200 y sub 200 div y 50 mul sin 30 div add add
  296.         %r = (200 - y)/200 + sin(y*50)/30 + .1
  297.         %C'est un dégradé classique avec une subtilité grace au sin
  298.         .1
  299.         %g = .1
  300.         188 255 108 sub y 300 div mul sub 255 div
  301.         %b = (188-(255-108)*(y/300))/255
  302.         % Dégradé classique b part de 188 puis tends vers 0 quand y augmente (mais plus lentement que le rouge   
  303.     end
  304. } def
  305.  
  306. /soleil { % Dessin du soleil
  307.     /basey 170 def % Hauteur du soleil (ici un peu au dessus de l'horizon)
  308.     -29 1 60 { % On dessine le soleil ligne à ligne (permet de faire un dégradé)
  309.         /y exch def % le for donne la valeur de la hauteur relative à la base
  310.        
  311.         % width = 60*sqrt(1-(y/60)^2) Largeur de la ligne en fonction de la hauteur
  312.         % Formule obtenue grâce au fait que la fonction y=sqrt(1-x^2) dessine un demi cercle
  313.        
  314.         /sunwidth 60 1 y 60 div dup mul sub sqrt mul def
  315.        
  316.         newpath
  317.             width 2 div sunwidth sub % x = width/2 - sunwidth (rappel : width correspond à la largeur de la fenetre)
  318.             basey y add % y = basey+y
  319.             moveto
  320.            
  321.             sunwidth 2 mul % decalagex = 2*sunwidth
  322.             0 % decalagey = 0
  323.             rlineto
  324.         closepath
  325.         1.5 setlinewidth
  326.        
  327.         /ratio y 30 add 90 div def % ratio = (y + 30)/90, ratio correspond au pourcentage de soleil dessiné
  328.        
  329.         % Ce ifelse permet de faire les "trous" dans le soleil, en dessinant le fond à la place du soleil selon une fonction qui devient négative sur les intervalles que je voulais.
  330.         % C'est donc pour ça qu'il y a un 0 le (<= 0) à la fin
  331.         % La fonction dépend de la hauter et est donc
  332.         % sin(y*((y / 2) + 50) + 20) + .2 (rappel : sin est en degré)
  333.         % Visualisation de la fonction :
  334.         % https://www.google.fr/?q=sin(pi*(y*((y+%2F+2)+%2B+50)+%2B+20)%2F180)+%2B+.2
  335.        
  336.         y 50 y 2 div add mul 20 add sin .2 add 0 le
  337.         y 15 le and % On ne coupe que si y <= 15
  338.         {
  339.             basey y add couleurfond % On rempli le trou avec la couleur de fond (pour écraser la spirale derrière le soleil)
  340.         }
  341.         {
  342.             % Pour la couleur du soleil en lui meme on fait juste une interpolation linéaire entre deux couleurs prises à la main
  343.             % couleur1 = 254, 246, 0 (une sorte de violet)
  344.             % couleur2 = 255, 45, 149 (un jaune)
  345.            
  346.             254 255 div ratio mul
  347.             255 255 div 1 ratio sub mul
  348.             add
  349.        
  350.             246 255 div ratio mul
  351.             45 255 div 1 ratio sub mul
  352.             add
  353.        
  354.             0 255 div ratio mul
  355.             149 255 div 1 ratio sub mul
  356.             add
  357.         }
  358.         ifelse
  359.        
  360.         setrgbcolor % on applique donc la couleur choisis
  361.  
  362.         stroke
  363.     } for
  364. } def
  365.  
  366. /fond { % Fonction qui dessine le dégradé de fond
  367.     0 0 moveto
  368.     0 1 width { % On dessine ligne à ligne
  369.         /y exch def
  370.         gsave
  371.             newpath
  372.                 0 y moveto
  373.                 width 0 rlineto
  374.             closepath % On mets le path pour la ligne
  375.            
  376.             y couleurfond
  377.             setrgbcolor
  378.            
  379.             stroke
  380.         grestore
  381.     } for
  382.    
  383. } def
  384.  
  385. /etoiles { % Dessin des étoiles en haut de l'image
  386.    
  387.     % Pour le dessin des étoiles, on coupe le ciel en 10 parties, puis plus on est haut dans le ciel plus cette partie à d'étoiles, celon la relation nb d'étoiles = (numéro_partie)^2
  388.    
  389.     0 1 11 { % on boucle sur les parties
  390.         /i exch def
  391.         /basey 200 i 20 mul add def % Le y de base vaut donc 200 + i*20 (la hauteur de l'image vaut 400 en tout, et les étoiles partent du millieu)
  392.        
  393.         i i mul { % On boucle i^2 fois
  394.             /x rand width mod def % On prend x au hasard entre 0 et width (x=rand(0, width))
  395.             /y basey rand 20 mod add def % On prend y = basey + rand(0, 20)
  396.             x y point % On dessine l'étoile
  397.         } repeat
  398.     } for
  399. } def
  400.  
  401. % Pipeline de render
  402.  
  403. fond    % Couleur de fond
  404. aureole % Spirale derrière le soleil
  405. pavage  % Pavage en perspective
  406. soleil  % Dessin du soleil
  407. arbres  % Dessin des arbres en allée
  408. etoiles % Dessin des étoiles en haut de l'écran
  409.  
  410. showpage
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement