Seite 1 von 2

Kreis in Pygame unterteilen

Verfasst: Samstag 19. Juni 2021, 12:52
von k-net
Hallo,

ich habe in Pygame mit

Code: Alles auswählen

pygame.draw.circle(screen, white, (250, 250), 250, 1)
einen Kreis gezeichnet.
Ich möchte nun Linien durch diesen Kreis zeichnen. Und zwar acht Linien, die den Kreis in 16 gleichgroße Teile teilen.
Einige Linien, wie diese hier

Code: Alles auswählen

pygame.draw.aaline(screen, yellow, [0, 0], [500, 500])
(Das Fenster ist 500x500 groß) sind ja denkbar einfach. Aber ich kann mich natürlich nicht auf Dauer an den Abmessungen des Fensters orientieren, denn dann werden die Teile nicht gleich groß.

Kann mir jemand einen Tipp geben, wie ich das hinbekomme? Ich stelle mir vor, dass er die Werte für die Koordinaten der Linien aus einer Winkelangabe nimmt. Oder gibt es andere Wege diese zu berechnen. Ich habe schon gesucht und mit dem math modul und pi rumexperimentiert, komme aber nicht weiter.

Wäre toll, wenn jemand da eine Idee hätte.

Danke!

Re: Kreis in Pygame unterteilen

Verfasst: Samstag 19. Juni 2021, 13:27
von __deets__
Der Startpunkt ist immer das Zentrum. Und die x und y Koordinate ist cos(Winkel) * Radius und sin(Winkel) * Radius. Und der Winkel ist i * PI * 2 / 8, wobei i von 0 - 7 läuft.

Re: Kreis in Pygame unterteilen

Verfasst: Sonntag 20. Juni 2021, 19:09
von k-net
Danke, das hat schonmal sehr geholfen.

Ich führe das in folgender Funktion aus:

Code: Alles auswählen

def lines():
    zahlenliste = range(0, 7)
    r = 250
    circle = pygame.draw.circle(screen, white, (250, 250), r, 1)
    for i in zahlenliste:
        w = i * math.pi * 2 / 4
        line_01 = pygame.draw.aaline(screen, yellow, [250, 250], [math.cos(w)*r, math.sin(w)*r])

Es ist aber nur ein Viertel des Kreises mit Linien befüllt. Wenn ich die Formel zu "w" wie von dir beschrieben übernehme, sind es zu viele Linien in dem Viertel, daher habe ich aus der 8 eine 4 gemacht. Aber irgendwas scheine ich zudem noch falsch zu machen... :?

Re: Kreis in Pygame unterteilen

Verfasst: Sonntag 20. Juni 2021, 19:23
von Sirius3
Du läßt nur sieben statt acht Linien zeichnen. Und die Endpositionen sind liegen auf einem Kreis der um 0/0 zentriert ist, und nicht um 250/250. Mit den Rückgabewerten von aaline und circle machst Du nichts.

Re: Kreis in Pygame unterteilen

Verfasst: Sonntag 20. Juni 2021, 19:41
von __deets__
Also meine Formel war schon korrekt. Wenn da was bei dir nicht gepasst hat, war es etwas anderes.

Code: Alles auswählen

>>> import math as m
>>> [i * m.pi * 2 / 8 for i in range(8)]
[0.0, 0.7853981633974483, 1.5707963267948966, 2.356194490192345, 3.141592653589793, 3.9269908169872414, 4.71238898038469, 5.497787143782138]
>>> rads = [i * m.pi * 2 / 8for i in range(8)]
>>> [m.degrees(r) for r in rads]
[0.0, 45.0, 90.0, 135.0, 180.0, 225.0, 270.0, 315.0]
Du musst aber auch den Startpunkt auf die errechnete Kreiskoordinate addieren. Denn das geht ja nur um den Nullpunkt.

Re: Kreis in Pygame unterteilen

Verfasst: Montag 21. Juni 2021, 16:57
von k-net
Tut mir leid, was du da gemacht hast, verstehe ich nicht :|

Re: Kreis in Pygame unterteilen

Verfasst: Montag 21. Juni 2021, 17:56
von __deets__
Es zeigt einfach nur, das meine Formel korrekt war. Wenn du es nicht verstehst ist das nicht schlimm, dann musst du es eben glauben. Wobei das ja nur zwei for schleifen sind. Was daran ist so ungewöhnlich?

Wenn dein Ding also nicht richtig dargestellt wird, liegt es an etwas andrem.

Re: Kreis in Pygame unterteilen

Verfasst: Montag 21. Juni 2021, 18:10
von k-net
Ich glaube dir das ganz sicher dass die Formel richtig ist, mein mathematisches Verständnis hinkt aber noch hinterher.
Nach diversen Tutorials über Kreisgleichungen und Umrechnung von Bogenmaß zu Winkelangaben etc... bin ich nur ein bisschen schlauer... nur ein bisschen.

