From cab00434202a8437fe11a526f1df9ea9991db21c Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Mon, 23 Sep 2024 09:32:50 -0400 Subject: design update. begin blog --- projects/learning-rust/1.html | 69 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 projects/learning-rust/1.html (limited to 'projects/learning-rust/1.html') diff --git a/projects/learning-rust/1.html b/projects/learning-rust/1.html new file mode 100644 index 0000000..840a968 --- /dev/null +++ b/projects/learning-rust/1.html @@ -0,0 +1,69 @@ + + + + 1: Solar Systems + + + + + + +
+

Learning Rust : Solar Systems

+ How do I store non-owning references to collection members? +
+ < +

I want to make a data-driven viewer for the solar system, as part of a game inspired by Aurora 4x but Rust is an entirely different beast from C.

+

I have prior experience writing systems like this, so I figured it would be as easy as:

+

+pub struct Orbital {
+    //Some optional non-owning reference to the parent orbital
+    mass : f64,
+    semi_major_axis : f64,
+    eccentricity : f64,
+    inclination : f64,
+    long_asc_node : f64,
+    argument_periapsis : f64,
+    mean_anomaly_epoch : f64
+}
+            
+

The question then is: How do we store the reference to the parent orbital?

+

note: by parent orbital, I mean the orbital body that the given orbital body orbits.

+

In C, we would just store a pointer into the data of the owning container (i.e. a dynamic array).

+

I understand that the method above could cause problems with object lifetimes and dead references, but in this case we are assuming a static lifetime with a fixed-width container.

+

So my first instinct is to look in the Rust docs for a non-owning reference type.

+

I wasted about a day researching Rc's and RefCell's when I had a revelation; what I wanted was over-engineered. Instead of storing a reference to the parent orbital, I could just store an index into the system's orbital container. All I need to do to make this work is pass a borrowed ref to the system object to the orbital's update function.

+

But not every part of the update function needs the parent orbital's position, so I can split the update into two parts:

+

1: Update the orbital elements relative to the parent object

+

2: Use the parent orbital's position to transform the relative coordinates into absolute coordinates

+

So here's what I came up with.

+

+pub struct Orbital {
+    parent_index : usize,
+    //Temporary state variables for later update.
+    rel_pos : (f64, f64, f64)
+    //Orbital parameters
+    mass : f64,
+    semi_major_axis : f64,
+    eccentricity : f64,
+    inclination : f64,
+    long_asc_node : f64,
+    argument_periapsis : f64,
+    mean_anomaly_epoch : f64
+}
+//...
+impl Orbital {
+//...
+    pub fn update_rel(&mut self) -> Orbital {
+        //...
+    }
+    
+    pub fn update(&self, &system : System) -> (f64, f64, f64) {
+        //...
+    }
+}
+        
+
+
+ + -- cgit v1.2.1