Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Understanding ui.Transform.rotation
-
Sorry, I am sure this is just such a stupid question. But I don't get how ui.Transform.rotate works. I put an example below. Naively, I thought that the rotation would just pivot around the center point of the rect. But it clearly does not.
Any help appreciatedimport ui class MyClass(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def draw(self): s = ui.Path.rect(100, 100, 200, 200) with ui.GState(): ui.set_color('deeppink') s.fill() with ui.GState(): ui.concat_ctm(ui.Transform.rotation(.45)) ui.set_color('red') s.fill() if __name__ == '__main__': w = 600 h = 800 f = (0, 0, w, h) mc = MyClass(frame = f, bg_color = 'white') mc.present('sheet')
-
Should have attached a pic before 😱
But you can see the rotation is not Center based. -
Rotation is around the origin (0, 0) by default. To rotate your drawing around an arbitrary point, you have to combine the rotation with a translation, like this:
import ui class MyClass(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def draw(self): s = ui.Path.rect(100, 100, 200, 200) with ui.GState(): ui.set_color('deeppink') s.fill() with ui.GState(): # Move the origin (0, 0) to the center of the rectangle: ui.concat_ctm(ui.Transform.translation(200, 200)) # Rotate the coordinate system: ui.concat_ctm(ui.Transform.rotation(.45)) # Move the origin back, so that the rectangle's coordinates are valid: ui.concat_ctm(ui.Transform.translation(-200, -200)) ui.set_color('red') s.fill() if __name__ == '__main__': w = 600 h = 800 f = (0, 0, w, h) mc = MyClass(frame = f, bg_color = 'white') mc.present('sheet')
-
@omz, thanks a lot.
I did the below, I could not apply a unary operator - to the unpacking. Not sure it's possible or not. Would have been nicer 😱import ui class MyClass(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def draw(self): rect = ui.Rect(100, 100, 300, 400) s = ui.Path.rect(*rect) with ui.GState(): ui.set_color('deeppink') s.fill() with ui.GState(): # Move the origin (0, 0) to the center of the rectangle: ui.concat_ctm(ui.Transform.translation(*rect.center())) #ui.concat_ctm(ui.Transform.translation(200, 200)) # Rotate the coordinate system: ui.concat_ctm(ui.Transform.rotation(.45)) # Move the origin back, so that the rectangle's coordinates are valid: #ui.concat_ctm(ui.Transform.translation(*rect.center())) ui.concat_ctm(ui.Transform.translation(-rect.center()[0], -rect.center()[1])) ui.set_color('red') s.fill() if __name__ == '__main__': w = 600 h = 800 f = (0, 0, w, h) mc = MyClass(frame = f, bg_color = 'white') mc.present('sheet')
-
@Phuket2 While you cannot use the unary minus operator with points or tuples, this should work, and is a bit more concise:
ui.Transform.translation(*(rect.center() * -1))
-
@omz, thanks. Simple, but you have to understand better than I do how the values are unpacked. In a few more years it will come to me, hopefully 😱