|
5 | 5 | from dataclasses import dataclass |
6 | 6 |
|
7 | 7 | import numpy as np |
| 8 | +import pylinalg as la |
8 | 9 |
|
9 | 10 | from pygfx import WorldObject |
10 | 11 |
|
@@ -142,6 +143,14 @@ def position_y(self, val): |
142 | 143 | def position_z(self, val): |
143 | 144 | self.world_object.world.z = val |
144 | 145 |
|
| 146 | + @property |
| 147 | + def rotation(self): |
| 148 | + return self.world_object.local.rotation |
| 149 | + |
| 150 | + @rotation.setter |
| 151 | + def rotation(self, val): |
| 152 | + self.world_object.local.rotation = val |
| 153 | + |
145 | 154 | @property |
146 | 155 | def visible(self) -> bool: |
147 | 156 | """Access or change the visibility.""" |
@@ -196,6 +205,28 @@ def __del__(self): |
196 | 205 | self.deleted = True |
197 | 206 | del WORLD_OBJECTS[self.loc] |
198 | 207 |
|
| 208 | + def rotate(self, alpha: float, axis: Literal["x", "y", "z"] = "y"): |
| 209 | + """Rotate the Graphic with respect to the world. |
| 210 | +
|
| 211 | + Parameters |
| 212 | + ---------- |
| 213 | + alpha : |
| 214 | + Rotation angle in radians. |
| 215 | + axis : |
| 216 | + Rotation axis label. |
| 217 | + """ |
| 218 | + if axis == "x": |
| 219 | + rot = la.quat_from_euler((alpha, 0), order="XY") |
| 220 | + elif axis == "y": |
| 221 | + rot = la.quat_from_euler((0, alpha), order="XY") |
| 222 | + elif axis == "z": |
| 223 | + rot = la.quat_from_euler((0, alpha), order="XZ") |
| 224 | + else: |
| 225 | + raise ValueError( |
| 226 | + f"`axis` must be either `x`, `y`, or `z`. `{axis}` provided instead!" |
| 227 | + ) |
| 228 | + self.rotation = la.quat_mul(rot, self.rotation) |
| 229 | + |
199 | 230 |
|
200 | 231 | class Interaction(ABC): |
201 | 232 | """Mixin class that makes graphics interactive""" |
|
0 commit comments