Info
This post was imported from a personal note. It may contain inside jokes, streams of consciousness, errors, and other nonsense.
I’m adding some logic to the Boids so they can detect food sources. That means the Boid class needs a reference to the Simulation class. And since the Simulation contains a bunch of Boids, it needs a reference to the Boid class. Problem.
TIL thanks to this answer (https://stackoverflow.com/a/628079) you can work around this using “Forward Declarations” and address or pointer references.
There are two main points: the compiler needs to know how much memory to allocate for each object and when each object includes an instance of the other the size can’t be determined. So use an address reference or pointer instead because those have a size that doesn’t depend on the size of the class.
Second point: one of the two classes will come first and it’s not going to know about the other class. In that case we can just declare, “this symbol is a class and don’t worry you’ll find out more about that class later.” That’s the forward declaration and goes like this:
boid.hpp
class Simulation;
class Boid {
...
}
…
Man, using Eigen is a pain. It’d probably be great if I knew my linear algebra but.
Here’s the code for rotating toward a food source:
Vector2f toFoodSource = foodSource->position - position;
float dist = toFoodSource.norm();
if (dist <= senseRadius) {
float angleBetween = atan2(direction.x() * toFoodSource.y() - direction.y() * toFoodSource.x(), toFoodSource.dot(direction));
Rotation2Df rotation(angleBetween * 0.01f);
direction = rotation.toRotationMatrix() * direction;
Had to use a manual calculation for getting the angle between. Might be a better way to do that but I don’t know it.
Then you instantiate a rotation and convert it to a rotation matrix and multiply it by the vector you want to rotate.
I guess I’m coming from Processing which has a bunch of helpers for common tasks and now I’m working with libraries that are much more generic. They can solve a lot more problems and do so very efficiently but they also take some learning?
Rendering Refactor #
I originally had the root renderer, SimRenderer, instantiating and drawing all the SFML shapes. That was getting unwieldy so I moved that responsibility into the renderer classes. Looks much better now.
Still a weird thing where the renderer needs to call the “getNearestFoodSource()” method on the simulation. Might try to get rid of that. That information should probably be duplicated into the Boid or Avatar being rendered.