Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- declare
- [Test]={Link ['C:/Users/Xavier/Desktop/testProjet140.ozf']}
- fun {SetLastSubAnim Animation To}
- case Animation
- of nil then
- To
- [] translate(dx:Dx dy:Dy 1:SubAnimation) then
- translate(dx:Dx dy:Dy 1:{SetLastSubAnim SubAnimation To})
- [] scale(rx:Rx ry:Ry 1:SubAnimation) then
- scale(rx:Rx ry:Ry 1:{SetLastSubAnim SubAnimation To})
- [] rotate(angle:Angle 1:SubAnimation) then
- rotate(angle:Angle 1:{SetLastSubAnim SubAnimation To})
- end
- end
- fun {SimplifyTrough Animation Parent Result} % Renvoi une liste d'animation
- case Animation
- of primitive(color:_ kind:_) then
- {SetLastSubAnim Parent Animation}|Result
- [] translate(dx:Dx dy:Dy 1:SubAnimations) then
- {SimplifyAccumulateSiblings SubAnimations {SetLastSubAnim Parent translate(dx:Dx dy:Dy 1:nil)} Result}
- [] scale(rx:Rx ry:Ry 1:SubAnimations) then
- {SimplifyAccumulateSiblings SubAnimations {SetLastSubAnim Parent scale(rx:Rx ry:Ry 1:nil)} Result}
- [] rotate(angle:Angle 1:SubAnimations) then
- {SimplifyAccumulateSiblings SubAnimations {SetLastSubAnim Parent rotate(angle:Angle 1:nil)} Result}
- end
- end
- fun {SimplifyAccumulateSiblings Animations Parent Result} % Renvoi une liste d'animation
- case Animations
- of ActualAnim|nil then
- {SimplifyTrough ActualAnim Parent Result}
- [] ActualAnim|NextAnims then
- {SimplifyAccumulateSiblings NextAnims Parent {SimplifyTrough ActualAnim Parent Result}}
- else % Why ?
- Animations
- end
- end
- fun {SimplifySiblings Animations}
- {SimplifyAccumulateSiblings Animations nil nil}
- end
- % Pré : Angle est l'angle de la rotation, Point est un point (x,y)
- % 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)))
- fun {RotatePoint Angle Point}
- local X Y in
- X = Point.x
- Y = Point.y
- pt(x:(X*{Float.cos Angle} - Y*{Float.sin Angle}) y:(X*{Float.sin Angle}+Y*{Float.cos Angle}))
- end
- end
- % Pré : List et Result sont des listes
- % Post : Ajoute les éléments de List à l'avant de Result en commençant par le premier et renvoie ensuite Result
- % Ex: List = [1 2 3] Result = [4 5]
- % La fonction renvoie [3 2 1 4 5]
- fun {ReverseList List Result}
- case List
- of nil then Result
- [] H|T then {ReverseList T H|Result}
- end
- end
- % Pré : Formule est une formule telle que décrite dans l'énoncé, Time est le temps
- % Post : renvoie le résultat de Formule
- fun {Parse Formule Time}
- case Formule
- of time then Time
- [] plus(A B) then {Parse A Time}+{Parse B Time}
- [] minus(A B) then {Parse A Time}-{Parse B Time}
- [] times(A B) then {Parse A Time}*{Parse B Time}
- [] 'div'(A B) then {Parse A Time}/{Parse B Time}
- [] 'sin'(A) then {Float.sin {Parse A Time}}
- [] 'cos'(A) then {Float.cos {Parse A Time}}
- [] 'tan'(A) then {Float.tan {Parse A Time}}
- [] 'exp'(A) then {Float.exp {Parse A Time}}
- [] 'log'(A) then {Float.log {Parse A Time}}
- [] 'neg'(A) then ~{Parse A Time}
- [] 'eq'(A B) then if {Parse A Time} == {Parse B Time} then
- 1.0
- else 0.0
- end
- []'ne'(A B) then if {Parse A Time} == {Parse B Time} then
- 0.0
- else 1.0
- end
- []'lt'(A B) then if {Parse A Time} < {Parse B Time} then
- 1.0
- else 0.0
- end
- [] 'le'(A B) then if {Parse A Time} =< {Parse B Time} then
- 1.0
- else 0.0
- end
- [] 'gt'(A B) then if {Parse A Time} > {Parse B Time} then
- 1.0
- else 0.0
- end
- [] 'ge'(A B) then if {Parse A Time} >= {Parse B Time} then
- 1.0
- else 0.0
- end
- else
- Formule
- end
- end
- % Je te laisse commenter celle-ci je ne sais pas trop comment l'expliquer
- fun {TransformAccumulator Transformer Time ShapeFunction Result}
- local Shape P1 P2 P3 P4 in
- Shape = {ShapeFunction Time}
- case Shape
- of shape(color:C kind:K points:P) then
- P1 = P.1
- P2 = P.2.1
- P3 = P.2.2.1
- P4 = P.2.2.2.1
- shape(color:C kind:K points:{Transformer P1 P2 P3 P4})
- end
- end
- end
- % Pré : AllAnmis est une animation, Result est une liste (éventuellement vide)
- % Post : Renvoie une liste de fonction qui prennent le temps en paramètre et renvoient une forme
- % C'est une fonction récursive terminale
- fun {TransformAnimAccumulator AllAnims Result}
- case AllAnims
- of nil then
- Result
- [] ActualAnim|NextAnims then
- case ActualAnim
- of primitive(color:C kind:K) then
- {TransformAnimAccumulator
- NextAnims
- (fun {$ Time}
- local K2 in
- if K==square then
- K2 = para
- elseif K==circle then
- K2 = ellipse
- end
- 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)])
- end
- end)|Result
- }
- % 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
- [] translate(dx:Dx dy:Dy 1:Anim) then
- {TransformAnimAccumulator
- NextAnims
- (fun {$ Time}
- {TransformAccumulator
- (fun {$ P1 P2 P3 P4}
- local DxParsed DyParsed in
- DxParsed = {Parse Dx Time}
- DyParsed = {Parse Dy Time}
- [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)]
- end
- end)
- Time
- {TransformAnim Anim}.1
- nil
- } % Virer Time
- end)|Result
- }
- % 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
- [] rotate(angle:Angle 1:Anim) then
- {TransformAnimAccumulator
- NextAnims
- (fun {$ Time}
- {TransformAccumulator
- (fun {$ P1 P2 P3 P4}
- local AngleParsed in
- AngleParsed = {Parse Angle Time}
- [{RotatePoint AngleParsed P1} {RotatePoint AngleParsed P2} {RotatePoint AngleParsed P3} {RotatePoint AngleParsed P4}]
- end
- end)
- Time
- {TransformAnim Anim}.1
- nil
- } % Virer Time
- end)|Result
- }
- % 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
- [] scale(rx:Rx ry:Ry 1:Anim) then
- {TransformAnimAccumulator
- NextAnims
- (fun {$ Time}
- {TransformAccumulator
- (fun {$ P1 P2 P3 P4}
- local RxParsed RyParsed in
- RxParsed = {Parse Rx Time}
- RyParsed = {Parse Ry Time}
- [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)]
- end
- end)
- Time
- {TransformAnim Anim}.1
- nil
- } % Virer Time
- end)|Result
- }
- % 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
- end
- else
- {TransformAnimAccumulator [AllAnims] Result}
- end
- end
- % Cette fonction reçoit en paramètre une animation et renvoie une liste de fonction
- % Pré : Anim est une animation
- % Post : Renvoie une liste de fonction qui prennent le temps en paramètre et renvoient une forme
- fun {TransformAnim Anim}
- {TransformAnimAccumulator {SimplifySiblings Anim} nil}
- end
- Pi=3.141592653589
- TestAnim1=[
- 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 [
- primitive(color:black kind:square)])
- scale(rx:0.2 ry:0.5 [
- primitive(color:black kind:square)])])])
- rotate(angle:times(0.6 sin(times(time ~10.0))) [translate( dx:~1.0 dy:~0.1 [scale(rx:1.0 ry:0.2 [
- 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 [
- primitive(color:black kind:square)])]) translate(dx:1.5 dy:~0.2 [scale(rx:0.4 ry:0.4 [
- primitive(color:black kind:circle)])])])])])])])]
- % A ball bouncing on the ground
- % Author: Sebastien Doeraene
- % Credits: Gery Debongnie, who found the appropriate mathematical approximation
- local
- Pi = 3.14159265358979
- % The PositiveOnly function is defined mathematically as:
- % f(x) = 0 if x <= 0
- % = x if x > 0
- % It is used in the scene below to have a non-continuous transition from the
- % state where the ball is in the air (translation defined by a cos) and the
- % state where the ball is on the ground (scaling defined by a cos).
- %
- % Of course such a function cannot be defined only with + - * / sin cos tan,
- % which are the only standard operations we have.
- %
- % In order to overcome this limitation, we use the development of a
- % Fourier Series of this function. Such a series *approximates* the function
- % with only the operations that are allowed. The formula is the following:
- %
- % f(x) ~= x*(1/2 + (2/pi)*sin(x) + (2/3pi)*sin(3x) + (2/5pi)*sin(5x) + ...)
- %
- % The PositiveOnly function below computes this development of the Fourier
- % Series with 25 terms (up to coeff 49), which by experience is enough to
- % get a smooth movement.
- fun {PositiveOnly X}
- As = {Map {List.number 1 49 2} IntToFloat}
- Terms = {Map As
- fun {$ A} times(2.0/A/Pi sin(times(A X))) end}
- Series = {FoldL Terms
- fun {$ Prev Term} plus(Prev Term) end
- 0.5}
- in
- times(X Series)
- end
- % The ball will follow a vertical movement defined by Height = cos(3*time)
- % By convention, a positive height means that it is in the air, and a
- % negative height means that it is crushed on the ground.
- Height = times(cos(times(3.0 times(time exp(times(0.08 time)))))
- exp(times(~0.3 time)))
- in
- TestAnim = [
- % Center the animation on the screen
- translate(dx:1.0 dy:0.0 [
- % If Height > 0.0, then translate upwards with amount Height
- translate(dx:0.0 dy:{PositiveOnly Height} [
- % If Height < 0.0, then crush the ball by scaling
- % - in X by 1 + 0.5 * (-Height)
- % - in Y by 1 - 0.5 * (-Height)
- scale(rx:plus(1.0 times(0.5 {PositiveOnly minus(0.0 Height)}))
- ry:minus(1.0 times(0.5 {PositiveOnly minus(0.0 Height)})) [
- % Center the ball on the y axis, so that X-scaling is symmetric
- translate(dx:~0.5 dy:0.0 [
- % The ball
- primitive(color:blue kind:circle)
- ])
- ])
- ])
- ])
- ]
- end
- A = [translate(dx:1.0 dy:0.0 [rotate(angle:cos(time) [primitive(color:red kind:square)])])]
- %{Test.showAnim {Test.transformAnim TestAnim} opts(title:'Solution')}
- {Test.showAnim {TransformAnim TestAnim1} opts(title:'Mon projet')}
Add Comment
Please, Sign In to add comment