package gl8080.physics.domain.force; import java.util.Objects; import java.util.Set; import gl8080.physics.domain.ActingForce; import gl8080.physics.domain.Physical; import gl8080.physics.domain.World; import gl8080.physics.domain.primitive.Force; import gl8080.physics.domain.primitive.Vector; public class UniversalGravitation implements ActingForce { private static final double G = 6.67 * Math.pow(10.0, -11.0); private final World world; public UniversalGravitation(World world) { Objects.requireNonNull(world); this.world = world; } @Override public Force getForce(Physical target) { Set<Physical> others = this.world.getPhysicalsWithout(target); return others.stream() .map(other -> this.calcForce(target, other)) .reduce(Force.ZERO, (f1, f2) -> f1.add(f2)); } private Force calcForce(Physical me, Physical other) { Vector vector = Vector.create(me.getLocation(), other.getLocation()); double rr = vector.x*vector.x + vector.y*vector.y + vector.z*vector.z; double m = me.getMass().quantity; double M = other.getMass().quantity; double F = G * M * m / rr; Vector f = vector.normalize().multiply(F); return new Force(f.x, f.y, f.z); } }