81 lines
2.3 KiB
Prolog
81 lines
2.3 KiB
Prolog
:- use_module(library(pce)).
|
|
|
|
pendulum :-
|
|
new(D, window('Pendulum')),
|
|
send(D, size, size(560, 300)),
|
|
new(Line, line(80, 50, 480, 50)),
|
|
send(D, display, Line),
|
|
new(Circle, circle(20)),
|
|
send(Circle, fill_pattern, colour(@default, 0, 0, 0)),
|
|
new(Boule, circle(60)),
|
|
send(Boule, fill_pattern, colour(@default, 0, 0, 0)),
|
|
send(D, display, Circle, point(270,40)),
|
|
send(Circle, handle, handle(h/2, w/2, in)),
|
|
send(Boule, handle, handle(h/2, w/2, out)),
|
|
send(Circle, connect, Boule, link(in, out, line(0,0,0,0,none))),
|
|
new(Anim, animation(D, 0.0, Boule, 200.0)),
|
|
send(D, done_message, and(message(Anim, free),
|
|
message(Boule, free),
|
|
message(Circle, free),
|
|
message(@receiver,destroy))),
|
|
send(Anim?mytimer, start),
|
|
send(D, open).
|
|
|
|
|
|
|
|
|
|
:- pce_begin_class(animation(window, angle, boule, len_pendulum), object).
|
|
variable(window, object, both, "Display window").
|
|
variable(boule, object, both, "bowl of the pendulum").
|
|
variable(len_pendulum, object, both, "len of the pendulum").
|
|
variable(angle, object, both, "angle with the horizontal").
|
|
variable(delta, object, both, "increment of the angle").
|
|
variable(mytimer, timer, both, "timer of the animation").
|
|
|
|
initialise(P, W:object, A:object, B : object, L:object) :->
|
|
"Creation of the object"::
|
|
send(P, window, W),
|
|
send(P, angle, A),
|
|
send(P, boule, B),
|
|
send(P, len_pendulum, L),
|
|
send(P, delta, 0.01),
|
|
send(P, mytimer, new(_, timer(0.01,message(P, anim_message)))).
|
|
|
|
% method called when the object is destroyed
|
|
% first the timer is stopped
|
|
% then all the resources are freed
|
|
unlink(P) :->
|
|
send(P?mytimer, stop),
|
|
send(P, send_super, unlink).
|
|
|
|
|
|
% message processed by the timer
|
|
anim_message(P) :->
|
|
get(P, angle, A),
|
|
get(P, len_pendulum, L),
|
|
calc(A, L, X, Y),
|
|
get(P, window, W),
|
|
get(P, boule, B),
|
|
send(W, display, B, point(X,Y)),
|
|
% computation of the next position
|
|
get(P, delta, D),
|
|
next_Angle(A, D, NA, ND),
|
|
send(P, angle, NA),
|
|
send(P, delta, ND).
|
|
|
|
:- pce_end_class.
|
|
|
|
% computation of the position of the bowl.
|
|
calc(Ang, Len, X, Y) :-
|
|
X is Len * cos(Ang)+ 250,
|
|
Y is Len * sin(Ang) + 20.
|
|
|
|
|
|
% computation of the next angle
|
|
% if we reach 0 or pi, delta change.
|
|
next_Angle(A, D, NA, ND) :-
|
|
NA is D + A,
|
|
(((D > 0, abs(pi-NA) < 0.01); (D < 0, abs(NA) < 0.01))->
|
|
ND = - D;
|
|
ND = D).
|