Behaviour of rotating image between kivy and python
Question: I'm having problem understanding what kivy is doing behind the scenes when
using the kivy language when rotating images and moving them. Below is a code
that's is supposed to draw two images in a 45 degree angle on the screen and
then for every mouse click rotate it more and then move it to the right on the
screen. First image is drawn by using the rotate defined in the kivy language
where the second is where I try to redo it in only python (to understand
better what kivy is actually doing), but I'm failing since the python version
firstly does not move the image to the right when I increase x, but looks like
the whole coordinate system has been rotated for that image since it moves in
45 degree angle up the screen, and secondly it does not rotate that image when
I click. Is anybody that can tell me what I am missing, what would be needed
to do in python (without using the kivy language) to acquire the same
behaviour as the first image is using?

thanks in advance!

Dan

    
    
    from kivy.app import App
    from kivy.lang import Builder
    from kivy.uix.image import Image
    from kivy.graphics import Rotate
    from kivy.uix.widget import Widget
    from kivy.properties import NumericProperty
    from kivy.graphics.context_instructions import PopMatrix, PushMatrix
    
    
    Builder.load_string('''
    <TestKV>:
        canvas.before:
            PushMatrix
            Rotate:
                angle: self.angle
                axis: (0, 0, 1)
                origin: self.center
        canvas.after:
            PopMatrix
    ''')
    
    class TestKV(Image):
        angle = NumericProperty(0)
    
        def __init__(self, x, **kwargs):
            super(TestKV, self).__init__(**kwargs)
            self.x = x
            self.angle = 45
    
        def on_touch_down(self, touch):
            self.angle += 20
            self.x += 10
    
    
    class TestPY(Image):
        angle = NumericProperty(0)
    
        def __init__(self, x, **kwargs):
            super(TestPY, self).__init__(**kwargs)
            self.x = x
            with self.canvas.before:
                PushMatrix()
                rot = Rotate()
                rot.angle = 45
                rot.origin = self.center
                rot.axis = (0, 0, 1)
            with self.canvas.after:
                PopMatrix()
    
        def on_touch_down(self, touch):
            self.angle += 20
            self.x += 10
    
    class MainWidget(Widget):
        #this is the main widget that contains the game.
    
        def __init__(self, **kwargs):
            super(MainWidget, self).__init__(**kwargs)
            self.all_sprites = []
    
            self.k = TestKV(source="myTestImage.bmp", x=10)
            self.add_widget(self.k)
    
            self.p = TestPY(source="myTestImage.bmp", x=200)
            self.add_widget(self.p)
    
    
    class TheApp(App):
    
        def build(self):
            parent = Widget()
            app = MainWidget()
            parent.add_widget(app)
    
            return parent
    
    if __name__ == '__main__':
        TheApp().run()
    


Answer: You never change the angle of the `Rotate` instruction. You have an `angle`
property on your widget, but that isn't linked to anything. Try updating the
`Rotate` instruction instead:

    
    
    class TestPY(Image):
        def __init__(self, **kwargs):
            super(TestPY, self).__init__(**kwargs)
            # self.x = x -- not necessary, x is a property and will be handled by super()
            with self.canvas.before:
                PushMatrix()
                self.rot = Rotate()
                self.rot.angle = 45
                self.rot.origin = self.center
                self.rot.axis = (0, 0, 1)
            with self.canvas.after:
                PopMatrix()
    
        def on_touch_down(self, touch):
            self.x += 10
            self.rot.origin = self.center  # center has changed; update here or bind instead
            self.rot.angle += 20
    

