# Coordinates vs pixels

Since I’m interested in using raylib to visualize some computations, I want to deal with world coordinates (in, say, meters), rather than screen coordinates (in pixels).

For example, if you want:

• y-direction to point up instead of down (origin at bottom left)
• the window to be 800 px wide
• x goes from 0 $$\rightarrow$$ 10
• y goes from 0 $$\rightarrow$$ 8

When my code generates x and y values in meters, I want to convert those “world coords” (m) into “screen coords” (pixels) so I can draw things. If we use “w” to mean world, and “s” to mean screen, and just put in $$C_{1}$$ and $$C_{2}$$ to stand-in for the conversion factors between screen (pixels) and world (meters):

$x_{\text{s}} = C_{1}x_{\text{w}}$

$y_{\text{s}} = -y_{\text{w}} + h$

where $$h$$ is screen_height.

Here’s the code:

#!/usr/bin/env python3

import pyray as pr

# Conversion factor:
# 800 px == 10 meters  (or, 80 px == 1 m)

screen_width  = 800  # = 10 m
screen_height = 640  # =  8 m (converted 8 m to px)

# Location of our little box we'll draw, in real world
# coords (meters).
x_wo_loc = 1.0
y_wo_loc = 2.0

def main():
init_game()
while not pr.window_should_close():
update_game()

pr.begin_drawing()
pr.clear_background(pr.BLACK)

draw_game()

pr.end_drawing()

pr.close_window()

def init_game():
pr.init_window(screen_width, screen_height,
"Now using real-world coords")
pr.set_target_fps(60)

def update_game():
global x_wo_loc, y_wo_loc
# Pressing a key moves the object in 10 cm (0.10 m) increments.
# Note difference betw is_key_down & is_key_pressed. :)
if pr.is_key_pressed(pr.KEY_RIGHT):
x_wo_loc += 0.10
if pr.is_key_down(pr.KEY_LEFT):
x_wo_loc -= 0.10
if pr.is_key_down(pr.KEY_UP):
y_wo_loc += 0.10
if pr.is_key_down(pr.KEY_DOWN):
y_wo_loc -= 0.10

def draw_game():
pr.draw_text("x: " + str(round(x_wo_loc, 2)) + " m",
x_sc(0.2), y_sc(7.6), 18, pr.GREEN)
pr.draw_text("y: " + str(round(y_wo_loc, 2)) + " m",
x_sc(0.2), y_sc(7.2), 18, pr.GREEN)

pr.draw_rectangle(x_sc(x_wo_loc),
y_sc(y_wo_loc),
10, 10, pr.RED)

#----------------------------------------------------------
# Convert pixel coord val (n) to value in meters.
def to_m(n):
# * 10 / 800
return n / 80

# Convert meters to pixels
def to_px(x):
# * 800 / 10
return int(x * 80)

# x world to screen coord
def x_sc(x_wo):
return to_px(x_wo)

# x screen to world coord
def x_wo(x_sc):
return to_m(x_sc)

# y world to screen coord
def y_sc(y_wo):
return -1 * to_px(y_wo) + screen_height

# y screen to world coord
def y_wo(y_sc):
return to_m(screen_height - y_sc)

#---------------
main()

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