----------------------------------------------------------------------- -- 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. ] |