DrawPolygon & DrawStar

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

Xeres

Moderator

Betreff: DrawPolygon & DrawStar

BeitragSa, Jul 05, 2008 16:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Da mir die Funktion DrawPoly in ihrer Form etwas... puristisch erschien, habe ich daraus erst mal eine Funktion geschrieben, die tatsächlich Polygone liefert (regelmäßige versteht sich) und im folgenden erweitert um Sterne hin zu zaubern.
Die Funktionen sollten ausreichend kommentiert sein und sind in dem mini-Programm lauffähig:
Code: [AUSKLAPPEN]
SuperStrict
Rem
DrawPolygon DrawStar.bmx
Autor: Xeres (Moritz Karbaum)
EndRem

AppTitle = "DrawPolygon & DrawStar - www.GreenStarEntertainment.de.tl"
Graphics 800,600,0,60
SeedRnd MilliSecs()

Local rotat:Int = 0

Repeat
   '*** Mit Pfeiltasten Hoch/Runter Winkel ändern:
   If KeyDown(KEY_UP) Then rotat = (rotat + 1) Mod 360
   If KeyDown(KEY_DOWN) Then rotat = (rotat - 1) Mod 360
   SetRotation(rotat)
   
   DrawStar(200, 300)
   DrawPolygon(600, 300)
   
   Flip
   Cls
   If KeyHit(KEY_ESCAPE) Then End
Forever
End


rem
Parameter:
fx|fy   =   Position (Mittelpunkt des Polygons)
fe      =   Anzahl der Ecken
fr      =   Länge der Strecke vom Mittelpunkt bis zu einer Ecke
endrem
Function DrawPolygon(fx:Float = 0, fy:Float = 0, fe:Int = 3, fr:Float = 50)
   If fe < 3 Then fe = 3
   '*** Ein Polygon mit weniger als drei Ecken macht m.M. nach keinen Sinn
   Local retri:Float[fe * 2]
   '*** Initialisieren des Arrays für die Koordinaten.
   '*** Für Jede Ecke werden X und Y Koordianten gebraucht, also Ecken*2
   Local w_pro_part:Float = 360.0 / Float(fe)
   '*** Der Winkel für jeden Polygonabschnitt...
   Local temp_w:Float = GetRotation()
   '**' Temporär den eingestellten winkel speichern
   Local w_akt:Int = temp_w - 90
   rem
      Aktueller winkel, -90 sorgt für spitze oben (ich mags halt ordentlich)
      Jetzt die Berechnung der Koordinaten für jede Ecke:
      Da X und Y Koordianten in einem eindimensionalen Array hintereinander liegen
      müssen, diese 1A Zählschleife
   endrem
   For Local i:Int = 0 To ((fe * 2) - 1) Step 2
      retri[i] = fx + fr * Cos(w_akt)      '** X
      retri[i + 1] = fy + fr * Sin(w_akt)  '** Y
      '*** Die Berechnung ist Simpel; Vom Mittelpunkt (fx) im Aktuellen Winkel (w_akt)
      '*** mit der Länge fr liegt die Koordinate für die Ecke.
      w_akt = (w_akt + w_pro_part) Mod 360
      '*** Der Winkel wird um den Betrag weitergedreht, der vorher ermittelt wurde...
   Next
   SetRotation(0)
   rem
      Die Rotation muss auf 0 gestellt werden, da das Polygon sonst von der Koordiante
      0|0 verschoben würde, was wir nicht wollen. Kommentiert die Zeile einfach aus, und
      seht, was ihr davon habt...
   endrem
   DrawPoly retri       '*** Das fertig berechnete und richtig gedrehte Polygon zeichnen
   SetRotation(temp_w)  '*** Den Winkel wieder ordentlich zurücksetzen.
End Function

rem
Parameter:
fx|fy   =   Position (Mittelpunkt des Sterns)
fe      =   Anzahl der Ecken
fr      =   Länge der Strecke vom Mittelpunkt bis zu einer Ecke
ff      =   Faktor um die "Einbuchtungen" zu erzeugen (immer kleiner 1)
endrem
Function DrawStar:Int(fx:Float = 0, fy:Float = 0, fe:Int = 5, fr:Int = 50, ff:Float = 0.31)
   If fe < 3 Then fe = 3
   '*** Schon ein Stern unter 5 Ecken sieht reichlich komisch aus, aber auch hier minimum 3 Ecken
   Local retri:Float[fe * 2 * 2]
   '*** Wieder brauchen wir für jede Ecke 2 Koordinaten, aber auch genausoviel Einbuchtungen
   '*** um dem Stern seine Spitzigkeit zu geben
   Local w_pro_part:Float = 360.0 / Float(fe)
   Local temp_w:Float = GetRotation()
   Local w_akt:Int = temp_w - 90
   '*** Winkelzeug ist das gleiche wie bei DrawPolygon   
   Local star:Int = 1
   '*** Jetzt brauchen wir einen Schalter um zwischen 0 = Spitze und 1=Einbuchtung umzuschalten:
   For Local i:Int = 0 To ((fe * 2 * 2) - 1) Step 2 '*** Koords berechnen
      If star = False Then
         retri[i] = fx + fr * Cos(w_akt)      '** X
         retri[i + 1] = fy + fr * Sin(w_akt)  '** Y
      EndIf
      If star = True Then
         retri[i] = fx + fr * Cos(w_akt) * ff      '** X
         retri[i + 1] = fy + fr * Sin(w_akt) * ff   '** Y
      EndIf
      w_akt = (w_akt + w_pro_part) Mod 360
      star:~1 '* Das "~" entspricht XOR
      rem
         Auch nicht anders als oben, nur, dass der Schalter "star" in jedem Durchlauf geswitcht wird,
         womit abwechselt Ecken (siehe Polygon) und Einbuchtungen berechnet werden.
         Der Faktor wird einfach einmultipliziert und verschiebt die Einbuchtungen etwas weiter nach innen
         (wenn man wie der Erfinder sich es dachte kleinere Zahlen als 1 verwendet, aber ihr macht ja eh
         was ihr wollt).
         Der Faktor ist auf einen Fünfzackigen Stern abgestimmt, wie die Voreingestellten Parameter ihn vorgeben,
         eine Regel dafür habe ich nicht gefunden, bei Sternen mit mehr Ecken müsst ihr euch selber Gedanken machen
      endrem
   Next
   SetRotation(0)       '*** Ohne Rotation! (wäre von 0|0 aus und damit falsch)
   DrawPoly retri       '*** Polygon zeichnen
   SetRotation(temp_w)  '*** Winkel wieder zurücksetzen... fertig.
End Function


(Blitzmax Version 1.28)
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group