Skip to content

Commit 59a2912

Browse files
authored
Merge pull request #80 from kushalkolar/auto-scale-camera
added camera auto-scaling, examples work :D
2 parents e27d8f4 + dfdbe72 commit 59a2912

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

fastplotlib/layouts/_base.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import numpy as np
12
from pygfx import Scene, OrthographicCamera, PerspectiveCamera, PanZoomController, OrbitController, \
23
Viewport, WgpuRenderer
34
from wgpu.gui.auto import WgpuCanvas
@@ -37,6 +38,13 @@ def __init__(
3738
self.camera
3839
)
3940

41+
# camera.far and camera.near clipping planes get
42+
# wonky with setting controller.distance = 0
43+
if isinstance(self.camera, OrthographicCamera):
44+
self.controller.distance = 0
45+
# also set a initial zoom
46+
self.controller.zoom(0.8 / self.controller.zoom_value)
47+
4048
self.renderer.add_event_handler(self.set_viewport_rect, "resize")
4149

4250
self._graphics: List[Graphic] = list()
@@ -135,6 +143,15 @@ def center_graphic(self, graphic, zoom: float = 1.3):
135143
self.controller.zoom(zoom)
136144

137145
def center_scene(self, zoom: float = 1.3):
146+
"""
147+
Auto-center the scene, does not scale.
148+
149+
Parameters
150+
----------
151+
zoom: float, default 1.3
152+
apply a zoom after centering the scene
153+
154+
"""
138155
if not len(self.scene.children) > 0:
139156
return
140157

@@ -148,6 +165,32 @@ def center_scene(self, zoom: float = 1.3):
148165

149166
self.controller.zoom(zoom)
150167

168+
def auto_scale(self, maintain_aspect: bool = False, zoom: float = 0.8):
169+
"""
170+
Auto-scale the camera w.r.t to the scene
171+
172+
Parameters
173+
----------
174+
maintain_aspect: bool, default ``False``
175+
maintain the camera aspect ratio for all dimensions, if ``False`` the camera
176+
is scaled according to the bounds in each dimension.
177+
178+
zoom: float, default 0.8
179+
zoom value for the camera after auto-scaling, if zoom = 1.0 then the graphics
180+
in the scene will fill the entire canvas.
181+
"""
182+
self.center_scene()
183+
self.camera.maintain_aspect = maintain_aspect
184+
185+
width, height, depth = np.ptp(self.scene.get_world_bounding_box(), axis=0)
186+
187+
self.camera.width = width
188+
self.camera.height = height
189+
190+
# self.controller.distance = 0
191+
192+
self.controller.zoom(zoom / self.controller.zoom_value)
193+
151194
def get_graphics(self):
152195
return self._graphics
153196

fastplotlib/layouts/_gridplot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def show(self):
175175
self.canvas.request_draw(self.render)
176176

177177
for subplot in self:
178-
subplot.center_scene()
178+
subplot.auto_scale(maintain_aspect=True, zoom=0.95)
179179

180180
return self.canvas
181181

fastplotlib/layouts/_subplot.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,12 @@ def __init__(
8888
self.set_title(self.name)
8989

9090
def _create_graphic(self, graphic_class, *args, **kwargs):
91+
if "center" in kwargs.keys():
92+
center = kwargs.pop("center")
93+
else:
94+
center = False
9195
graphic = graphic_class(*args, **kwargs)
92-
self.add_graphic(graphic, center=False)
96+
self.add_graphic(graphic, center=center)
9397

9498
return graphic
9599

fastplotlib/plot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,6 @@ def render(self):
9191

9292
def show(self):
9393
self.canvas.request_draw(self.render)
94-
self.center_scene()
94+
self.auto_scale(maintain_aspect=True, zoom=0.95)
9595

9696
return self.canvas

0 commit comments

Comments
 (0)