This is an early game prototype. If loaded correctly, you should be watching the above interactive HTML5 Demo. Use WASD keys to move the blue circle. (Or tap|click and hold on a position to attract the circle).
The simulation is made with Box2D physics on the Defold engine. The orange square, the circle, and the gray boat are just standard collision objects with some linear and angular damping, while gravity is null.
The fun is in the Green Boat!
For any other objects, using linear and angular damping was fine to give a sense of water resistance. But my green boat need a more realistic approach: it has a shape, and that shape should affect the simulation. The boat needs more viscosity force affecting the lateral motion!
Viscosity friction is proportional to the velocity, and the vector points the opposite. So I needed to get the Lateral Velocity (Lv), projecting the linear velocity (V) onto the axis perpendicular to the boat facing direction. Let’s call the last one as Pd, and make it normalized (length = 1).
We get a scalar showing the projection with the dot product: S = vmath.dot( V, Pd).
Then the lateral velocity vector is: Lv = Pd * S (assuming Pd is normalized).
Finally, our opposite force is: F = – Lv * K (Where K is “made up” constant :P).
Apply this force to the center of mass of the object on every frame and that’s it!
For more realism in not-so-low speeds, I think we should use the square of the velocity. But without it, we also get the effect and it works just fine! Go back up and keep playing with the simulation. Compare how the green and the gray boat react to the circle pushing. Take a look at the vector lines drawn over the green boat: there is the direction and linear velocity in white and the Lateral Velocity in green.
My plans are to make a game out of this. Next step: oars. If you like it, keep tuned.
EXTRA HINT: Applying the lateral friction force, not in the center of mass, but a bit behind it, makes a feeling that the boat is less resistant on its front part (the bow). Also good for simulating arrows or bullets 😉