math: added function to reverse isometric transformation.
authorLukas Krickl <lukas@krickl.dev>
Thu, 5 Mar 2026 04:11:40 +0000 (05:11 +0100)
committerLukas Krickl <lukas@krickl.dev>
Thu, 5 Mar 2026 04:11:40 +0000 (05:11 +0100)
This function will of course lose some data if applied since we only
work with integers, but in general it is close enough.

src/tests/t_math.c
src/u_math.c

index 8323229f7203b43f52821858f16c0bedd3fb1b50..9593985b1a927424cd1082670757baf4159af615 100644 (file)
@@ -22,19 +22,44 @@ int t_test_tile_to_screen(void) {
 }
 
 int t_test_point_to_world_world_to_point(void) {
-       struct u_vec2 res = u_point_to_screen(1, 2);
-       T_ASSERT(res.x == -2 && res.y == 1, ("point to screen %d/%d\n", res.x, res.y));
+       struct u_vec2 res;
+       i32 x, y;
+       const i32 check_max = 1024 * 8;
+
+       /* 1 */
+       res = u_point_to_screen(4, 2);
+       T_ASSERT(res.x == 0 && res.y == 2, ("point to screen %d/%d\n", res.x, res.y));
        
        res = u_point_to_world(res.x, res.y);
-       T_ASSERT(res.x == 1 && res.y == 2, ("point to world %d/%d\n", res.x, res.y));
-
+       T_ASSERT(res.x == 4 && res.y == 2, ("point to world %d/%d\n", res.x, res.y));
 
+       /* 2 */
        res = u_point_to_screen(32, 64);
        T_ASSERT(res.x == -48 && res.y == 40, ("point to screen %d/%d\n", res.x, res.y));
 
        res = u_point_to_world(res.x, res.y);
        T_ASSERT(res.x == 32 && res.y == 64, ("point to world %d/%d\n", res.x, res.y));
 
+       /* 3 */
+       res = u_point_to_screen(256, 128);
+       T_ASSERT(res.x == 0 && res.y == 128, ("point to screen %d/%d\n", res.x, res.y));
+
+       res = u_point_to_world(res.x, res.y);
+       T_ASSERT(res.x == 256 && res.y == 128, ("point to world %d/%d\n", res.x, res.y));
+
+       /* test all points 
+        * tiles on the grid line should work fine
+        * all other tiles might lose data when transforming back
+        * because it is all integer coordinates
+        */
+       for (x = -check_max; x < check_max; x += R_TILE_W) {
+               for (y = -check_max; y < check_max; y += R_TILE_H) {
+                       res = u_point_to_screen(x, y);
+                       res = u_point_to_world(res.x, res.y);
+                       T_ASSERT(res.x == x && res.y == y, ("point to world from %d/%d to %d/%d\n", x, y, res.x, res.y));
+               }
+       }
+
        return 0;
 }
 
index 4ddfb8827988cc237f33e0dea59df56eb9fa3013..e266bcf014e8a163b6e9618c67596916fbdf9e6d 100644 (file)
@@ -26,8 +26,8 @@ struct u_vec2 u_point_to_screen(i32 x, i32 y) {
 struct u_vec2 u_point_to_world(i32 x, i32 y) {
        struct u_vec2 r;
 
-       r.x = (y + x);
        r.y = (2 * y - x) / 2;
+       r.x = (x + 2 * y);
 
        return r;
 }