program spaceship (input,output); const RADIUS = 1; type Vector = record x : real; y : real; end; var shipPos, massPos, velocity : Vector; numCalc, oldnumCalc : integer; mass, simTime : real; procedure readEnvironment; begin readln(shipPos.x, shipPos.y); readln(velocity.x, velocity.y); readln(mass, massPos.x, massPos.y); readln(simTime, numCalc); end; function calcInterval ( shipPos, velocity : Vector; timeStep : integer ) : real ; begin calcInterval := simTime / numCalc; end; procedure calcPosition ( var shipPos, velocity : Vector; interval : real ; var collision : boolean ) ; var deltaD, deltaV : Vector; distanceSquared, distance, speed : real; begin (* calculate distance to mass *) deltaD.x := massPos.x - shipPos.x; deltaD.y := massPos.y - shipPos.y; distanceSquared := deltaD.x*deltaD.x + deltaD.y*deltaD.y; distance := sqrt(distanceSquared); collision := (distance <= RADIUS); if (collision) then begin (* collision occured, position = mass, velocity = 0 *) shipPos := massPos; velocity.x := 0; velocity.y := 0; end else begin (* calculate change in velocity *) speed := interval * mass / distanceSquared; deltaV.x := speed * (deltaD.x / distance); deltaV.y := speed * (deltaD.y / distance); (* calculate new position using average velocity in interval *) shipPos.x := shipPos.x + ((velocity.x + deltaV.x/2) * interval); shipPos.y := shipPos.y + ((velocity.y + deltaV.y/2) * interval); (* calculate new velocity *) velocity.x := velocity.x + deltaV.x; velocity.y := velocity.y + deltaV.y; end; end; procedure calcCourse ; var interval, time : real; i : integer; collision : boolean; begin time := 0.0; collision := false; for i := 1 to numCalc do begin if (not collision) then begin interval := calcInterval(shipPos, velocity, i); time := time + interval; calcPosition(shipPos, velocity, interval, collision); writeln(time:9:3, shipPos.x:9:3, shipPos.y:9:3); end; end; end; begin readEnvironment; calcCourse; end.