Berechnung eines ausgefüllten Kreises in einem Array

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Berechnung eines ausgefüllten Kreises in einem Array

    Wie schon in der Überschrift erwähnt, versuche ich einen ausgefüllten Kreis in ein Array zu schreiben. Hintergrund ist eine 2D World Map, aber ich kenne keine passende Formel.

    Mfg, Crazydrift
    Wat?
    Was hat das für einen Sinn einen Kreis in ein Array zu schreiben? Du weißt, dass das keinen Sinn hat, da der Kreis rund ist und du so nur Annäherungsweise an die Rundeform kommst.
    Ansonsten: wofür genau willst das verwenden?

    Crazydrift schrieb:


    Hintergrund ist eine 2D World Map, aber ich kenne keine passende Formel.

    Pic:


    Die Welt wird durch das Array gezeichnet.
    Einen nicht ausgefüllten Kreis bekomme ich durch:

    VB.NET-Quellcode

    1. Public Shared Sub Circle(a As Double, b As Double, r As Double, block As Blocks)
    2. ' Zeichnet einen Kreis mit Radius r um den Mittelpunkt (a, b), wobei n Punkte gesetzt werden
    3. Dim n As Integer = 5
    4. Dim pi As Double = 3.141
    5. Dim w As Double = 0
    6. Dim s As Double = 2 * Math.PI \ n
    7. For i As Integer = 1 To n * 100
    8. w += s
    9. Try
    10. World(CInt(a + r * Math.Cos(w)), CInt(b + r * Math.Sin(w))) = block
    11. Catch ex As Exception
    12. End Try
    13. Next
    14. End Sub
    dann mach dirn Array mit Index-Positionen und zeichne dann entsprechend der Index-Position deine Sachen.
    Also:

    VB.NET-Quellcode

    1. Dim items() As GameElement = New GameElement() {new GameElement() With {.x = x, .y = y, .index = i}}
    2. Public Structure GameElement
    3. Public Property x As Integer
    4. Public Property y As Integer
    5. Public Property index As Integer
    6. End Structure

    Und dann musst du nurnoch an X, Y den Inhalt von i zeichnen.
    du füllst das Array mit deinen Items und whatever du da drin haben willst.
    Für index 0 = Luft, 1 = Erde, 2 = Kopf, 3 = Körper oben, 4 = Beine
    Dann musst du "nur" die Items durchlaufen und die Sachen entsprechend zeichnen.

    VB.NET-Quellcode

    1. For Each gE As GameElement In items
    2. Select Case gE.index
    3. Case 0
    4. ' hier die Luft zeichnen, mit gE.x und gE.y. Je nach dem wie du deinen Zeichencode hast
    5. Case 1
    6. ' ...
    7. Case 2
    8. ' ...
    9. Case 3
    10. ' ...
    11. Case 4
    12. '...
    13. Case undsoweiter
    14. End Select
    15. Next
    Meinst Du so etwas:

    VB.NET-Quellcode

    1. Private Sub Form1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
    2. Dim g As Graphics = e.Graphics
    3. g.FillEllipse(Brushes.Black, New Rectangle(1, 2, 3, 4))
    4. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @AliveDevil
    Ich glaube du hast die Frage falsch verstanden...

    In der Map-Generation am Anfang brauche ich eine tools, um z.b. einen kreis aus sand in den boden zu "malen".

    Das Array besteht aus id's, ca. so:

    111111000432222
    111994442211145
    558237619433333

    Und diese Zahlen werden dann eben immer durch block-texturen ersetzt und gezeichnet, alles kein Problem. Nun will ich aber in so ein Zahlen-Array "Kreise" einfügen. Das würde ca. so aussehen:

    0000000000
    0000110000
    0001111000
    0001111000
    0000110000
    0000000000

    @RodFromGermany
    Nein, sowas meine ich nicht, übrigens arbeite ich nicht mit GDI+, sondern mit XNA, das ist aber völlig egal. Ich will lediglich einen "Kreis" in ein Array zeichnen, das habe ich zwar schon geschafft, dieser ist aber leider nicht ausgefüllt, sondern innen leer.
    mit einer for schleife für jedes array-feld prüfen ob es im kreis liegt oder eben nicht.

    zur prüfung kann man den satz des pythagoras anwenden
    Bilder
    • kreis.png

      4,44 kB, 221×192, 1.219 mal angesehen

    Crazydrift schrieb:

    dieser ist aber leider nicht ausgefüllt, sondern innen leer.
    Dann arbeite nicht mit x² + y² = r² (Peripherie des Kreises) sondern mit x² + y² <= r² (Peripherie und das Innere des Kreises):

    VB.NET-Quellcode

    1. Dim x0, y0, r As Integer
    2. For x = -50 To 50
    3. For y = -50 To 50
    4. If (x - x0) * (x - x0) + (y - y0) * (y - y0) <= r * r Then
    5. ' was tun
    6. End If
    7. Next
    8. Next
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich hab's aus Spaß mal als Console-App geschrieben:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Module KreisArray
    3. Private Structure Punkt
    4. Dim x As Integer
    5. Dim y As Integer
    6. End Structure
    7. Sub Main()
    8. ''==================================================
    9. ''Deklartation
    10. Dim Array(20, 20) As Boolean
    11. Dim Mittelpunkt As Punkt
    12. Mittelpunkt.x = CInt(Math.Floor(Array.GetLength(0) / 2)) 'Mittelpunkt des Kreises auf Mitte des Arrays festlegen
    13. Mittelpunkt.y = CInt(Math.Floor(Array.GetLength(1) / 2)) 'Mittelpunkt des Kreises auf Mitte des Arrays festlegen
    14. Const Radius As Integer = 5
    15. Const AusgabeChar As Char = "#"c
    16. ''==================================================
    17. ''Kreis in das Array schreiben
    18. For x As Integer = Mittelpunkt.x - Radius To Mittelpunkt.x + Radius
    19. For y As Integer = Mittelpunkt.y - Radius To Mittelpunkt.y + Radius
    20. If ((x - Mittelpunkt.x) ^ 2 + (y - Mittelpunkt.y) ^ 2) < Radius ^ 2 Then
    21. Array(x, y) = True
    22. End If
    23. Next
    24. Next
    25. ''==================================================
    26. ''Array in Console ausgeben
    27. For x As Integer = 0 To Array.GetLength(0) - 1
    28. For y As Integer = 0 To Array.GetLength(1) - 1
    29. If Array(x, y) = True Then
    30. Console.ForegroundColor = ConsoleColor.DarkGreen
    31. Else
    32. Console.ForegroundColor = ConsoleColor.Gray
    33. End If
    34. Console.SetCursorPosition(x, y)
    35. Console.Write(AusgabeChar)
    36. Next
    37. Next
    38. ''==================================================
    39. ''Mittelpunkt in Console ausgeben
    40. Console.ForegroundColor = ConsoleColor.Red
    41. Console.SetCursorPosition(Mittelpunkt.x, Mittelpunkt.y)
    42. Console.Write(AusgabeChar)
    43. Console.ReadKey()
    44. End Sub
    45. End Module



    //EDIT: BTW Warum gibt Math.Floor keinen Integer zurück ?(
    Dateien
    • KreisArray.zip

      (57,11 kB, 178 mal heruntergeladen, zuletzt: )
    Nein - eigentlich nur in Codes, die zur Veranschaulichung von Sachverhalten dienen, um Codeabschnitte getrennter Funktionalität untereinander strukturiert zu differenzieren. Mir fällt spontan kein Argument ein, das dagegen spricht, oder zählst du die paar Bytes Speicherplatz, die durch die Zeilenumbrüche verloren gegangen sind?

    Wenn du ein Problem damit hast, "anfängerfreudlich" strukturierten Code zu lesen, lässt du in Zukunft einfach den Expander zu. Dass du als extrem erfahrener User mit wesentlich Anspruchsvollerem klar kommst, stellt hier niemand in Abrede. Dem TE wurde scheinbar mit diesem Ansatz weitergeholfen. Die (folglich unnötige) Beschwerde über die Formatierung erscheint als Trollerei.
    Ich hab nix gegen Leerzeilen, nur gegen die sinnlosen. Guck, so hätte ich formatiert, und halte ich für besser lesbar:

    VB.NET-Quellcode

    1. Option Strict On
    2. Module KreisArray
    3. Private Structure Punkt
    4. Dim x As Integer
    5. Dim y As Integer
    6. End Structure
    7. Sub Main()
    8. Const Radius As Integer = 5
    9. Const AusgabeChar As Char = "#"c
    10. Dim Array(20, 20) As Boolean
    11. Dim Mittelpunkt As Punkt
    12. Mittelpunkt.x = CInt(Math.Floor(Array.GetLength(0) / 2)) 'Mittelpunkt des Kreises auf Mitte des Arrays festlegen
    13. Mittelpunkt.y = CInt(Math.Floor(Array.GetLength(1) / 2)) 'Mittelpunkt des Kreises auf Mitte des Arrays festlegen
    14. ''Kreis in das Array schreiben
    15. For x As Integer = Mittelpunkt.x - Radius To Mittelpunkt.x + Radius
    16. For y As Integer = Mittelpunkt.y - Radius To Mittelpunkt.y + Radius
    17. If ((x - Mittelpunkt.x) ^ 2 + (y - Mittelpunkt.y) ^ 2) < Radius ^ 2 Then
    18. Array(x, y) = True
    19. End If
    20. Next
    21. Next
    22. ''Array in Console ausgeben
    23. For x As Integer = 0 To Array.GetLength(0) - 1
    24. For y As Integer = 0 To Array.GetLength(1) - 1
    25. If Array(x, y) = True Then
    26. Console.ForegroundColor = ConsoleColor.DarkGreen
    27. Else
    28. Console.ForegroundColor = ConsoleColor.Gray
    29. End If
    30. Console.SetCursorPosition(x, y)
    31. Console.Write(AusgabeChar)
    32. Next
    33. Next
    34. ''Mittelpunkt in Console ausgeben
    35. Console.ForegroundColor = ConsoleColor.Red
    36. Console.SetCursorPosition(Mittelpunkt.x, Mittelpunkt.y)
    37. Console.Write(AusgabeChar)
    38. Console.ReadKey()
    39. End Sub
    40. End Module

    Ich seh halt oft so viele sinnlose Leerzeilen, da nehme ich an, diese komische Unsitte guckt einer vom anneren ab.

    Dabei ist beim Coden immer auch wichtig, dass man möglichst viel in einem Blick hat, und dass was zusammen-gehört, auch als solches erkenntlich ist.
    Und Leerzeilen haben den Sinn, verschiedene Bereiche, deren Zeilen je enger zusammengehören, bischen optisch voneinander abzugrenzen.
    Aber da reicht eine Zeile - es soll ja auch noch erkennbar bleiben, dass das alles in derselben Methode stattfindet.

    FuFu^^ schrieb:

    Warum gibt Math.Floor keinen Integer zurück
    Weil der andere Benutzer dieser Funktion da ein Double braucht, und er hat sich bei Bill eher angestellt. :D
    Dafür gibt es dier Funktion Convert.ToInt()
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!