Seite 1 von 3
Kivy Rotation resize ändert position
Verfasst: Montag 15. März 2021, 09:28
von MupfSpace
Hallo,
ich habe ein rotiertes Rechteck, bei dem die Größe geändert wird.
Dadurch verändert sich aber auch die Position ein bisschen, das möchte ich aber nicht.
So ist es im moment:
https://youtu.be/ofGYKKFGv7Q
und so soll es sein:
https://youtu.be/ThvYjvCHamo (Ich habe da das center neu setzen deaktiviert, aber das soll natürlich neu gesetzt werden)
Ich glaube das liegt daran, das ich das center falsch setze, aber ich wüsste nicht, wie es richtig ist.
Das ist mein Code:
Code: Alles auswählen
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Rectangle, PushMatrix, Rotate, PopMatrix
from kivy.clock import Clock
class Canvas:
def __init__(self, root, pos, size, rotation=0, color=(1, 0, 0, 1)):
self._pos = pos
self._size = size
self._rotation = rotation
self._color = color
with root.canvas:
PushMatrix()
self._color_instruction = Color(rgba=self.color)
self._rotation_instruction = Rotate(angle=self.rotation, origin=self.center())
self._rectangle_instruction = Rectangle(pos=self.pos, size=self.size)
PopMatrix()
Clock.schedule_interval(self.step, 0)
def step(self, dt):
self.size= (self.size[0] + 5, self.size[1])
def center(self):
center_x = self.pos[0] + self.size[0]/2
center_y= self.pos[1] + self.size[1]/2
return (center_x, center_y)
@property
def pos(self):
return self._pos
@pos.setter
def pos(self, value):
self._pos = value
self._rectangle_instruction.pos = self._pos
@property
def size(self):
return self._size
@size.setter
def size(self, value):
self._size = value
self._rectangle_instruction.size = self._size
self._rotation_instruction.origin = self.center()
@property
def rotation(self):
return self._rotation
@rotation.setter
def rotation(self, value):
self._rotation = value
self._rotation_instruction.angle= self._rotation
self._rotation_instruction.origin = self.center()
@property
def color(self):
return self._color
@color.setter
def color(self, value):
self._color = value
self._color_instruction.rgba = self._color
class Root(Widget):
def __init__(self, **kwargs):
super(Root, self).__init__(**kwargs)
self.rectangle = Canvas(self, (100, 100), (100, 100), rotation=45)
class TestApp(App):
def __init__(self, **kwargs):
super(TestApp, self).__init__(**kwargs)
def build(self):
return Root()
def main():
app = TestApp()
app.run()
if __name__ == "__main__":
main()
Re: Kivy Rotation resize ändert position
Verfasst: Montag 15. März 2021, 09:58
von Sirius3
Warum speicherst Du die ganzen Informationen redundant? Das sollte man vermeiden.
Und wenn Du nicht willst, dass sich das Zentrum ändert, dann mußt Du beim Ändern der Größe auch die Position anpassen.
Code: Alles auswählen
class Canvas:
def __init__(self, root, pos, size, rotation=0, color=(1, 0, 0, 1)):
with root.canvas:
PushMatrix()
self._color_instruction = Color(rgba=color)
self._rectangle_instruction = Rectangle(pos=pos, size=size)
self._rotation_instruction = Rotate(angle=rotation, origin=self.center)
PopMatrix()
Clock.schedule_interval(self.step, 0)
def step(self, dt):
self.size = (self.size[0] + 5, self.size[1])
@property
def center(self):
pos = self.pos
size = self.size
center_x = pos[0] + size[0] / 2
center_y = pos[1] + size[1] / 2
return (center_x, center_y)
@property
def pos(self):
return self._rectangle_instruction.pos
@pos.setter
def pos(self, value):
self._rectangle_instruction.pos = value
@property
def size(self):
return self._rectangle_instruction.size
@size.setter
def size(self, new_size):
old_pos = self._rectangle_instruction.pos
old_size = self._rectangle_instruction.size
new_pos = (old_pos[0] + (old_size[0] - new_size[0]) / 2,
old_pos[1] + (old_size[1] - new_size[1]) / 2)
self._rectangle_instruction.pos = new_pos
self._rectangle_instruction.size = new_size
@property
def rotation(self):
return self._rotation_instruction.angle
@rotation.setter
def rotation(self, value):
self._rotation_instruction.angle = rotation
@property
def color(self):
return self._color_instruction.rgba
@color.setter
def color(self, value):
self._color_instruction.rgba = value
Re: Kivy Rotation resize ändert position
Verfasst: Montag 15. März 2021, 10:38
von MupfSpace
- Warum soll man es vermeiden die Informationen redundant zu speichern?
- Ich möchte schon das sich das Zentrum ändert, es soll sich einfach nur nicht verschieben.
wie würde das funktionieren?
Re: Kivy Rotation resize ändert position
Verfasst: Montag 15. März 2021, 10:45
von Sirius3
- Weil bei redundanten Informationen Du jeweils synchron an mehreren Stellen ändern mußt. Das ist sehr aufwändig, wie Du ja an Deinem Beispiel siehst. Und wenn man da einen Fehler macht, ist die Fehlersuche sehr schwierig.
- Diese beiden Aussagen widersprechen sich: das Zentrum soll sich ändern aber sich doch nicht ändern.
Re: Kivy Rotation resize ändert position
Verfasst: Montag 15. März 2021, 10:59
von MupfSpace
Also...
Ich möchte dass das Zentrum der Rotation dem Zentrum des Rechtecks entspricht, aber sich das Rechteck nicht bewegt.
So wie wenn ich das Rechteck zeichnen würde und dann weiter zeichne um es größer zu machen.
Da ändert sich die Position ja auch nicht (Natürlich änderst sie sich nicht und wahrscheinlich ist das auch ein blödes Beispiel mir fällt aber gerade kein besseres ein

)
Re: Kivy Rotation resize ändert position
Verfasst: Montag 15. März 2021, 11:24
von Sirius3
Also...
wie weicht jetzt meine Lösung von Deinen Wünschen ab?
Re: Kivy Rotation resize ändert position
Verfasst: Montag 15. März 2021, 12:19
von MupfSpace
Vielleicht ist das gerade auch mein Fehler, ich schaue mir das später an.
hab gerade keine Zeit.
(Nur damit du nicht denkst das ich nicht mehr antworte

)
Re: Kivy Rotation resize ändert position
Verfasst: Dienstag 16. März 2021, 08:10
von MupfSpace
Also irgendetwas ist da ganz ganz komisch und es passieren Dinge, die ich nicht verstehe.
- bei der center property kommt immer 150, 150 als ergebnis. ich weiß nicht woran das liegt. wenn ich mir self.pos und self.size ausgeben lasse, passt noch alles.
wenn ich ich self.pos[0] + self.size[0] mache passt auch noch alles. sobald ich aber /2 hinzufüge kommt immer 150, 150. und das verstehe ich nicht so wirklich.
- ich wollte noch was mit center der rotation setzen ausprobieren (das ist das, was was bei deiner Lösung noch fehlt

)
allerdings kann ich das nicht, weil ja das mit dem center nicht funktioniert.
Re: Kivy Rotation resize ändert position
Verfasst: Dienstag 16. März 2021, 08:28
von Sirius3
Natürlich funktioniert das mit `center`. Wenn size setzt, ändert sich center nicht, das ist genau das Verhalten, das Du (soweit ich das verstanden habe) willst.
Wenn Du zusätzlich noch rotation.origin ändern willst, dann mußt Du halt dafür auch noch eine Funktion schreiben.
Re: Kivy Rotation resize ändert position
Verfasst: Mittwoch 17. März 2021, 00:01
von MupfSpace
Ja, Funktioniert

