Kreis sauber achteln

  • VB.NET

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von nafets3646.

    Kreis sauber achteln

    Hi,

    Ich möchte im Zuge eines Spieles ein Kreis dessen Größe dynamisch bleiben soll suaber achteln. Abmessen läuft hier nicht und ich weiß ja nicht wo der Kreis der in .drawEllipse im Rectangle angegeben wird anfängt.

    Gibt es auch eine Möglichkeit alle Punkte eines Kreises in einer Liste zu speichern, um später ein Objekt ein Achtel des Kreises auf der linie weitergleiten zu lassen?

    Außerdem hat jemand eine Idee wie ich Die Anordung der Spielfiguren speichern kann? Ein Array fällt hier leider raus.

    Hat jemand eine Idee dazu?

    8-) faxe1008 8-)
    Ein Kreis hat unendlich Punkte, deswegen wirst du ihn auch kaum in einer List Of speichern können. Ein Kreis hat 360°, du köntest also durch 3.6 teilen um die Prozent für ein Stückchen zu haben, das rechnest du jetzt nur noch auf den Umfang und du weißt wie groß die Rundung des Stückchen ist.
    Was passt hier nicht?:

    VB.NET-Quellcode

    1. Dim rect As New Rectangle(20, 20, 400, 400)
    2. Public Sub DrawNewField(ByVal g As Graphics)
    3. Dim gpt As GraphicsPath
    4. gpt.AddArc(rect, 0, 45)
    5. gpt.CloseFigure()
    6. g.DrawPath(Pens.Black, gpt)
    7. End Sub


    Der Kreis soll innerhalb des Rectangles liegen.

    8-) faxe1008 8-)

    VB.NET-Quellcode

    1. Dim rect As New Rectangle(20, 20, 400, 400)
    2. Public Sub DrawNewField(ByVal g As Graphics)
    3. Dim Mittex As Integer = rect.X + rect.Width / 2
    4. Dim Mittey As Integer = rect.Y + rect.Height / 2
    5. For u = 1 To 8
    6. Dim gpt As New GraphicsPath()
    7. gpt.AddArc(rect, (u - 1) * 45, 45)
    8. gpt.AddLine(New Point(Mittex, Mittey), New Point(Mittex + 1, Mittey + 1))
    9. gpt.CloseFigure()
    10. g.DrawPath(Pens.Black, gpt)
    11. Next
    12. End Sub


    Habe das nun mit der Schumelei der Linie gelöst.


    So sieht das aus. aber es nicht diese Überschneidungen zeigen. Außerdem brauche ich unbedingt die Punkte der Kreisteil-"ecken".

    8-) faxe1008 8-)
    Sinus und Cosinus vertauschen, dann passts.
    Du kannst Alpha doch ganz einfach aus dem Schleifenzähler berechnen. Alpha = 45 * i (i muss 0-basiert sein). Außerdem musst du die Sinus/Cosinus-Werte dann noch mit dem Radius des Kreises multiplizieren.
    Zum Zeichnen: du kannst dann auch einfach einen Kreis zeichnen und die Linien in der Mitte dann mittels der berechneten Punkte zeichnen.

    VB.NET-Quellcode

    1. Dim rect As New Rectangle(20, 20, 400, 400)
    2. Public Sub DrawNewField(ByVal g As Graphics)
    3. Dim Mittex As Integer = rect.X + rect.Width / 2
    4. Dim Mittey As Integer = rect.Y + rect.Height / 2
    5. g.DrawEllipse(Pens.Black, rect)
    6. Dim leer As New List(Of Point)
    7. leer = GetPoints()
    8. For u = 0 To 8
    9. g.DrawLine(Pens.Black, New Point(Mittex, Mittey), leer.Item(u))
    10. Next
    11. End Sub
    12. Public Function GetPoints() As List(Of Point)
    13. Dim lstofpt As New List(Of Point)
    14. For u = 0 To 8
    15. lstofpt.Add(New Point(Math.Cos(45 * u) * rect.Width, Math.Sin(45 * u) * rect.Width))
    16. Next
    17. Return lstofpt
    18. End Function


    Die Linien liegen quer im Bild total unsinnige Anordnung. Warum zeichnet es nicht richtig?

    8-) faxe1008 8-)
    So?:

    VB.NET-Quellcode

    1. Dim rect As New Rectangle(0, 0, 400, 400)
    2. Public Sub DrawNewField(ByVal g As Graphics)
    3. Dim Mittex As Integer = rect.X + rect.Width / 2
    4. Dim Mittey As Integer = rect.Y + rect.Height / 2
    5. g.DrawEllipse(Pens.Black, rect)
    6. Dim leer As New List(Of Point)
    7. leer = GetPoints()
    8. For u = 1 To 8
    9. g.DrawLine(Pens.Black, New Point(Mittex, Mittey), New Point(leer.Item(u).X + Mittex, leer.Item(u).Y + Mittey))
    10. Next
    11. End Sub
    12. Public Function GetPoints() As List(Of Point)
    13. Dim lstofpt As New List(Of Point)
    14. For u = 0 To 8
    15. lstofpt.Add(New Point(Math.Cos(45 * u) * (rect.Width / 2), Math.Sin(45 * u) * (rect.Width / 2)))
    16. Next
    17. Return lstofpt
    18. End Function

    8-) faxe1008 8-)
    Schau mal:

    VB.NET-Quellcode

    1. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    2. Dim g = e.Graphics
    3. g.SmoothingMode = SmoothingMode.AntiAlias
    4. g.PixelOffsetMode = PixelOffsetMode.HighQuality
    5. Dim rectSize = Math.Min(ClientSize.Width, ClientSize.Height)
    6. Dim rect As New RectangleF((ClientSize.Width - rectSize) / 2.0F, (ClientSize.Height - rectSize) / 2.0F, rectSize, rectSize)
    7. Dim center As New PointF(rect.X + rect.Width / 2, rect.Y + rect.Height / 2)
    8. Dim radius = rectSize / 2.0F
    9. g.DrawEllipse(Pens.Black, rect)
    10. For i = 0 To 7
    11. Dim angle = Math.PI / 4 * i
    12. Dim p As New PointF(CSng(Math.Cos(angle)) * radius + center.X, CSng(Math.Sin(angle)) * radius + center.Y)
    13. g.DrawLine(Pens.Black, center, p)
    14. Next
    15. End Sub
    Das ist der einzige Unterschied oder:

    VB.NET-Quellcode

    1. Dim angle = Math.PI / 4 * i


    So läufts es auch:

    VB.NET-Quellcode

    1. Dim rect As New Rectangle(0, 0, 400, 400)
    2. Public Sub DrawNewField(ByVal g As Graphics)
    3. Dim Mittex As Integer = rect.X + rect.Width / 2
    4. Dim Mittey As Integer = rect.Y + rect.Height / 2
    5. g.DrawEllipse(Pens.Black, rect)
    6. Dim leer As New List(Of Point)
    7. leer = GetPoints()
    8. For u = 0 To 7
    9. g.DrawLine(Pens.Black, New Point(Mittex, Mittey), New Point(leer.Item(u).X + Mittex, leer.Item(u).Y + Mittey))
    10. Next
    11. End Sub
    12. Public Function GetPoints() As List(Of Point)
    13. Dim lstofpt As New List(Of Point)
    14. For u = 0 To 7
    15. Dim angle = Math.PI / 4 * u
    16. lstofpt.Add(New Point(Math.Cos(angle) * (rect.Width / 2), Math.Sin(angle) * (rect.Width / 2)))
    17. Next
    18. Return lstofpt
    19. End Function


    Das mit dem Alising und weitere Feinheiten bau ich später ein. Danke :thumbup: .

    Hat jemand noch eine Idee wie ich die einzelnen Spielfiguren zwischenspeichern kann? ein Array fällt weg weil es ja kein Quadrat ist.

    8-) faxe1008 8-)
    Um es grob zu umreisen:

    Beide Spieler setzen auf die "Ecken" und den Mittelpunkt abwechselnd ihre Spielfiguren (pro Spieler 3 Steine, jedes Feld darf nur ein mal belegt werden). Dann werden die Spielfiguren abwechselnd bewegt solange bis jemand drei Figuren in einer Reihe hat.


    8-) faxe1008 8-)
    Also irgend ne Form einer Auflistung brauchst du wohl trotzdem, da kannst du auch ein 9-Elemente-Array nehmen. Wichtig ist nur, dass der Index im Array nichts mit der Position auf dem Spielfeld zu tun hat, stattdessen müssen die Elemente ihre Nachbarn speichern. Also ein Element außen hat drei Nachbarn, und das Element in der Mitte hat alle anderen Elemente als Nachbarn.
    zum Zeichnen hier noch die Vorstellung der Matrix-Klasse:

    VB.NET-Quellcode

    1. Public Class frm_A0FormTests
    2. Public Sub New()
    3. CreateFigure()
    4. InitializeComponent()
    5. End Sub
    6. Private _gpTemplate As New GraphicsPath, _Matrix As New Matrix, _gpFigure As New GraphicsPath
    7. Private Sub CreateFigure()
    8. Dim rct = New RectangleF(0, 0, 100, 100)
    9. Dim mid = New PointF(rct.Width / 2.0F, rct.Height / 2.0F)
    10. _Matrix.RotateAt(45, mid)
    11. For i = 0 To 7 '8 mal um 45° rotieren
    12. _gpTemplate.StartFigure()
    13. _gpTemplate.AddLine(mid.X, 0, mid.X, rct.Height)
    14. _gpTemplate.Transform(_Matrix)
    15. Next
    16. _gpTemplate.AddEllipse(rct)
    17. End Sub
    18. Private Sub Panel1_Resize(sender As Object, e As System.EventArgs) Handles Panel1.Resize
    19. Dim ctl = DirectCast(sender, Control)
    20. _Matrix.Reset()
    21. _Matrix.Scale(ctl.Width / 100.0F - 1, ctl.Height / 100.0F - 1)
    22. With _gpFigure
    23. .Reset()
    24. .AddPath(_gpTemplate, False)
    25. .Transform(_Matrix)
    26. End With
    27. End Sub
    28. Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
    29. e.Graphics.DrawPath(Pens.Black, _gpFigure)
    30. End Sub
    Das sollte optimal optimiert sein, denn im Paint-Event findet sich nurnoch ein Aufruf - gerechnet wird da nix mehr.
    Auch die Rechnereien sind interessant: von Geometrie ist man weitestgehend verschont - das macht die Matrix.

    Allerdings wird sich das Spiel im weiteren Verlauf so oder so in Richtung Control mit beweglicher Figur entwickeln müssen, also dass (für die Spiel-Steine) Figur-Klassen geschaffen werden, die selbst wissen, wie sie sich malen.