Guest User

Untitled

a guest
Apr 22nd, 2018
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Oz 14.48 KB | None | 0 0
  1.  
  2. declare
  3.  
  4.  
  5. [Test]={Link ['C:/Users/Xavier/Desktop/testProjet140.ozf']}
  6.  
  7.  
  8. fun {SetLastSubAnim Animation To}
  9.    case Animation
  10.    of nil then
  11.       To
  12.    [] translate(dx:Dx dy:Dy 1:SubAnimation) then
  13.       translate(dx:Dx dy:Dy 1:{SetLastSubAnim SubAnimation To})
  14.    [] scale(rx:Rx ry:Ry 1:SubAnimation) then
  15.       scale(rx:Rx ry:Ry 1:{SetLastSubAnim SubAnimation To})
  16.    [] rotate(angle:Angle 1:SubAnimation) then
  17.       rotate(angle:Angle 1:{SetLastSubAnim SubAnimation To})
  18.    end
  19. end
  20. fun {SimplifyTrough Animation Parent Result} % Renvoi une liste d'animation
  21.       case Animation
  22.       of primitive(color:_ kind:_) then
  23.          {SetLastSubAnim Parent Animation}|Result
  24.       [] translate(dx:Dx dy:Dy 1:SubAnimations) then
  25.          {SimplifyAccumulateSiblings SubAnimations {SetLastSubAnim Parent translate(dx:Dx dy:Dy 1:nil)} Result}
  26.       [] scale(rx:Rx ry:Ry 1:SubAnimations) then
  27.          {SimplifyAccumulateSiblings SubAnimations {SetLastSubAnim Parent scale(rx:Rx ry:Ry 1:nil)} Result}
  28.       [] rotate(angle:Angle 1:SubAnimations) then
  29.          {SimplifyAccumulateSiblings SubAnimations {SetLastSubAnim Parent rotate(angle:Angle 1:nil)} Result}
  30.       end
  31. end
  32.  
  33. fun {SimplifyAccumulateSiblings Animations Parent Result} % Renvoi une liste d'animation
  34.    case Animations
  35.    of ActualAnim|nil then
  36.       {SimplifyTrough ActualAnim Parent Result}
  37.    [] ActualAnim|NextAnims then
  38.       {SimplifyAccumulateSiblings NextAnims Parent {SimplifyTrough ActualAnim Parent Result}}
  39.    else % Why ?
  40.       Animations
  41.    end
  42. end
  43.  
  44.  
  45. fun {SimplifySiblings Animations}
  46.    {SimplifyAccumulateSiblings Animations nil nil}
  47. end
  48.  
  49.  
  50. % Pré : Angle est l'angle de la rotation, Point est un point (x,y)
  51. % Post: renvoie les coordonnées du point après rotation d'angle Angle (grâce à la formule (x,y) = ((X*cos(Angle) - Y*sin(Angle)),(X*sin(Angle) + Y*cos(Angle)))
  52. fun {RotatePoint Angle Point}
  53.         local X Y in
  54.                 X = Point.x
  55.                 Y = Point.y
  56.                 pt(x:(X*{Float.cos Angle} - Y*{Float.sin Angle}) y:(X*{Float.sin Angle}+Y*{Float.cos Angle}))
  57.         end
  58. end
  59.  
  60. % Pré : List et Result sont des listes
  61. % Post : Ajoute les éléments de List à l'avant de Result en commençant par le premier et renvoie ensuite Result
  62. % Ex: List = [1 2 3] Result = [4 5]
  63. %     La fonction renvoie [3 2 1 4 5]
  64. fun {ReverseList List Result}
  65.         case List
  66.         of nil then Result
  67.         [] H|T then {ReverseList T H|Result}
  68.         end
  69. end
  70.  
  71. % Pré : Formule est une formule telle que décrite dans l'énoncé, Time est le temps
  72. % Post : renvoie le résultat de Formule
  73. fun {Parse Formule Time}
  74.         case Formule
  75.         of time then Time
  76.         [] plus(A B) then {Parse A Time}+{Parse B Time}
  77.         [] minus(A B) then {Parse A Time}-{Parse B Time}
  78.         [] times(A B) then {Parse A Time}*{Parse B Time}
  79.         [] 'div'(A B) then {Parse A Time}/{Parse B Time}
  80.         [] 'sin'(A) then {Float.sin {Parse A Time}}
  81.         [] 'cos'(A) then {Float.cos {Parse A Time}}
  82.         [] 'tan'(A) then {Float.tan {Parse A Time}}
  83.         [] 'exp'(A) then {Float.exp {Parse A Time}}
  84.         [] 'log'(A) then {Float.log {Parse A Time}}
  85.         [] 'neg'(A) then ~{Parse A Time}
  86.         [] 'eq'(A B) then if {Parse A Time} == {Parse B Time} then
  87.                              1.0
  88.                           else 0.0
  89.                           end
  90.         []'ne'(A B) then if {Parse A Time} == {Parse B Time} then
  91.                             0.0
  92.                          else 1.0
  93.                          end
  94.         []'lt'(A B) then if {Parse A Time} < {Parse B Time} then
  95.                             1.0
  96.                          else 0.0
  97.                          end
  98.         [] 'le'(A B) then if {Parse A Time} =< {Parse B Time} then
  99.                              1.0
  100.                           else 0.0
  101.                           end
  102.         [] 'gt'(A B) then if {Parse A Time} > {Parse B Time} then
  103.                              1.0
  104.                           else 0.0
  105.                           end
  106.         [] 'ge'(A B) then if {Parse A Time} >= {Parse B Time} then
  107.                              1.0
  108.                           else 0.0
  109.                           end
  110.         else
  111.                 Formule
  112.         end
  113. end
  114.  
  115. % Je te laisse commenter celle-ci je ne sais pas trop comment l'expliquer
  116. fun {TransformAccumulator Transformer Time ShapeFunction Result}
  117.                 local Shape P1 P2 P3 P4 in
  118.                         Shape = {ShapeFunction Time}
  119.                         case Shape
  120.                         of shape(color:C kind:K points:P) then
  121.                                 P1 = P.1
  122.                                 P2 = P.2.1
  123.                                 P3 = P.2.2.1
  124.                                 P4 = P.2.2.2.1
  125.                                 shape(color:C kind:K points:{Transformer P1 P2 P3 P4})
  126.                         end
  127.                 end
  128. end
  129.  
  130. % Pré : AllAnmis est une animation, Result est une liste (éventuellement vide)
  131. % Post : Renvoie une liste de fonction qui prennent le temps en paramètre et renvoient une forme
  132. % C'est une fonction récursive terminale
  133. fun {TransformAnimAccumulator AllAnims Result}
  134.         case AllAnims
  135.         of nil then
  136.                 Result
  137.         [] ActualAnim|NextAnims then
  138.                 case ActualAnim
  139.                 of primitive(color:C kind:K) then
  140.                         {TransformAnimAccumulator
  141.                                 NextAnims
  142.                                 (fun {$ Time}
  143.                                         local K2 in
  144.                                                 if K==square then
  145.                                                         K2 = para
  146.                                                 elseif K==circle then
  147.                                                         K2 = ellipse
  148.                                                 end
  149.                                                 shape(color:C kind:K2 points:[pt(x:0.0 y:0.0) pt(x:1.0 y:0.0) pt(x:1.0 y:1.0) pt(x:0.0 y:1.0)])
  150.                                         end
  151.                                 end)|Result
  152.             }
  153.             % si l'animation actuelle est un Element de type primitive, on rappelle la fonction (récursivité) sur l'animation suivante tout en ajoutant une fonction qui renvoie la forme d'une primitive à Result
  154.                 [] translate(dx:Dx dy:Dy 1:Anim) then
  155.                         {TransformAnimAccumulator
  156.                                 NextAnims
  157.                                 (fun {$ Time}
  158.                                         {TransformAccumulator
  159.                                                 (fun {$ P1 P2 P3 P4}
  160.                                                         local DxParsed DyParsed in
  161.                                                                 DxParsed = {Parse Dx Time}
  162.                                                                 DyParsed = {Parse Dy Time}
  163.                                                                 [pt(x:(P1.x+DxParsed) y:P1.y+DyParsed) pt(x:P2.x+DxParsed y:P2.y+DyParsed) pt(x:P3.x+DxParsed y:P3.y+DyParsed) pt(x:P4.x+DxParsed y:P4.y+DyParsed)]
  164.                                                         end
  165.                                                 end)
  166.                                                 Time
  167.                                                 {TransformAnim Anim}.1
  168.                                                 nil
  169.                                         } % Virer Time
  170.                                 end)|Result
  171.             }
  172.            % si l'animation actuelle est un Element de type translate, on rappelle la fonction (récursivité) sur l'animation suivante tout en ajoutant au résultat une fonction qui renvoie la forme après translation
  173.                 [] rotate(angle:Angle 1:Anim) then
  174.                         {TransformAnimAccumulator
  175.                                 NextAnims
  176.                                 (fun {$ Time}
  177.                                         {TransformAccumulator
  178.                                                 (fun {$ P1 P2 P3 P4}
  179.                                                         local AngleParsed in
  180.                                                                 AngleParsed = {Parse Angle Time}
  181.                                                                 [{RotatePoint AngleParsed P1} {RotatePoint AngleParsed P2} {RotatePoint AngleParsed P3} {RotatePoint AngleParsed P4}]
  182.                                                         end
  183.                                                 end)
  184.                                                 Time
  185.                                                 {TransformAnim Anim}.1
  186.                                                 nil
  187.                                         } % Virer Time
  188.                                 end)|Result
  189.             }
  190.            % si l'animation actuelle est un Element de type rotate, on rappelle la fonction (récursivité) sur l'animation suivante tout en ajoutant au résultat une fonction qui renvoie la forme après translation
  191.                 [] scale(rx:Rx ry:Ry 1:Anim) then
  192.                         {TransformAnimAccumulator
  193.                                 NextAnims
  194.                                 (fun {$ Time}
  195.                                         {TransformAccumulator
  196.                                                 (fun {$ P1 P2 P3 P4}
  197.                                                         local RxParsed RyParsed in
  198.                                                                 RxParsed = {Parse Rx Time}
  199.                                                                 RyParsed = {Parse Ry Time}
  200.                                                                 [pt(x:(P1.x*RxParsed) y:P1.y*RyParsed) pt(x:P2.x*RxParsed y:P2.y*RyParsed) pt(x:P3.x*RxParsed y:P3.y*RyParsed) pt(x:P4.x*RxParsed y:P4.y*RyParsed)]
  201.                                                         end
  202.                                                 end)
  203.                                                 Time
  204.                                                 {TransformAnim Anim}.1
  205.                                                 nil
  206.                                         } % Virer Time
  207.                                 end)|Result
  208.             }
  209.            % si l'animation actuelle est un Element de type scale, on rappelle la fonction (récursivité) sur l'animation suivante tout en ajoutant au résultat une fonction qui renvoie la forme après application du scale
  210.                 end
  211.         else
  212.                 {TransformAnimAccumulator [AllAnims] Result}
  213.         end
  214. end
  215.  
  216. % Cette fonction reçoit en paramètre une animation et renvoie une liste de fonction
  217. % Pré : Anim est une animation
  218. % Post : Renvoie une liste de fonction qui prennent le temps en paramètre et renvoient une forme
  219. fun {TransformAnim Anim}
  220.         {TransformAnimAccumulator {SimplifySiblings Anim} nil}
  221. end
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232. Pi=3.141592653589
  233.  
  234. TestAnim1=[
  235. scale(rx:0.5 ry:0.5 [translate(dx:2.0 dy:2.0 [translate(dx:times(~1.5 sin(time)) dy:times(~0.5 cos(time)) [scale( rx:times(cos(time) plus(0.8 times(0.2 cos(time)))) ry:plus(0.8 times(0.2 cos(time))) [rotate(angle:Pi/2.0 [rotate(angle:times(0.6 sin(times(time 10.0))) [translate( dx:~1.0 dy:~0.1 [scale(rx:1.0 ry:0.2 [
  236.         primitive(color:black kind:square)])
  237.         scale(rx:0.2 ry:0.5 [
  238.                 primitive(color:black kind:square)])])])
  239.                 rotate(angle:times(0.6 sin(times(time ~10.0))) [translate( dx:~1.0 dy:~0.1 [scale(rx:1.0 ry:0.2 [
  240.                         primitive(color:black kind:square)]) scale(rx:0.2 ry:0.5 [primitive(color:black kind:square)])])]) translate(dx:0.0 dy:~0.1 [scale(rx:1.5 ry:0.2 [
  241.                         primitive(color:black kind:square)])]) translate(dx:1.5 dy:~0.2 [scale(rx:0.4 ry:0.4 [
  242.                                 primitive(color:black kind:circle)])])])])])])])]
  243.  
  244.  
  245.  
  246.  
  247.  
  248. % A ball bouncing on the ground
  249. % Author: Sebastien Doeraene
  250. % Credits: Gery Debongnie, who found the appropriate mathematical approximation
  251.  
  252. local
  253.    Pi = 3.14159265358979
  254.  
  255.    % The PositiveOnly function is defined mathematically as:
  256.    % f(x) = 0    if x <= 0
  257.    %      = x    if x > 0
  258.    % It is used in the scene below to have a non-continuous transition from the
  259.    % state where the ball is in the air (translation defined by a cos) and the
  260.    % state where the ball is on the ground (scaling defined by a cos).
  261.    %
  262.    % Of course such a function cannot be defined only with + - * / sin cos tan,
  263.    % which are the only standard operations we have.
  264.    %
  265.    % In order to overcome this limitation, we use the development of a
  266.    % Fourier Series of this function. Such a series *approximates* the function
  267.    % with only the operations that are allowed. The formula is the following:
  268.    %
  269.    %   f(x) ~= x*(1/2 + (2/pi)*sin(x) + (2/3pi)*sin(3x) + (2/5pi)*sin(5x) + ...)
  270.    %
  271.    % The PositiveOnly function below computes this development of the Fourier
  272.    % Series with 25 terms (up to coeff 49), which by experience is enough to
  273.    % get a smooth movement.
  274.    fun {PositiveOnly X}
  275.       As = {Map {List.number 1 49 2} IntToFloat}
  276.       Terms = {Map As
  277.                fun {$ A} times(2.0/A/Pi sin(times(A X))) end}
  278.       Series = {FoldL Terms
  279.                 fun {$ Prev Term} plus(Prev Term) end
  280.                 0.5}
  281.    in
  282.       times(X Series)
  283.    end
  284.  
  285.    % The ball will follow a vertical movement defined by Height = cos(3*time)
  286.    % By convention, a positive height means that it is in the air, and a
  287.    % negative height means that it is crushed on the ground.
  288.       Height = times(cos(times(3.0 times(time exp(times(0.08 time)))))
  289.                   exp(times(~0.3 time)))
  290. in
  291.    TestAnim = [
  292.      % Center the animation on the screen
  293.      translate(dx:1.0 dy:0.0 [
  294.        % If Height > 0.0, then translate upwards with amount Height
  295.        translate(dx:0.0 dy:{PositiveOnly Height} [
  296.          % If Height < 0.0, then crush the ball by scaling
  297.          % - in X by 1 + 0.5 * (-Height)
  298.          % - in Y by 1 - 0.5 * (-Height)
  299.          scale(rx:plus(1.0 times(0.5 {PositiveOnly minus(0.0 Height)}))
  300.                ry:minus(1.0 times(0.5 {PositiveOnly minus(0.0 Height)})) [
  301.            % Center the ball on the y axis, so that X-scaling is symmetric
  302.            translate(dx:~0.5 dy:0.0 [
  303.              % The ball
  304.              primitive(color:blue kind:circle)
  305.            ])
  306.          ])
  307.        ])
  308.      ])
  309.    ]
  310. end
  311.  
  312. A = [translate(dx:1.0 dy:0.0 [rotate(angle:cos(time) [primitive(color:red kind:square)])])]
  313.  
  314. %{Test.showAnim {Test.transformAnim TestAnim} opts(title:'Solution')}
  315. {Test.showAnim {TransformAnim TestAnim1} opts(title:'Mon projet')}
Add Comment
Please, Sign In to add comment