Das es nicht Funktioniert hat, war mein Fehler...
Noch eine Frage:
Wie würde new_pos aussehen, wenn sich die Größe nur in eine Richtung verändern soll?
Momentan verändert sich das ja in beide Richtungen...
Das mit den 2 Richtugen ist aber perfekt so

Würde das mit der einen Richtung nur gerne wissen, damit ich mal weiß wie es geht...
Re: Kivy Rotation resize ändert position
Verfasst: Mittwoch 17. März 2021, 08:06
von Sirius3
Einfach 0, 0.5 oder 1 mal size abziehen.
Re: Kivy Rotation resize ändert position
Verfasst: Donnerstag 18. März 2021, 19:54
von MupfSpace
Also das mit dem 0,5 funktioniert wie gesagt perfekt aber das *1 und *0 nicht :/
da bewegt es sich so wie oben erwähnt und und in dem Video oben gezeigt.
(weil wenn ich das *0 mache ist ja zu meinem Code am Anfang abgesehen davon das ich nichts mehr redundant speichere kein unterschied...)
Re: Kivy Rotation resize ändert position
Verfasst: Donnerstag 18. März 2021, 20:02
von Sirius3
Ja, was willst Du denn nun?
Wie soll sich denn das Rechteck bewegen. Mal sagst Du, Du möchtest, dass der linke Rand fix bleibt, dann wieder nicht?
Re: Kivy Rotation resize ändert position
Verfasst: Donnerstag 18. März 2021, 22:22
von MupfSpace
also der linke Rand soll fix bleiben.
also *0, damit ist new_pos = old_pos und ich kann mir das komplett sparen...
wenn ich das mit *0,5 mache, also so, dass sich die Größe in beide Richtungen verändert funktioniert alles.
mache ich es aber so, dass der linke Rand fix bleibt, dann passiert das:
https://youtu.be/ofGYKKFGv7Q, es verschiebt sich...
Re: Kivy Rotation resize ändert position
Verfasst: Freitag 19. März 2021, 08:16
von MupfSpace
Das ist das was passiert:
https://youtu.be/Q4DkcBuptyM
und das hier ist mein Aktueller code:
Code: Alles auswählen
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Rectangle, PushMatrix, Rotate, PopMatrix
from kivy.clock import Clock
from kivy.core.window import Window
class Canvas:
def __init__(self, root, pos, size, rotation=0, color=(1, 0, 0, 1)):
with root.canvas:
PushMatrix()
self._color_instruction = Color(rgba=color)
self._rotation_instruction = Rotate(angle=rotation, origin=(150, 150))
self._rectangle_instruction = Rectangle(pos=pos, size=size)
PopMatrix()
def step(self, dt):
self.size = (self.size[0] + 5, self.size[1])
@property
def center(self):
pos = self.pos
size = self.size
center_x = pos[0] + size[0] / 2
center_y = pos[1] + size[1] / 2
return (center_x, center_y)
@property
def pos(self):
return self._rectangle_instruction.pos
@pos.setter
def pos(self, value):
self._rectangle_instruction.pos = value
self._rotation_instruction.origin = self.center
@property
def size(self):
return self._rectangle_instruction.size
@size.setter
def size(self, value):
self._rectangle_instruction.size = value
self._rotation_instruction.origin = self.center
@property
def rotation(self):
return self._rotation_instruction.angle
@rotation.setter
def rotation(self, value):
self._rotation_instruction.angle = value
@property
def color(self):
return self._color_instruction.rgba
@color.setter
def color(self, value):
self._color_instruction.rgba = value
class Root(Widget):
def __init__(self, **kwargs):
super(Root, self).__init__(**kwargs)
self.rectangle = Canvas(self, (100, 100), (100, 100), rotation=45)
self.keys_pressed = set()
self._keyboard = Window.request_keyboard(self._on_keyboard_closed, self)
self._keyboard.bind(on_key_down = self._on_key_down)
self._keyboard.bind(on_key_up = self._on_key_up)
self.focused = self.rectangle
Clock.schedule_interval(self.step, 0)
def step(self, dt):
x = self.focused.pos[0]
y = self.focused.pos[1]
width = self.focused.size[0]
height = self.focused.size[1]
rotation = self.focused.rotation
step_size = 300 * dt
if "up" in self.keys_pressed:
y += step_size
if "left" in self.keys_pressed:
x -= step_size
if "right" in self.keys_pressed:
x += step_size
if "down" in self.keys_pressed:
y -= step_size
if "y" in self.keys_pressed:
rotation += step_size
if "x" in self.keys_pressed:
rotation -= step_size
if "w" in self.keys_pressed:
height = min(height + step_size, 300)
if "a" in self.keys_pressed:
width = max(width - step_size, 10)
if "d" in self.keys_pressed:
width = min(width + step_size, 300)
if "s" in self.keys_pressed:
height = max(height - step_size, 10)
self.focused.pos = (x, y)
self.focused.size = (width, height)
self.focused.rotation = rotation
def _on_keyboard_closed(self):
self._keyboard.unbind(_on_key_down = self._on_key_down)
self._keyboard.ubind(_on_key_up = self._on_key_up)
self._keyboard = None
def _on_key_down(self, keyboard, keycode, text, modifiers):
self.keys_pressed.add(text if text != None else keycode[1])
def _on_key_up(self, keyboard, keycode):
if keycode[1] in self.keys_pressed:
self.keys_pressed.remove(keycode[1])
class TestApp(App):
def __init__(self, **kwargs):
super(TestApp, self).__init__(**kwargs)
def build(self):
return Root()
def main():
app = TestApp()
app.run()
if __name__ == "__main__":
main()
Re: Kivy Rotation resize ändert position
Verfasst: Freitag 19. März 2021, 08:27
von Sirius3
Und wo ist jetzt die Frage? Du schreibst immer noch nicht, was Du eigentlich ganz genau haben möchtest.
Re: Kivy Rotation resize ändert position
Verfasst: Freitag 19. März 2021, 09:01
von MupfSpace
Das soll sich nicht bewegen...
es soll einfach nur die Größe andern, sich aber nicht so verschieben.
mit
Code: Alles auswählen
new_pos = (old_pos[0] + (old_size[0] - new_size[0]) / 2, old_pos[1] + (old_size[1] - new_size[1]) / 2)
funktioniert es ja auch ohne, dass es sich verschiebt
Re: Kivy Rotation resize ändert position
Verfasst: Freitag 19. März 2021, 09:39
von Sirius3
Du hast 4 Größen: Position, Größe, Drehzentrum und Drehwinkel. Und wenn Du eine dieser Größen änderst, dann ändert sich das Rechteck. Wenn Du ein anderes Verhalten möchtest, mußt Du gleichzeitig eine der anderen Größen mit anpassen.
Was Du genau willst, hast Du immer noch nicht gesagt, von daher mußt Du Dir selbst die Gedanken machen.
Re: Kivy Rotation resize ändert position
Verfasst: Freitag 19. März 2021, 09:57
von MupfSpace
Ich habe eigentlich schon gesagt, wie ich das haben will aber wahrscheinlich habe ich das unverständlich gesagt...
sorry
es soll so sein wie hier:
https://youtu.be/PXUoib5Yl8w (in diesem Video habe ich das center setzen deaktiviert)
Allerdings soll das center gesetzt werden.
Meine Frage: wie mache ich das
Code: >siehe vorherige beiträge<
Re: Kivy Rotation resize ändert position
Verfasst: Freitag 19. März 2021, 10:31
von Sirius3
Du willst also, dass die untere Ecke sich nicht bewegt. Dann mußt Du die Position der untere Ecke des Rechtecks relativ zum umschreibenden Rechteck berechnen.
Dafür brauchst Du, wie schon im letzten Beitrag geschrieben, die Position, Größe und Winkel, und etwas Mathematik, also Sinus und Cosinus.