From 68b52b7edc4c562096d6ecf0242535a6d2bada3d Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Sun, 19 May 2019 15:38:19 -0400 Subject: [PATCH 01/15] Camera: Update frame_top/frame_bottom --- ppb/camera.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ppb/camera.py b/ppb/camera.py index 6a9d58ee..9a88c6a8 100644 --- a/ppb/camera.py +++ b/ppb/camera.py @@ -35,11 +35,11 @@ def __init__(self, viewport: Sequence[int]=(0, 0, 800, 600), @property def frame_top(self) -> Number: - return self.position.y - self.half_height + return self.position.y + self.half_height @property def frame_bottom(self) -> Number: - return self.position.y + self.half_height + return self.position.y - self.half_height @property def frame_left(self) -> Number: From 2de1d3ac92f517811e50fc96a7c6e4f6927da816 Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Sun, 19 May 2019 15:57:22 -0400 Subject: [PATCH 02/15] Sprites: Update SIDES map --- ppb/sprites.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ppb/sprites.py b/ppb/sprites.py index f9b0cf8e..9abdc37d 100644 --- a/ppb/sprites.py +++ b/ppb/sprites.py @@ -21,8 +21,8 @@ class Side: sides = { LEFT: ('x', -1), RIGHT: ('x', 1), - TOP: ('y', -1), - BOTTOM: ('y', 1) + TOP: ('y', 1), + BOTTOM: ('y', -1) } def __init__(self, parent: 'BaseSprite', side: str): From 597abf9cb69d20668c54ff05eeb73eba0960908f Mon Sep 17 00:00:00 2001 From: Piper Thunstrom Date: Sun, 19 May 2019 19:07:16 -0400 Subject: [PATCH 03/15] Adds more translate_to_viewport tests, fixes bad tests. --- tests/test_camera.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_camera.py b/tests/test_camera.py index b28bfec7..54275f04 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -42,8 +42,16 @@ def test_camera_translate_to_viewport(): assert cam.translate_to_viewport(Vector(0, 0)) == Vector(400, 300) assert cam.translate_to_viewport(Vector(2, 1)) == Vector(560, 220) cam.position = Vector(5, 5) - assert cam.translate_to_viewport(Vector(5, -5)) == Vector(400, 300) - assert cam.translate_to_viewport(Vector(7, -4)) == Vector(560, 220) + assert cam.translate_to_viewport(Vector(5, 5)) == Vector(400, 300) + assert cam.translate_to_viewport(Vector(7, 4)) == Vector(560, 380) + + +def test_camera_translate_to_viewport_2(): + cam = Camera(viewport=(0, 0, 800, 600), pixel_ratio=1) + assert cam.position == Vector(0, 0) + assert cam.translate_to_viewport(Vector(0, 0)) == Vector(400, 300) + assert cam.translate_to_viewport(Vector(100, 100)) == Vector(500, 200) + assert cam.translate_to_viewport(Vector(-150, -500)) == Vector(250, 800) def test_sprite_in_viewport(): From 3123703dbc0118363d3ee4b761e6f1367e218570 Mon Sep 17 00:00:00 2001 From: Piper Thunstrom Date: Sun, 19 May 2019 19:07:44 -0400 Subject: [PATCH 04/15] Fixes translate_to_viewport --- ppb/camera.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ppb/camera.py b/ppb/camera.py index 9a88c6a8..c1fac1b9 100644 --- a/ppb/camera.py +++ b/ppb/camera.py @@ -6,6 +6,7 @@ from ppb.sprites import BaseSprite from ppb.flags import DoNotRender + class Camera(BaseSprite): image = DoNotRender @@ -108,6 +109,4 @@ def translate_to_viewport(self, point: Vector) -> Vector: """ Converts a vector from in-game to pixel-based window coordinate space """ - point = point.update(y=-point.y) - offset = (point - self.position) * self.pixel_ratio - return self.viewport_offset + offset + return Vector(point.x - self.frame_left, self.frame_top - point.y) * self.pixel_ratio \ No newline at end of file From 5de5a478f399336fb372696b14beb740a2535243 Mon Sep 17 00:00:00 2001 From: Piper Thunstrom Date: Sun, 19 May 2019 19:10:08 -0400 Subject: [PATCH 05/15] Fixes Camera.in_frame --- ppb/camera.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ppb/camera.py b/ppb/camera.py index c1fac1b9..accf276c 100644 --- a/ppb/camera.py +++ b/ppb/camera.py @@ -93,8 +93,8 @@ def point_in_viewport(self, point:Vector) -> bool: def in_frame(self, sprite: BaseSprite) -> bool: return (self.frame_left <= sprite.right and self.frame_right >= sprite.left and - self.frame_top <= sprite.bottom and - self.frame_bottom >= sprite.top + self.frame_top >= sprite.bottom and + self.frame_bottom <= sprite.top ) def translate_to_frame(self, point: Vector) -> Vector: From 2536dd7bea3f4968d29b1ce612d539ce7d689fb2 Mon Sep 17 00:00:00 2001 From: Piper Thunstrom Date: Sun, 19 May 2019 19:27:58 -0400 Subject: [PATCH 06/15] Fixes sprite tests. --- ppb/camera.py | 2 +- tests/test_sprites.py | 52 +++++++++++++++++++++---------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/ppb/camera.py b/ppb/camera.py index accf276c..010cc866 100644 --- a/ppb/camera.py +++ b/ppb/camera.py @@ -109,4 +109,4 @@ def translate_to_viewport(self, point: Vector) -> Vector: """ Converts a vector from in-game to pixel-based window coordinate space """ - return Vector(point.x - self.frame_left, self.frame_top - point.y) * self.pixel_ratio \ No newline at end of file + return Vector(point.x - self.frame_left, self.frame_top - point.y) * self.pixel_ratio diff --git a/tests/test_sprites.py b/tests/test_sprites.py index da84761f..e1ced2c9 100644 --- a/tests/test_sprites.py +++ b/tests/test_sprites.py @@ -60,31 +60,31 @@ def test_right(self): self.assertEqual(self.sprite.position.y, 0) def test_top(self): - self.assertEqual(self.sprite.top, -0.5) - self.assertEqual(self.wide_sprite.top, 1) + self.assertEqual(self.sprite.top, 0.5) + self.assertEqual(self.wide_sprite.top, 3) self.sprite.top = 0 self.assertEqual(self.sprite.position.x, 0) - self.assertEqual(self.sprite.position.y, 0.5) + self.assertEqual(self.sprite.position.y, -0.5) self.sprite.top += 2 self.assertEqual(self.sprite.position.x, 0) - self.assertEqual(self.sprite.position.y, 2.5) + self.assertEqual(self.sprite.position.y, 1.5) def test_bottom(self): - self.assertEqual(self.sprite.bottom, 0.5) - self.assertEqual(self.wide_sprite.bottom, 3) + self.assertEqual(self.sprite.bottom, -0.5) + self.assertEqual(self.wide_sprite.bottom, 1) self.sprite.bottom = 0 self.assertEqual(self.sprite.position.x, 0) - self.assertEqual(self.sprite.position.y, -0.5) + self.assertEqual(self.sprite.position.y, 0.5) self.sprite.bottom += 2 self.assertEqual(self.sprite.position.x, 0) - self.assertEqual(self.sprite.position.y, 1.5) + self.assertEqual(self.sprite.position.y, 2.5) def test_left_top(self): - self.assertEqual(self.sprite.left.top, Vector(-0.5, -0.5)) + self.assertEqual(self.sprite.left.top, Vector(-0.5, 0.5)) self.sprite.left.top = (2, 2) self.assertEqual(self.sprite.left.top, Vector(2, 2)) @@ -95,10 +95,10 @@ def test_left_top(self): result = self.sprite.left.top + (3, 3) self.assertEqual(result, Vector(7, 7)) - self.assertEqual(self.sprite.position, Vector(4.5, 4.5)) + self.assertEqual(self.sprite.position, Vector(4.5, 3.5)) def test_left_bottom(self): - self.assertEqual(self.sprite.left.bottom, Vector(-0.5, 0.5)) + self.assertEqual(self.sprite.left.bottom, Vector(-0.5, -0.5)) self.sprite.left.bottom = (1, 2) self.assertEqual(self.sprite.left.bottom, Vector(1, 2)) @@ -109,7 +109,7 @@ def test_left_bottom(self): result = self.sprite.left.bottom + (3, 2) self.assertEqual(result, Vector(6, 5)) - self.assertEqual(self.sprite.position, Vector(3.5, 2.5)) + self.assertEqual(self.sprite.position, Vector(3.5, 3.5)) def test_left_center(self): self.assertEqual(self.sprite.left.center, Vector(-0.5, 0)) @@ -126,7 +126,7 @@ def test_left_center(self): self.assertEqual(self.sprite.position, Vector(3.5, 2)) def test_right_bottom(self): - self.assertEqual(self.sprite.right.bottom, Vector(0.5, 0.5)) + self.assertEqual(self.sprite.right.bottom, Vector(0.5, -0.5)) self.sprite.right.bottom = (1, 1) self.assertEqual(self.sprite.right.bottom, Vector(1, 1)) @@ -137,10 +137,10 @@ def test_right_bottom(self): result = self.sprite.right.bottom + (2, 3) self.assertEqual(result, Vector(5, 5)) - self.assertEqual(self.sprite.position, Vector(2.5, 1.5)) + self.assertEqual(self.sprite.position, Vector(2.5, 2.5)) def test_right_top(self): - self.assertEqual(self.sprite.right.top, Vector(0.5, -0.5)) + self.assertEqual(self.sprite.right.top, Vector(0.5, 0.5)) self.sprite.right.top = (1, 1) self.assertEqual(self.sprite.right.top, Vector(1, 1)) @@ -151,7 +151,7 @@ def test_right_top(self): result = self.sprite.right.top + (2, 3) self.assertEqual(result, Vector(5, 5)) - self.assertEqual(self.sprite.position, Vector(2.5, 2.5)) + self.assertEqual(self.sprite.position, Vector(2.5, 1.5)) def test_right_center(self): self.assertEqual(self.sprite.right.center, Vector(0.5, 0)) @@ -184,7 +184,7 @@ def test_right_left(self): self.assertRaises(AttributeError, setattr, self.sprite.right, "left", Vector(1, 1)) def test_top_left(self): - self.assertEqual(self.sprite.top.left, Vector(-0.5, -0.5)) + self.assertEqual(self.sprite.top.left, Vector(-0.5, 0.5)) self.sprite.top.left = (2, 2) self.assertEqual(self.sprite.top.left, Vector(2, 2)) @@ -195,10 +195,10 @@ def test_top_left(self): result = self.sprite.top.left + (3, 3) self.assertEqual(result, Vector(7, 7)) - self.assertEqual(self.sprite.position, Vector(4.5, 4.5)) + self.assertEqual(self.sprite.position, Vector(4.5, 3.5)) def test_top_right(self): - self.assertEqual(self.sprite.top.right, Vector(0.5, -0.5)) + self.assertEqual(self.sprite.top.right, Vector(0.5, 0.5)) self.sprite.top.right = (1, 1) self.assertEqual(self.sprite.top.right, Vector(1, 1)) @@ -209,10 +209,10 @@ def test_top_right(self): result = self.sprite.top.right + (2, 3) self.assertEqual(result, Vector(5, 5)) - self.assertEqual(self.sprite.position, Vector(2.5, 2.5)) + self.assertEqual(self.sprite.position, Vector(2.5, 1.5)) def test_top_center(self): - self.assertEqual(self.sprite.top.center, Vector(0, -0.5)) + self.assertEqual(self.sprite.top.center, Vector(0, 0.5)) self.sprite.top.center = (1, 1) self.assertEqual(self.sprite.top.center, Vector(1, 1)) @@ -226,7 +226,7 @@ def test_top_bottom(self): self.assertRaises(AttributeError, setattr, self.sprite.top, "bottom", Vector(1, 1)) def test_bottom_left(self): - self.assertEqual(self.sprite.bottom.left, Vector(-0.5, 0.5)) + self.assertEqual(self.sprite.bottom.left, Vector(-0.5, -0.5)) self.sprite.bottom.left = (2, 2) self.assertEqual(self.sprite.bottom.left, Vector(2, 2)) @@ -237,10 +237,10 @@ def test_bottom_left(self): result = self.sprite.bottom.left + (3, 3) self.assertEqual(result, Vector(7, 7)) - self.assertEqual(self.sprite.position, Vector(4.5, 3.5)) + self.assertEqual(self.sprite.position, Vector(4.5, 4.5)) def test_bottom_right(self): - self.assertEqual(self.sprite.bottom.right, Vector(0.5, 0.5)) + self.assertEqual(self.sprite.bottom.right, Vector(0.5, -0.5)) self.sprite.bottom.right = (1, 1) self.assertEqual(self.sprite.bottom.right, Vector(1, 1)) @@ -251,10 +251,10 @@ def test_bottom_right(self): result = self.sprite.bottom.right + (2, 3) self.assertEqual(result, Vector(5, 5)) - self.assertEqual(self.sprite.position, Vector(2.5, 1.5)) + self.assertEqual(self.sprite.position, Vector(2.5, 2.5)) def test_bottom_center(self): - self.assertEqual(self.sprite.bottom.center, Vector(0, 0.5)) + self.assertEqual(self.sprite.bottom.center, Vector(0, -0.5)) self.sprite.bottom.center = (1, 1) self.assertEqual(self.sprite.bottom.center, Vector(1, 1)) From 1691e5be7f863ce31c82ddbd53d5927a5c4d862b Mon Sep 17 00:00:00 2001 From: Piper Thunstrom Date: Sun, 19 May 2019 19:28:22 -0400 Subject: [PATCH 07/15] Fixes top and bottom setters on Sprite. --- ppb/sprites.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ppb/sprites.py b/ppb/sprites.py index 9abdc37d..61c02198 100644 --- a/ppb/sprites.py +++ b/ppb/sprites.py @@ -272,7 +272,7 @@ def top(self): @top.setter def top(self, value): - self.position = Vector(self.position.x, value + self._offset_value) + self.position = Vector(self.position.x, value - self._offset_value) @property def bottom(self): @@ -280,7 +280,7 @@ def bottom(self): @bottom.setter def bottom(self, value): - self.position = Vector(self.position.x, value - self._offset_value) + self.position = Vector(self.position.x, value + self._offset_value) @property def _offset_value(self): From e37db7e170baddc97b976be96d71626972f29509 Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Tue, 21 May 2019 15:25:54 -0400 Subject: [PATCH 08/15] Add a hypothesis test --- tests/test_camera.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_camera.py b/tests/test_camera.py index 54275f04..9e654394 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -2,6 +2,9 @@ from ppb import Vector from ppb.camera import Camera +from hypothesis import given +import hypothesis.strategies as st + def test_camera_move(): cam = Camera() @@ -79,3 +82,24 @@ def test_viewport_change_affects_frame_height(): assert cam.frame_left == -5 cam.viewport_width = 400 assert cam.frame_left == -2.5 + + +@given( + vp_width=st.integers(min_value=1), + vp_height=st.integers(min_value=1), + pixel_ratio=st.floats(min_value=1, allow_nan=False, allow_infinity=False), + cam_x=st.floats(allow_nan=False, allow_infinity=False), + cam_y=st.floats(allow_nan=False, allow_infinity=False), + point_x=st.floats(allow_nan=False, allow_infinity=False), + point_y=st.floats(allow_nan=False, allow_infinity=False), +) +def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_x, cam_y, point_x, point_y): + cam = Camera( + viewport=(0, 0, vp_width, vp_height), + pixel_ratio=pixel_ratio, + ) + cam.position = Vector(cam_x, cam_y) + point = Vector(point_x, point_y) + + assert cam.translate_to_viewport(cam.translate_to_frame(point)) == point + assert cam.translate_to_frame(cam.translate_to_viewport(point)) == point From 3e7f09f7b997a4ac5c02c0b47a736730548b5082 Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Tue, 21 May 2019 17:09:54 -0400 Subject: [PATCH 09/15] Camera: Add a metamorphic test --- tests/test_camera.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/test_camera.py b/tests/test_camera.py index 9e654394..514f353b 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -2,7 +2,7 @@ from ppb import Vector from ppb.camera import Camera -from hypothesis import given +from hypothesis import given, assume import hypothesis.strategies as st @@ -103,3 +103,33 @@ def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_x, cam_y assert cam.translate_to_viewport(cam.translate_to_frame(point)) == point assert cam.translate_to_frame(cam.translate_to_viewport(point)) == point + + +@given( + vp_width=st.integers(min_value=1), + vp_height=st.integers(min_value=1), + pixel_ratio=st.floats(min_value=1, allow_nan=False, allow_infinity=False), + cam_x=st.floats(allow_nan=False, allow_infinity=False), + cam_y=st.floats(allow_nan=False, allow_infinity=False), + point_x=st.floats(allow_nan=False, allow_infinity=False), + point_y=st.floats(allow_nan=False, allow_infinity=False), + delta_x=st.floats(allow_nan=False, allow_infinity=False), + delta_y=st.floats(allow_nan=False, allow_infinity=False), +) +def test_transfromation_movement( + vp_width, vp_height, pixel_ratio, cam_x, cam_y, point_x, point_y, delta_x, delta_y, +): + cam = Camera( + viewport=(0, 0, vp_width, vp_height), + pixel_ratio=pixel_ratio, + ) + cam.position = Vector(cam_x, cam_y) + point = Vector(point_x, point_y) + delta = Vector(delta_x, delta_y) + + assume(delta.length != 0) + + point_moved = point + delta + + assert (cam.translate_to_frame(point_moved) - cam.translate_to_frame(point)).length / delta.length == pixel_ratio + assert delta.length / (cam.translate_to_viewport(point_moved) - cam.translate_to_viewport(point)).length == pixel_ratio From a3f48e843719d03363b3e8331a71b5268086fc95 Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Tue, 21 May 2019 17:28:06 -0400 Subject: [PATCH 10/15] Camera: Attempted to rewrite translate_to_frame(), failed --- ppb/camera.py | 13 ++++++------- tests/test_camera.py | 4 ++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ppb/camera.py b/ppb/camera.py index 010cc866..9789fe1d 100644 --- a/ppb/camera.py +++ b/ppb/camera.py @@ -1,5 +1,4 @@ from typing import Sequence -from typing import Union from numbers import Number from ppb import Vector @@ -11,8 +10,8 @@ class Camera(BaseSprite): image = DoNotRender - def __init__(self, viewport: Sequence[int]=(0, 0, 800, 600), - pixel_ratio: float=64): + def __init__(self, viewport: Sequence[int] = (0, 0, 800, 600), + pixel_ratio: float = 64): """ viewport: A container of origin x, origin y, width, and @@ -65,6 +64,7 @@ def half_height(self) -> float: @property def half_width(self) -> float: return self.frame_width / 2 + @property def viewport_width(self) -> int: return self._viewport_width @@ -83,7 +83,7 @@ def viewport_height(self, value: int): self._viewport_height = value self.viewport_offset = Vector(self.viewport_width / 2, value / 2) - def point_in_viewport(self, point:Vector) -> bool: + def point_in_viewport(self, point: Vector) -> bool: px, py = point vpx, vpy = self.viewport_origin vpw = self.viewport_width @@ -101,9 +101,8 @@ def translate_to_frame(self, point: Vector) -> Vector: """ Converts a vector from pixel-based window to in-game coordinate space """ - offset = (point - self.viewport_offset) * (1/self.pixel_ratio) - loc = self.position + offset - return loc.update(y=-loc.y) + scaled = point / self.pixel_ratio + return Vector(self.frame_left + scaled.x, self.frame_top - point.y) def translate_to_viewport(self, point: Vector) -> Vector: """ diff --git a/tests/test_camera.py b/tests/test_camera.py index 514f353b..b3ad5f11 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -32,6 +32,10 @@ def test_camera_point_in_viewport_not_at_origin(): def test_camera_translate_to_frame(): cam = Camera(viewport=(0, 0, 800, 600), pixel_ratio=80) assert cam.position == Vector(0, 0) + assert cam.frame_top == 3.75 + assert cam.frame_bottom == -3.75 + assert cam.frame_left == -5 + assert cam.frame_right == 5 assert cam.translate_to_frame(Vector(400, 300)) == Vector(0, 0) assert cam.translate_to_frame(Vector(560, 220)) == Vector(2, 1) cam.position = Vector(5, 5) From faf341fe3bde146e5c5aca835305b287a37ce948 Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Thu, 23 May 2019 13:32:09 -0400 Subject: [PATCH 11/15] Camera: Fix up viewport->frame conversion --- ppb/camera.py | 6 +++++- tests/test_camera.py | 16 ++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ppb/camera.py b/ppb/camera.py index 9789fe1d..6d407f1c 100644 --- a/ppb/camera.py +++ b/ppb/camera.py @@ -101,11 +101,15 @@ def translate_to_frame(self, point: Vector) -> Vector: """ Converts a vector from pixel-based window to in-game coordinate space """ + # 1. Scale from pixels to game unites scaled = point / self.pixel_ratio - return Vector(self.frame_left + scaled.x, self.frame_top - point.y) + # 2. Reposition relative to frame edges + return Vector(self.frame_left + scaled.x, self.frame_top - scaled.y) def translate_to_viewport(self, point: Vector) -> Vector: """ Converts a vector from in-game to pixel-based window coordinate space """ + # 1. Reposition based on frame edges + # 2. Scale from game units to pixels return Vector(point.x - self.frame_left, self.frame_top - point.y) * self.pixel_ratio diff --git a/tests/test_camera.py b/tests/test_camera.py index b3ad5f11..94968029 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -1,3 +1,5 @@ +from math import isclose + from ppb import BaseSprite from ppb import Vector from ppb.camera import Camera @@ -39,8 +41,8 @@ def test_camera_translate_to_frame(): assert cam.translate_to_frame(Vector(400, 300)) == Vector(0, 0) assert cam.translate_to_frame(Vector(560, 220)) == Vector(2, 1) cam.position = Vector(5, 5) - assert cam.translate_to_frame(Vector(400, 300)) == Vector(5, -5) - assert cam.translate_to_frame(Vector(560, 220)) == Vector(7, -4) + assert cam.translate_to_frame(Vector(400, 300)) == Vector(5, 5) + assert cam.translate_to_frame(Vector(560, 220)) == Vector(7, 6) def test_camera_translate_to_viewport(): @@ -105,8 +107,8 @@ def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_x, cam_y cam.position = Vector(cam_x, cam_y) point = Vector(point_x, point_y) - assert cam.translate_to_viewport(cam.translate_to_frame(point)) == point - assert cam.translate_to_frame(cam.translate_to_viewport(point)) == point + assert cam.translate_to_viewport(cam.translate_to_frame(point)).isclose(point, abs_tol=1e-5) + assert cam.translate_to_frame(cam.translate_to_viewport(point)).isclose(point, abs_tol=1e-5) @given( @@ -135,5 +137,7 @@ def test_transfromation_movement( point_moved = point + delta - assert (cam.translate_to_frame(point_moved) - cam.translate_to_frame(point)).length / delta.length == pixel_ratio - assert delta.length / (cam.translate_to_viewport(point_moved) - cam.translate_to_viewport(point)).length == pixel_ratio + diff = cam.translate_to_frame(point_moved) - cam.translate_to_frame(point) + assert isclose(diff.length / delta.length, pixel_ratio) + diff = cam.translate_to_viewport(point_moved) - cam.translate_to_viewport(point) + assert isclose(delta.length / diff.length, pixel_ratio) From 006eb2511850588b62bec31aa950b810b1f653f8 Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Fri, 24 May 2019 12:27:13 -0400 Subject: [PATCH 12/15] Camera: Work on transform tests more --- tests/test_camera.py | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/tests/test_camera.py b/tests/test_camera.py index 94968029..d035aa57 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -4,7 +4,7 @@ from ppb import Vector from ppb.camera import Camera -from hypothesis import given, assume +from hypothesis import given, assume, note, example import hypothesis.strategies as st @@ -93,12 +93,13 @@ def test_viewport_change_affects_frame_height(): @given( vp_width=st.integers(min_value=1), vp_height=st.integers(min_value=1), - pixel_ratio=st.floats(min_value=1, allow_nan=False, allow_infinity=False), + pixel_ratio=st.floats(min_value=1, max_value=1e5, allow_nan=False, allow_infinity=False), cam_x=st.floats(allow_nan=False, allow_infinity=False), cam_y=st.floats(allow_nan=False, allow_infinity=False), point_x=st.floats(allow_nan=False, allow_infinity=False), point_y=st.floats(allow_nan=False, allow_infinity=False), ) +@example(vp_width=1, vp_height=1, pixel_ratio=1.0, cam_x=0.0, cam_y=0.0, point_x=0.0, point_y=0.0) def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_x, cam_y, point_x, point_y): cam = Camera( viewport=(0, 0, vp_width, vp_height), @@ -107,14 +108,30 @@ def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_x, cam_y cam.position = Vector(cam_x, cam_y) point = Vector(point_x, point_y) - assert cam.translate_to_viewport(cam.translate_to_frame(point)).isclose(point, abs_tol=1e-5) - assert cam.translate_to_frame(cam.translate_to_viewport(point)).isclose(point, abs_tol=1e-5) + # Some underflow/loss of resolution problems + assume(cam.frame_left != cam.frame_right) + assume(cam.frame_top != cam.frame_bottom) + + note(f"frame: ({cam.frame_left}, {cam.frame_bottom}) -> ({cam.frame_right}, {cam.frame_top})") + note(f"point: {point}") + + point_frame = cam.translate_to_frame(point) + note(f"point->frame: {point_frame}") + point_viewport = cam.translate_to_viewport(point_frame) + note(f"point->frame->viewport: {point_viewport}") + assert point_viewport.isclose(point, rel_tol=1e-5) + + point_viewport = cam.translate_to_viewport(point) + note(f"point->viewport: {point_viewport}") + point_frame = cam.translate_to_viewport(point_viewport) + note(f"point->viewport->frame: {point_frame}") + assert point_frame.isclose(point, rel_tol=1e-5) @given( vp_width=st.integers(min_value=1), vp_height=st.integers(min_value=1), - pixel_ratio=st.floats(min_value=1, allow_nan=False, allow_infinity=False), + pixel_ratio=st.floats(min_value=1, max_value=1e5, allow_nan=False, allow_infinity=False), cam_x=st.floats(allow_nan=False, allow_infinity=False), cam_y=st.floats(allow_nan=False, allow_infinity=False), point_x=st.floats(allow_nan=False, allow_infinity=False), @@ -133,11 +150,20 @@ def test_transfromation_movement( point = Vector(point_x, point_y) delta = Vector(delta_x, delta_y) + note(f"point: {point}") + note(f"delta: {delta}") + assume(delta.length != 0) point_moved = point + delta + assume(point_moved != point) # This will happen when delta is too small to make an effect + + note(f"point moved: {point_moved}") + diff = cam.translate_to_frame(point_moved) - cam.translate_to_frame(point) - assert isclose(diff.length / delta.length, pixel_ratio) + note(f"frame diff: {diff}") + assert isclose(delta.length / diff.length, pixel_ratio, rel_tol=1e-5) diff = cam.translate_to_viewport(point_moved) - cam.translate_to_viewport(point) - assert isclose(delta.length / diff.length, pixel_ratio) + note(f"viewport diff: {diff}") + assert isclose(diff.length / delta.length, pixel_ratio, rel_tol=1e-5) From b280bd6463ab9ee18e57d664f92b745ae624a2d3 Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Fri, 24 May 2019 14:15:56 -0400 Subject: [PATCH 13/15] Camera: Fix test_transfromation_roundtrip --- tests/test_camera.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_camera.py b/tests/test_camera.py index d035aa57..43cad3f6 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -99,7 +99,7 @@ def test_viewport_change_affects_frame_height(): point_x=st.floats(allow_nan=False, allow_infinity=False), point_y=st.floats(allow_nan=False, allow_infinity=False), ) -@example(vp_width=1, vp_height=1, pixel_ratio=1.0, cam_x=0.0, cam_y=0.0, point_x=0.0, point_y=0.0) +@example(vp_width=2, vp_height=2, pixel_ratio=1.0, cam_x=0.0, cam_y=0.0, point_x=0.0, point_y=0.0) def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_x, cam_y, point_x, point_y): cam = Camera( viewport=(0, 0, vp_width, vp_height), @@ -123,7 +123,7 @@ def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_x, cam_y point_viewport = cam.translate_to_viewport(point) note(f"point->viewport: {point_viewport}") - point_frame = cam.translate_to_viewport(point_viewport) + point_frame = cam.translate_to_frame(point_viewport) note(f"point->viewport->frame: {point_frame}") assert point_frame.isclose(point, rel_tol=1e-5) From 80270cc6f5525ad8f3b631dc1484c3b30f1df149 Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Fri, 24 May 2019 14:34:04 -0400 Subject: [PATCH 14/15] Camera: Vectorize the the tests --- tests/test_camera.py | 39 +++++++++++++++------------------------ tests/utils.py | 11 +++++++++++ 2 files changed, 26 insertions(+), 24 deletions(-) create mode 100644 tests/utils.py diff --git a/tests/test_camera.py b/tests/test_camera.py index 43cad3f6..714ce5b6 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -6,6 +6,7 @@ from hypothesis import given, assume, note, example import hypothesis.strategies as st +from .utils import vectors def test_camera_move(): @@ -94,25 +95,23 @@ def test_viewport_change_affects_frame_height(): vp_width=st.integers(min_value=1), vp_height=st.integers(min_value=1), pixel_ratio=st.floats(min_value=1, max_value=1e5, allow_nan=False, allow_infinity=False), - cam_x=st.floats(allow_nan=False, allow_infinity=False), - cam_y=st.floats(allow_nan=False, allow_infinity=False), - point_x=st.floats(allow_nan=False, allow_infinity=False), - point_y=st.floats(allow_nan=False, allow_infinity=False), + cam_pos=vectors(), + point=vectors(), ) -@example(vp_width=2, vp_height=2, pixel_ratio=1.0, cam_x=0.0, cam_y=0.0, point_x=0.0, point_y=0.0) -def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_x, cam_y, point_x, point_y): +@example(vp_width=2, vp_height=2, pixel_ratio=1.0, cam_pos=Vector(0.0, 0.0), point=Vector(0.0, 0.0)) +def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_pos, point): cam = Camera( viewport=(0, 0, vp_width, vp_height), pixel_ratio=pixel_ratio, ) - cam.position = Vector(cam_x, cam_y) - point = Vector(point_x, point_y) + cam.position = cam_pos + + note(f"frame: ({cam.frame_left}, {cam.frame_bottom}) -> ({cam.frame_right}, {cam.frame_top})") # Some underflow/loss of resolution problems assume(cam.frame_left != cam.frame_right) assume(cam.frame_top != cam.frame_bottom) - note(f"frame: ({cam.frame_left}, {cam.frame_bottom}) -> ({cam.frame_right}, {cam.frame_top})") note(f"point: {point}") point_frame = cam.translate_to_frame(point) @@ -132,26 +131,18 @@ def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_x, cam_y vp_width=st.integers(min_value=1), vp_height=st.integers(min_value=1), pixel_ratio=st.floats(min_value=1, max_value=1e5, allow_nan=False, allow_infinity=False), - cam_x=st.floats(allow_nan=False, allow_infinity=False), - cam_y=st.floats(allow_nan=False, allow_infinity=False), - point_x=st.floats(allow_nan=False, allow_infinity=False), - point_y=st.floats(allow_nan=False, allow_infinity=False), - delta_x=st.floats(allow_nan=False, allow_infinity=False), - delta_y=st.floats(allow_nan=False, allow_infinity=False), + cam_pos=vectors(), + point=vectors(), + delta=vectors(), ) def test_transfromation_movement( - vp_width, vp_height, pixel_ratio, cam_x, cam_y, point_x, point_y, delta_x, delta_y, + vp_width, vp_height, pixel_ratio, cam_pos, point, delta, ): cam = Camera( viewport=(0, 0, vp_width, vp_height), pixel_ratio=pixel_ratio, ) - cam.position = Vector(cam_x, cam_y) - point = Vector(point_x, point_y) - delta = Vector(delta_x, delta_y) - - note(f"point: {point}") - note(f"delta: {delta}") + cam.position = cam_pos assume(delta.length != 0) @@ -163,7 +154,7 @@ def test_transfromation_movement( diff = cam.translate_to_frame(point_moved) - cam.translate_to_frame(point) note(f"frame diff: {diff}") - assert isclose(delta.length / diff.length, pixel_ratio, rel_tol=1e-5) + assert isclose(delta.length, pixel_ratio * diff.length, rel_tol=1e-5) diff = cam.translate_to_viewport(point_moved) - cam.translate_to_viewport(point) note(f"viewport diff: {diff}") - assert isclose(diff.length / delta.length, pixel_ratio, rel_tol=1e-5) + assert isclose(diff.length, pixel_ratio * delta.length, rel_tol=1e-5) diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 00000000..bda9bda0 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,11 @@ +import hypothesis.strategies as st + +from ppb import Vector + + +def vectors(max_magnitude=1e75): + return st.builds( + Vector, + st.floats(min_value=-max_magnitude, max_value=max_magnitude), + st.floats(min_value=-max_magnitude, max_value=max_magnitude), + ) From 0af8e5f684c85e570f742d4936b1471a8dcf7285 Mon Sep 17 00:00:00 2001 From: Jamie Bliss Date: Fri, 24 May 2019 15:13:12 -0400 Subject: [PATCH 15/15] Camera: Reduce the magnitude of camera position in testing, to prevent precision problems. --- tests/test_camera.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_camera.py b/tests/test_camera.py index 714ce5b6..17cc60e1 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -95,7 +95,7 @@ def test_viewport_change_affects_frame_height(): vp_width=st.integers(min_value=1), vp_height=st.integers(min_value=1), pixel_ratio=st.floats(min_value=1, max_value=1e5, allow_nan=False, allow_infinity=False), - cam_pos=vectors(), + cam_pos=vectors(1e15), # Set low to prevent loss-of-precision problems about frame size point=vectors(), ) @example(vp_width=2, vp_height=2, pixel_ratio=1.0, cam_pos=Vector(0.0, 0.0), point=Vector(0.0, 0.0)) @@ -108,7 +108,7 @@ def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_pos, poi note(f"frame: ({cam.frame_left}, {cam.frame_bottom}) -> ({cam.frame_right}, {cam.frame_top})") - # Some underflow/loss of resolution problems + # Some underflow/loss of precision problems assume(cam.frame_left != cam.frame_right) assume(cam.frame_top != cam.frame_bottom) @@ -118,13 +118,13 @@ def test_transfromation_roundtrip(vp_width, vp_height, pixel_ratio, cam_pos, poi note(f"point->frame: {point_frame}") point_viewport = cam.translate_to_viewport(point_frame) note(f"point->frame->viewport: {point_viewport}") - assert point_viewport.isclose(point, rel_tol=1e-5) + assert point_viewport.isclose(point, rel_tol=1e-5, rel_to=[cam.position]) point_viewport = cam.translate_to_viewport(point) note(f"point->viewport: {point_viewport}") point_frame = cam.translate_to_frame(point_viewport) note(f"point->viewport->frame: {point_frame}") - assert point_frame.isclose(point, rel_tol=1e-5) + assert point_frame.isclose(point, rel_tol=1e-5, rel_to=[cam.position]) @given(