Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ws1819:programmcode [2019/02/14 17:52] lennox99 angelegt |
ws1819:programmcode [2019/03/05 17:32] (aktuell) mana16 [Code] |
||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== Code ====== | + | {{https://i.ibb.co/48VrRGH/Code.png}} |
+ | ===== Main.py: ===== | ||
- | WIP | ||
+ | <code python> | ||
+ | # -*- coding: utf-8 -*- | ||
+ | from model import World, WorldOutput | ||
+ | from file_model import WorldFileInput, WorldFileOutput | ||
+ | from physics_euler import PhysicsEngineEuler | ||
+ | from physics_rk4 import PhysicsEngineRK4 | ||
+ | from physics_leapfrog import PhysicsEngineLeap | ||
+ | from physics_skyfield import PhysicsEngineSkyfield | ||
+ | from render import RenderEngineVPython | ||
+ | import sys | ||
+ | |||
+ | class WorldLogOutput(WorldOutput): | ||
+ | | ||
+ | def start(self): | ||
+ | self.print_state() | ||
+ | | ||
+ | def step(self): | ||
+ | self.print_state() | ||
+ | | ||
+ | def print_state(self): | ||
+ | for key, wo in self.world.world_objects: | ||
+ | print('{time},{key},{wo}'.format( | ||
+ | time=self.world.time, key=key, wo=wo)) | ||
+ | | ||
+ | input_type = sys.argv[1] | ||
+ | output_types = sys.argv[2].split(',') | ||
+ | end_time = float(sys.argv[3]) | ||
+ | path = sys.argv[4] | ||
+ | world = World() | ||
+ | |||
+ | if input_type.startswith('file'): | ||
+ | world.input = WorldFileInput(world, path) | ||
+ | elif input_type.startswith('euler'): | ||
+ | #Init world | ||
+ | o = WorldFileOutput(world, path) | ||
+ | parts = input_type.split(':') | ||
+ | dt = 1.0 | ||
+ | if len(parts) > 1: | ||
+ | dt = float(parts[1]) | ||
+ | world.input = PhysicsEngineEuler(world, dt) | ||
+ | elif input_type.startswith('rk4'): | ||
+ | #Init world | ||
+ | o = WorldFileOutput(world, path) | ||
+ | parts = input_type.split(':') | ||
+ | dt = 1.0 | ||
+ | if len(parts) > 1: | ||
+ | dt = float(parts[1]) | ||
+ | world.input = PhysicsEngineRK4(world, dt) | ||
+ | elif input_type.startswith('leapfrog'): | ||
+ | #Init world | ||
+ | o = WorldFileOutput(world, path) | ||
+ | parts = input_type.split(':') | ||
+ | dt = 1.0 | ||
+ | if len(parts) > 1: | ||
+ | dt = float(parts[1]) | ||
+ | world.input = PhysicsEngineLeap(world, dt) | ||
+ | elif input_type.startswith('skyfield'): | ||
+ | #Init world | ||
+ | o = WorldFileOutput(world, path) | ||
+ | parts = input_type.split(':') | ||
+ | dt = 1.0 | ||
+ | if len(parts) > 1: | ||
+ | dt = float(parts[1]) | ||
+ | world.input = PhysicsEngineSkyfield(world, dt) | ||
+ | | ||
+ | for output_type in output_types: | ||
+ | if output_type.startswith('vpython'): | ||
+ | parts = output_type.split(':') | ||
+ | time_scale = 1.0 | ||
+ | radius_scale = 1.0 | ||
+ | if len(parts) > 1: | ||
+ | time_scale = float(parts[1]) | ||
+ | if len(parts) > 2: | ||
+ | radius_scale = float(parts[2]) | ||
+ | world.outputs.append(RenderEngineVPython(world, time_scale, radius_scale)) | ||
+ | if output_type.startswith('file'): | ||
+ | world.outputs.append(WorldFileOutput(world, path)) | ||
+ | if output_type.startswith('log'): | ||
+ | world.outputs.append(WorldLogOutput(world)) | ||
+ | | ||
+ | world.start(end_time) | ||
+ | </code> | ||
+ | \\ | ||
+ | \\ | ||
+ | |||
+ | |||
+ | =====physics_leapfrog.py:===== | ||
+ | <code python> | ||
+ | # -*- coding: utf-8 -*- | ||
+ | from physics import PhysicsEngine | ||
+ | from itertools import combinations | ||
+ | import numpy as np | ||
+ | |||
+ | class PhysicsEngineLeap(PhysicsEngine): | ||
+ | | ||
+ | dt = None | ||
+ | |||
+ | def __init__(self, world, dt): | ||
+ | super(PhysicsEngineLeap, self).__init__(world) | ||
+ | self.dt = dt | ||
+ | |||
+ | def calc_acceleration(self, wo): | ||
+ | return wo.force / wo.mass | ||
+ | |||
+ | def step(self): | ||
+ | world_objects = self.world.world_objects.values() | ||
+ | | ||
+ | #reset force | ||
+ | for wo in world_objects: | ||
+ | wo.force = np.array([0.0,0.0,0.0]) | ||
+ | | ||
+ | pairs = combinations(world_objects, 2) | ||
+ | |||
+ | #force-loop | ||
+ | for wo1, wo2 in pairs: | ||
+ | force = self.grav_force(wo1.position, wo2.position, wo1.mass, wo2.mass) | ||
+ | wo1.force += force | ||
+ | wo2.force -= force | ||
+ | | ||
+ | #first velocity-loop | ||
+ | for wo in world_objects: | ||
+ | wo.velocity += self.calc_acceleration(wo) * self.dt / 2 | ||
+ | |||
+ | #position-loop | ||
+ | for wo in world_objects: | ||
+ | wo.position += wo.velocity * self.dt | ||
+ | |||
+ | for wo in world_objects: | ||
+ | wo.force = np.array([0.0,0.0,0.0]) | ||
+ | | ||
+ | pairs = combinations(world_objects, 2) | ||
+ | |||
+ | #force-loop | ||
+ | for wo1, wo2 in pairs: | ||
+ | force = self.grav_force(wo1.position, wo2.position, wo1.mass, wo2.mass) | ||
+ | wo1.force += force | ||
+ | wo2.force -= force | ||
+ | |||
+ | #second velocity-loop: | ||
+ | for wo in world_objects: | ||
+ | wo.velocity += self.calc_acceleration(wo) * self.dt / 2 | ||
+ | |||
+ | self.world.time += self.dt | ||
+ | </code> |