Some Python Raylib Notes
(top-level)

Coordinates vs pixels

Since I’m interested in using raylib to visualize some computations, I want to almost exclusively work with real world \(x\) and \(y\) coordinates (in meters), and then only at the end (when drawing to the screen) convert those to screen coordinates (in pixels) since that’s what raylib expects.

I also want the \(y\)-direction to point up instead of down (world origin at bottom left).

If we use subscripts “w” to mean world, and “s” to mean screen, and \(p\) and \(q\) for the \(x\)- and \(y\)-axis conversion factors between screen (pixels) and world (meters), we have:

\[x_{\text{s}} = px_{\text{w}}\]

\[y_{\text{s}} = -qy_{\text{w}} + h\]

where \(h\) is screen_height in pixels.

And so, likewise, to go back the other way:

\[x_{\text{w}} = \frac{x_{\text{s}}}{p}\]

\[y_{\text{w}} = \frac{1}{q} (h-y_{\text{s}})\]

To find those constants \(p\), \(q\), and \(h\), suppose, for example, I want:

When \(x_{\text{w}}\) = 10 m, that means \(x_{\text{s}}\) must be 800 px. Thus \(p\) = 80 px/m.

As for \(q\), since we know that the width/height ratios of the world and the screen are the same, it follows that the max \(y_{\text{s}}\) is 640 px, and thus \(h\), is 640 px. If we then put in the pair \(y_{\text{s}}\) = 0 px and \(y_{\text{w}}\) = 8 m, we get \(q\) = 640 px / 8 m = 80 px/m. The same as \(p\)! Of course, this is no surprise, because we are keeping our aspect ratio on the screen the same as in the real world. :)

Without the units present, the equations above now look like:

\[x_{\text{s}} = 80 x_{\text{w}}\]

\[y_{\text{s}} = -80 y_{\text{w}} + 640\]

and

\[x_{\text{w}} = \frac{x_{\text{s}}}{80}\]

\[y_{\text{w}} = \frac{1}{80} (640-y_{\text{s}})\]

Here’s the code (“wo” means “world”, “sc” means “screen”):

see ~/temp/foo.py

Run it and see how the screen is “10 m wide” and “8 m tall”.