1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//! A countable number of things at places — the other half of what a domain can be.
//!
//! [`ScalarField`](crate::ScalarField) covers the domains that are continua: a room, a bar, a
//! solid. A caller can sample one anywhere without knowing what it is, which is what let the
//! renderer stop naming `Room` and `Bar1D`.
//!
//! Then the other half stayed uncovered. An orbit, a bouncing ball and a box of atoms are *not*
//! fields — they are a finite number of bodies at positions, and rasterising them would invent a
//! continuum they do not have. `as_field` returning `None` for them is the honest answer and it
//! left every caller back at `domain_as::<NBody>`, `domain_as::<ContactSystem>`,
//! `domain_as::<Fluid>`. That is `FRICTION.md` finding 11, recorded and not fixed for months.
//!
//! Splitting the layers apart is what forced it. A scene layer that had to name three domains to
//! find out where anything *was* would need editing every time a physics arrived, and that is
//! the one thing this structure exists to prevent.
//!
//! # What belongs here and what does not
//!
//! A body's **position** is physics. So is a **real wall** it cannot cross — a periodic cell is
//! a boundary condition, and an atom leaving one face genuinely enters the opposite one.
//!
//! The **extent to draw** is not. An orbit's box is only as big as the picture wants; there is
//! nothing physical at its edge. So [`Bodies::cell`] reports a wall or `None`, and a view that
//! wants framing computes it from the positions it has — over the whole run, so that a body
//! moving is a body moving rather than the frame rescaling underneath it.
use LengthVec;
/// A domain that is a finite number of bodies rather than a continuum.
///
/// Indexed rather than iterated so a caller can take one body without building a vector, and
/// because the order is meaningful: index is identity here, and body 3 in one frame is body 3 in
/// the next.