-----------------------------------------------------------------------
-- An example of Actor Prolog program. --
-- (c) 2013 IRE RAS Alexei A. Morozov --
-----------------------------------------------------------------------
import .. from "morozov/Java3D";
DOMAINS:
Balls = Ball*.
Ball = ball(NodeLabel,Position,Velocity).
Position = Translation.
Velocity = Numerical*.
class 'Main' (specialized 'Timer'):
--
constant:
--
scene_halfwidth = 0.5;
ball_radius : Radius = 0.03;
--
internal:
--
object_store = ('ObjectStore',
scene_halfwidth);
canvas = ('TargetCanvas',
scene= object_store,
ball_radius);
--
[
goal:-!,
set_period(0.030,0.0),
activate.
--
tick:-!,
object_store ? modify(?time()),
canvas ? update.
]
class 'ObjectStore' (specialized 'Database'):
--
constant:
--
scene_halfwidth = 1;
--
[
DOMAINS:
--
Target = Ball; Time.
--
PREDICATES:
--
imperative:
--
modify(Time) - (i);
--
calculate_new_position(
Position,
Velocity,
Time,
Time) = Position - (i,i,i,i);
--
correct_velosity(
Position,
Position,
Position,
Velocity,
Velocity) - (i,i,o,i,o);
--
correct_V_and_P(
Numerical,
Numerical,
Numerical,
Numerical,
Numerical) - (i,i,o,i,o);
--
'+'(Position,Position) = Position - (i,i);
'*'(Velocity,REAL) = Position - (i,i);
'-'(Numerical) = Numerical - (i);
--
CLAUSES:
--
modify(T2):-
Item1== ?match(time(_,_,_,_)),
T1== ?val("Time",Item1),
B1== ?match(ball(_,_,_)),
B1 == ball(Label,P1,V1),
P2== ?calculate_new_position(P1,V1,T1,T2),
correct_velosity(P1,P2,P3,V1,V2),
retract_all(B1),
insert(ball(Label,P3,V2)),
fail.
modify(T2):-
retract_all(time(_,_,_,_)),
insert(T2).
--
calculate_new_position(P1,V1,T1,T2) = P2 :-
Interval== (T2 - T1) / 1000.0,
P2== P1 + V1 * Interval.
--
correct_velosity([P1|R1],[P2|R2],[P3|R3],[V1|R4],[V2|R5]):-!,
correct_V_and_P(P1,P2,P3,V1,V2),
correct_velosity(R1,R2,R3,R4,R5).
correct_velosity(_,_,[],_,[]).
--
correct_V_and_P(P1,P2,P1,V1,V2):-
P2 >= scene_halfwidth,!,
V2== -(V1).
correct_V_and_P(P1,P2,P1,V1,V2):-
P2 <= -(scene_halfwidth),!,
V2== -(V1).
correct_V_and_P(_,P2,P2,V1,V1).
]
class 'TargetCanvas' (specialized 'Canvas3D'):
--
internal:
--
scene : 'ObjectStore';
--
constant:
--
ball_radius : Radius = 0.03;
--
enable_scene_antialiasing = 'yes';
background = 'Black';
--
[
PREDICATES:
--
imperative:
--
create_balls(INTEGER,Balls) - (i,o);
insert_balls(Balls) - (i);
--
create_spheres(Balls,Radius,NodeList) - (i,i,o);
create_sphere(Ball,Radius,Node) - (i,i,o);
--
update;
--
CLAUSES:
--
goal:-!,
create_balls(100,Balls),
insert_balls(Balls),
create_spheres(Balls,ball_radius,Spheres),
Bounds== 'BoundingSphere'({
center: p(0.0,0.0,0.0),
radius: 100.0
}),
show([ 'Background'({
color: 'Black',
scaleMode: 'SCALE_REPEAT',
applicationBounds: Bounds
}),
'OrbitBehavior'({
reverseAll: 'yes',
stopZoom: 'yes',
minRadius: 1.5,
schedulingBounds: Bounds
})
| Spheres
]).
--
create_balls(N,[ball(N,[0,0,0],[Vx,Vy,Vz])|Rest]):-
N > 0,!,
Vx== ?random() - 0.5,
Vy== ?random() - 0.5,
Vz== ?random() - 0.5,
create_balls(N-1,Rest).
create_balls(_,[]).
--
insert_balls([Ball|Rest]):-!,
scene ? insert(Ball),
insert_balls(Rest).
insert_balls(_).
--
create_spheres([Ball|Rest1],Radius,[Sphere|Rest2]):-!,
create_sphere(Ball,Radius,Sphere),
create_spheres(Rest1,Radius,Rest2).
create_spheres(_,_,[]).
--
create_sphere(ball(Label,_,_),Radius,Sphere):-
Red== ?random() / 1.5,
Green== ?random() / 1.5,
Blue== ?random() / 1.5,
Sphere ==
'TransformGroup'({
label: Label,
allowTransformWrite: 'yes',
allowTransformRead: 'yes',
branches: [
'Sphere'({
radius: Radius,
generateNormals: 'yes',
divisions: 100,
appearance: 'Appearance'({
material: 'Material'({
ambientColor: color3(Red,Green,Blue),
diffuseColor: 'Black',
specularColor: color3(0.8,0.8,0.8),
emissiveColor: color3(Red,Green,Blue),
shininess: 70
})
})
}),
'PointLight'({
color: color3(Red,Green,Blue),
position: p(0.0,0.0,0.0),
attenuation: a(1,0,0),
influencingBounds: 'BoundingSphere'({
center: p(0.0,0.0,0.0),
radius: 100.0
})
})
]
}).
--
update:-
B== scene?match(ball(_,_,_)),
B == ball(Label,Position,_),
set_translation(Label,Position),
fail.
update.
]
|