2023-08-23
Did I fall off the blogging wagon? Or was two posts per week just too high of a cadence? Maybe there is no wagon.
On my main project (reminder: a 3D VR physical environment that reacts to the position of the viewing device), I’ve progressed from last time to what I’ll keep as the end state of the 2D version: a dot moving around on a canvas, using the phone position to determine forces on the dot.
Let’s see if I can embed that entirely here…
The dot should react to how you hold the phone in a physically plausible way; it looks like this currently doesn’t work on iPhones, though. Here’s some footage from testing it using the in-browser sensors tool:
I encountered lots of interesting challenges along the way!
Initially, I tried using the AbsolutOrientationSensor
interface of the Sensor
APIs. This requires collecting permissions for all the underlying
sensors, and returns a quaternion, a four-element vector that’s well
suited for spatial computations, but also kind of annoying when you’re
not working with a library that already uses them. (I’m not.)
Eventually, I switched to the deviceorientation
event, for which you don’t need to collect permissions,1 and which gives you three simple
angles to determine device orientation.
There are limitations to this approach (tilting sideways by more than 90 degrees has gravity point up, for example), but it’s good enough for now. I might have to use quaternions anyway when switching to 3D.
The physical model is a simple one-particle system, where the only external force is gravity, and in every time step, acceleration, velocity, and position are updated. Hitting a boundary mirrors one component of the velocity vector. I had two bugs, which made me simplify to one dimension for a while:
The function that draws a new frame receives a timestamp, and I compare that to the previous step’s timestamp to get the timestep size. It’s typically around 18 ms or so, but I messed up and compared to the time at scene creation—resulting in the timestep getting larger and larger, and the slightest angle causing huge velocities.
When updating the velocity, you take the current velocity, and modify it using the average acceleration of the current and next timestep (Verlet integration):
\[\mathbf{v}(t + \Delta t) = \mathbf{v}(t) + \frac{\mathbf{a}(t) + \mathbf{a}(t + \Delta t)}{2} \Delta t\]
I somehow lost that \(\mathbf{v}(t)\) on the right-hand side, resulting in tiiiiiny velocities, like 1 pixel per 10 seconds 😅
But in the end, it’s working well enough for me to move on. I’ll probably try and fix the “doesn’t work on iPhones” issue at some point, but I don’t want to waste much time on it now. The current result is here (lets you select between a 1D and 2D version).
My fallback project for when I’ve had enough of the toybox is to work through the Building Git book, which guides through implementing Git in Ruby; and I’m reading the “Pickaxe book”, Programming Ruby, as a complement.
I’ve made steady progress with both, and really enjoy Ruby so far.
Much of it reminds me of Perl, but without the sigils (e.g., the
$
in my $str = "abc"
), but first-class
object-orientation,2 and a slightly less dramatic
community, as far as I can tell.
We’ve started a recurring Building Git meeting with a handful of people attending, though not everybody uses Ruby, but I’m glad I’ll have others to discuss progress and insights. So far, my Git implementation can create a commit to contain itself, but no branches, or history. The idea is that you never use Git for version control, but the tool itself while developing it. It was fun to see my prompt recognize that there seems to be a Git repository when the commit was successfully created for the first time!
There’s no way we’ll finish before my half-batch ends, but I hope I’ll be able to keep attending the meeting.
Most days, I solve two small Ruby problems, and one or two in jq, both on the Exercism platform. It’s a great way to get some programming in early in the day without having to think much about what exactly to work on. Ruby is an obvious choice to complement the reading above, and jq is fun because it’s stream-oriented and requires very different thinking from how I usually approach problems.
I’ve settled into a rhythm of doing an in-person (video) checkin in the mornings, and a short end-of-day written checkin.
There are lots of book clubs that I’d love to attend, but I don’t want to stretch myself too thin; however, the list has substantial overlap with my own “to read” list, so I hope to get around to these at some point:
plus (but not on my list) Understanding Distributed Systems, Learning Rust With Entirely Too Many Linked Lists, Modern Operating Systems…
On Friday, a small group visited the New York Transit Museum, which turned out to be super interesting. I think the most mind-blowing fact I learned about was that to keep the water out, the tunnels were pressurized up to 7 bar or so, so the workers suffered from all the problems you can have when you surface too fast when scuba diving (getting the “bends”). Not to mention what happened when there was a leak, and the workers were literally sucked out of the tunnel!
Tomorrow, we have “Impossible Stuff Day”, which is a bit like a one-day hackathon where you work on something that’s supposed to feel impossibly challenging, and definitely beyond the edge of your abilities. I’m not sure if I’ll come up with a suitable project idea, but I do have the offer to join a group that plans to settle the P vs. NP problem 😉
All in all, I’m happy with how things are going, and very much enjoy going to the hub every day and meet all the other Recursers. There are a few social activities later this week that I’m planning to attend; until now, there has been a lot of screen time for me mostly!
On Sunday, I have moved into my new AirBnB in Prospect Heights, and it’s a huge upgrade, both in terms of the unit, and the neighbourhood. I’m now just a few minutes away from Prospect Park, and plan to take advantage of that for my runs. (Which, sad face, seem to only happen on weekends.)
I’m eating not too terribly, but also not very varied; I think I know all Trader Joe’s salads now. The new place has a nice, fully stocked kitchen, so who knows, maybe I’ll cook sometimes.
But you do need to be in a “secure context”, so I had to figure out how to serve pages locally using HTTPS. I ended up using mkcert and a little Python script for the HTTPS server.↩︎
Perl just got experimental support for classes.↩︎