# Nbody barnes hut

`nbody_barnes_hut` is designed to facilitate the simulation of N-body systems in `O(nlogn)` time. This is useful for many applications: common ones are gravitational simulations and electrostatic simulations. Simulations in 2D and 3D are both supported.

This crate is not multithreaded. Rather, call `calc_forces_on_particle` in a multithreaded loop (for example, with `rayon`). The time to create the tree is negligible in comparison to the time used calculating forces.

# Example

Here is a basic 3D gravitational simulator:

```
use rand::Rng;
use nbody_barnes_hut::particle_3d::Particle3D;
use nbody_barnes_hut::vector_3d::Vector3D;
use nbody_barnes_hut::barnes_hut_3d::OctTree;

const G: f64 = 6.67E-11; // Newton's Gravitational Constant

// Create 10 000 random points
let points: Vec<Particle3D> = (0..10_000)
.map(|_| {
let pos = Vector3D::new(
rng.gen_range(-1000.0, 1000.0),
rng.gen_range(-1000.0, 1000.0),
rng.gen_range(-1000.0, 1000.0),
);
Particle3D::new(pos, 30.0)
})
.collect();

// This is pretty hacky
let points_ref = &points.iter().collect::<Vec<&Particle3D>>()[..];

let tree = OctTree::new(points_ref, 0.5);

for p in &points {
// Do something with this value
let acceleration_on_particle = tree.calc_forces_on_particle(
p.position,
(),
|d_squared, mass, dis_vec, _| {
// dis_vec is not normalized, so we have to normalize it here
G * mass * dis_vec / (d_squared * d_squared.sqrt())
},
);
}```

## Modules

 barnes_hut_2d barnes_hut_3d particle_2d particle_3d vector_2d vector_3d