Was genau meinst du mit
Denn das geht ja nur um den Nullpunkt.
?

Re: Kreis in Pygame unterteilen

Verfasst: Montag 21. Juni 2021, 18:37
von __deets__
Die Formel berechnet die Koordinaten um den Nullpunkt. Du malst deinen Kreis aber irgendwo. Also musst du den errechneten Punkt auf den Kreismittelpunkt addieren. Mal dir die Sache mal auf Kästchenpapier auf. Dann kommt das Verständnis einfacher.

Re: Kreis in Pygame unterteilen

Verfasst: Montag 21. Juni 2021, 21:42
von k-net
Ah, okay... geschnallt.

aktuell sieht es so aus:

Code: Alles auswählen

line_01 = pygame.draw.aaline(screen, yellow, [250, 250], [math.cos(math.radians(0)) * r + 250, math.sin(math.radians(0)) * r + 250])
line_02 = pygame.draw.aaline(screen, yellow, [250, 250], [math.cos(math.radians(22.5)) * r + 250, math.sin(math.radians(22.5)) * r + 250])
usw... für jede Linie einzeln eben.

Es funktioniert. Ich werde das aber noch ändern. Ich musste mir das erstmal so herleiten, damit ich verstehe, was passiert und wie es funktioniert. Aus den einzelnen Linien mache ich aber noch eine Schleife und werde deine Formel wieder einbringen. Aber schonmal vielen Dank für die Hilfe!

Re: Kreis in Pygame unterteilen

Verfasst: Montag 21. Juni 2021, 22:22
von __deets__
Du musst wie Sirius3 schon sagte die Ergebnisse von aaline nicht an einen Namen binden. Und du solltest auch den Kreismittelpunkt nicht fest verdrahten. Sondern mit Variablen gestalten.

Re: Kreis in Pygame unterteilen

Verfasst: Montag 21. Juni 2021, 22:42
von rogerb
@k-net,

kleiner Tipp, bzw. Herausforderung: Wenn du die Linien durch den Mittelpunkt kreuzen lässt, brauchst du sie nur vier mal zu zeichnen.

Code: Alles auswählen

# Nur ein Ausschnitt, kein fertiges Programm, angle, radius, center_x, center_y müssen natürlich vorher definiert sein
x_distance = math.cos(math.radians(angle)) * radius
y_distance = math.sin(math.radians(angle)) * radius
pygame.draw.aaline(screen, yellow, [center_x - x_distance, center_y - y_distance], [center_x + x_distance, center_y + y_distance])

Re: Kreis in Pygame unterteilen

Verfasst: Donnerstag 24. Juni 2021, 17:19
von k-net
Hallo,

ich habe erneut ein kleines Rechenproblem.

Auf meinem Rad habe ich nun mehrere Kugeln, die sich die Speichen hin und her entlang bewegen.

Bild

Kugel 1 (links unten):

Code: Alles auswählen

    def draw_ball_01(self):
        ball_01 = pygame.draw.circle(screen, self.color, (self.ball_01_x, self.ball_01_y), self.radius, self.width)
        self.ball_01_x += self.speed
        if self.ball_01_x <= math.cos(math.radians(180)) * self.r + self.r:
            self.speed = 3
        elif self.ball_01_x >= math.cos(math.radians(0)) * self.r + self.r:
            self.speed = -3
Kugel 2 (darüber)

Code: Alles auswählen

    def draw_ball_02(self):
        ball_02 = pygame.draw.circle(screen, self.color, (self.ball_02_x, self.ball_02_y), self.radius, self.width)
        self.ball_02_x += self.speed 
        self.ball_02_y += self.speed
        if self.ball_02_x <= math.cos(math.radians(202.5)) * self.r + self.r:
            self.speed = 3
        elif self.ball_02_y >= math.sin(math.radians(22.5)) * self.r + self.r:
            self.speed = -3
Kugel 3 (über 2)

Code: Alles auswählen

    def draw_ball_03(self):
        ball_03 = pygame.draw.circle(screen, self.color, (self.ball_03_x, self.ball_03_y), self.radius, self.width)
        self.ball_03_x += self.speed / 1.414
        self.ball_03_y += self.speed / 1.414
        if self.ball_03_y <= math.sin(math.radians(225)) * self.r + self.r:
            self.speed = 3
        elif self.ball_03_x >= math.cos(math.radians(45)) * self.r + self.r:
            self.speed = -3
usw...

Das hin und her bewegen zwischen den Punkten und auf der Linie klappt gut. Kugel 1 und 3 und natürlich 5 laufen synchron und passieren gleichzeitig den Mittelpunkt. bei Kugel drei habe ich mich an dem Verhältnis einer Diagonalen zu den Seitenlängen eines Quadrates orientiert.

Aber Teufel auch für Kugel 2 und 4 bekomme ich das nicht hin :x
Kann mir bitte jemand da weiterhelfen?

Danke!

Re: Kreis in Pygame unterteilen

Verfasst: Donnerstag 24. Juni 2021, 17:48
von __deets__
Mir ist unklar was diese Kugeln tun sollen. Kannst du das mal beschreiben?

Was aber klar ist: du musst dringend Klassen, Argumente und Variablen benutzen. Statt mehrfach den nahezu gleichen Code zu kopieren. Das ist fehlerträchtig und kompliziert.

Re: Kreis in Pygame unterteilen

Verfasst: Donnerstag 24. Juni 2021, 18:03
von Sirius3
Statt für jeden Ball eine eigene Funktion zu schreiben, benutzt man eine passende Datenstruktur.
Wenn alle Bälle immer den gleichen Abstand zum Mittelpunkt haben sollen, ist das noch einfacher:

Code: Alles auswählen

    def draw_balls(self):
        for i in range(8):
            angle = i * math.pi / 4
            x = math.cos(angle) * self.ball_position + self.r
            y = math.sin(angle) * self.ball_position + self.r
            pygame.draw.circle(screen, self.color, (x, y), self.radius, self.width)
        self.ball_position -= 1

Re: Kreis in Pygame unterteilen

Verfasst: Donnerstag 24. Juni 2021, 20:17
von k-net
__deets__ hat geschrieben: Donnerstag 24. Juni 2021, 17:48 Mir ist unklar was diese Kugeln tun sollen. Kannst du das mal beschreiben?
Letztendlich möchte ich diesen optischen Effekt nachbilden:
https://www.youtube.com/watch?v=pNe6fsaCVtI

Jede Kugel bewegt sich eigentlich nur auf ihrer Linie hin und her, aber mit den passenden Abständen entsteht der Effekt, dass sie sich umeinander drehen würden. So wie ich das bisher habe, sieht das auch schon ganz nett aus. Es fehlt noch, dass die Kugeln zum Ende hin ihre Geschwindigkeit verlangsamen und eben die richtige Geschwindigkeit für die Kugeln die ich benannt habe.
Was aber klar ist: du musst dringend Klassen, Argumente und Variablen benutzen. Statt mehrfach den nahezu gleichen Code zu kopieren. Das ist fehlerträchtig und kompliziert.
Das ist mir absolut klar! Ich schreibe den Code aktuell so, weil ich es nicht besser kann. Ich mache das nur, um Python autodidaktisch zu lernen (aus Spaß übrigens, in meinem Alltag oder Beruf hab ich davon nix) und dafür gehe ich langsam vor (auch weil ich nicht so wahnsinnig viel Freizeit habe). Bei dem Code so wie er jetzt ist, weiß ich in jeder Zeile, was passiert. Das ist mir wichtig. Ich möchte auch keine fertigen Lösungen haben (naja, manchmal vielleicht schon) sondern mir das selber erarbeiten, eben um das zu kapieren. Ich möchte aber natürlich eure Unterstützungsbereitschaft auch nicht überstrapazieren. Aber wenn ich eine Formel genannt bekomme, die ich nicht verstehe, habe ich nichts davon und kann die nicht auf spätere Projekte anwenden. Beim Autofahren fängt man ja auch nicht auf der Rennstrecke an, sondern übt erstmal. Daher mache ich das so scheibchenweise in der Hoffnung, niemanden zu nerven :)

Im weiteren Verlauf würde ich natürlich versuchen, den häufig gleich oder ähnlich verwendeten Code in eine elegantere Datenstruktur zu setzen. Das ist aber häufig eine Verständnisfrage. Kennt ihr die Leute, wenn der Lehrer in der Oberstufe irgendwelche wüsten mathematischen Formeln an die Tafel geschrieben hat, die darin direkt irgendwelche Zusammenhänge gesehen haben und angefangen haben, in ihre Hefte zu schreiben? Ich war so einer nicht :D

Re: Kreis in Pygame unterteilen

Verfasst: Donnerstag 24. Juni 2021, 23:05
von __blackjack__
@k-net: Was die Geschwindigkeit angeht, würde ich mal einfach eine Sinus-Schwingung probieren.

Das `pygame.math`-Modul könnte auch interessant sein.

Re: Kreis in Pygame unterteilen

Verfasst: Freitag 25. Juni 2021, 09:05
von k-net
Hi,
könntest du das etwas präziser benennen? Vielleicht hast du irgendwo ein Beispiel oder Tutorial an dem ich mich orientieren kann?
Danke!

Re: Kreis in Pygame unterteilen

Verfasst: Freitag 25. Juni 2021, 09:17
von __deets__
Du willst eine oszillierende Bewegung. Der Sinus ist eine oszillierende Schwingung.

Re: Kreis in Pygame unterteilen

Verfasst: Freitag 25. Juni 2021, 09:57
von __deets__
Ich habe jetzt erst das Video gesehen. Und damit ist klar, dass du einen Sinus nehmen *musst*. Das sind 8 Phasenverschobene Sinusschwingungen über den gesamten Durchmesser.