Dreieck zeichnen, Katheden beschriften

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 50 Antworten in diesem Thema. Der letzte Beitrag () ist von MichaHo.

    MichaHo schrieb:

    komplett falsch
    isses wohl nicht, da hat nur ein y-Offset das falsche Vorzeichen, weil beim Paint-Befehl oben links (0, 0) ist. :thumbsup:
    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!

    MichaHo schrieb:

    So müsste ich doch die Mitte der Seite klein c berechnet haben, oder?
    kann man nix zu sagen, ausser dass die Benamung falsch ist.
    Und bei falscher Benamung ist die Berechnung ebenfalls überaus leicht falsch zu machen.
    Dein ptMitte ist keine Mitte, und es ist auch nicht erkennbar, welche der Variablen überhaupt das Ergebnis beinhalten sollen.

    Also ich schlage folgende Benamung vor:
    ptA, ptB, ptC für die Eckpunkte.
    pt_a, pt_b, pt_c für die Kanten-Mitten.
    alpha, beta, gamma für die Winkel - alles ganz analog den Gepflogenheiten der Mathematik. Dann sollte der Code recht leicht nachvollzieh- und verifizier-bar sein.
    Und da du 3 Kanten-Mitten berechnen musst, empfiehlt sich das auch gleich in eine eigene Methode auszulagern.
    Danke @RodFromGermany jetzt passt es

    VB.NET-Quellcode

    1. Dim ptHypothenuse As New PointF((ptKoord.X / 2) + ptMitte.X, (-ptKoord.Y / 2) + ptMitte.Y)


    ich muss mich intensiver mit dem Koordinatensystem der Form beschäftigen, ich glaub da happerts etwas...
    so, jetzt mache ich mich an die GegenKathede und Ankathede :(

    EDIT:Danke @ErfinderDesRades... ich hatte diese Benamung (fast genauso)
    angedacht, aber wieder verworfen da ich einige CodeTeile aus dem
    Übungsprojekt des Lernheftes übernommen habe.
    ptMitte ist bei mir ptA, ptMaus ist ptB und gegenKathede ist ptC.
    Ich werde die Aufgabe aber noch einmal komplett neu schreiben, dann Bename ich auch so, wie ich den Code dann verstehe...
    Dein
    Beispiel mit der Uhr aus dem gestrigen Post hab ich mir angeschaut und
    versucht zu verstehen, das haut aber noch nicht wirklich hin *Seufz*

    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    dann Bename ich auch so
    Du kannst mit dem Studio Variablen, Prozeduren usw. ganz easy umbenennen. Rechtsklick auf die Variable => Umbenennen => neuer Name, feddich.
    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!
    Danke Rod, die Möglichkeit kenne ich, geht auch wenn man eine Variable umbenannt hat, erscheint unterhalb ein kleiner roter Balken, dort drauf drücken benamt die Variable im ganzen Code um. Ich will aber die Aufgabe noch einmal von Grund auf neu anfangen, ohne code zu kopieren, ich denke dann steige ich eher dahinter welche Koordinate wo liegt und wie man sie anspricht.
    "Hier könnte Ihre Werbung stehen..."
    Gute Idee. Fang am besten mit einer neuen Klasse TriAngle an, die alles beinhaltet, was ein 3-Eck braucht. Dazu bringe ich nochmal diese Gedanken in Erinnerung:

    ErfinderDesRades schrieb:

    Also ich schlage folgende Benamung vor:
    ptA, ptB, ptC für die Eckpunkte.
    pt_a, pt_b, pt_c für die Kanten-Mitten.
    alpha, beta, gamma für die Winkel - alles ganz analog den Gepflogenheiten der Mathematik. Dann sollte der Code recht leicht nachvollzieh- und verifizier-bar sein.
    Und da du 3 Kanten-Mitten berechnen musst, empfiehlt sich das auch gleich in eine eigene Methode auszulagern.
    So eine Trinangle-Klasse kann dann auch weiter ausgebaut werden und mit Figure-Funktionalität versehen, also man kann, nachdem die Mathematik stimmt, ihr auch beibringen, sich zu zeichnen etc (s.Post#10).
    Hallo @ErfinderDesRades, @RodFromGermany, @ThePlexian
    Danke Danke durch Eure Hinweise hab ich doch tatsächlich etwas gefunden, was sogar ich verstehe und ganz alleine umsetzen konnte...
    Jetzt muss ich noch austüffteln, wie ich dies in eine eigene Klasse packe, aber das guck ich dann nächste Woche...
    Hier mein jetziger Code:

    VB.NET-Quellcode

    1. Imports System.Drawing
    2. Public Class Form1
    3. Private ptA, ptB, ptC As PointF
    4. Private fFont As New Font("Arial", 10.0)
    5. Private bBrush As New SolidBrush(Color.Green)
    6. Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
    7. ptA = New PointF(CSng(ClientSize.Width / 2), CSng(ClientSize.Height / 2))
    8. ptB = New PointF(e.X, e.Y)
    9. ptC = New PointF(ptB.X, ptA.Y)
    10. Invalidate()
    11. End Sub
    12. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    13. Dim points() As PointF = {ptA, ptB, ptC}
    14. e.Graphics.DrawPolygon(Pens.Red, points)
    15. e.Graphics.DrawString("A", fFont, bBrush, ptA)
    16. e.Graphics.DrawString("B", fFont, bBrush, ptB)
    17. e.Graphics.DrawString("C", fFont, bBrush, ptC)
    18. e.Graphics.DrawString("a", fFont, bBrush, middleSite(ptB, ptC))
    19. e.Graphics.DrawString("b", fFont, bBrush, middleSite(ptA, ptC))
    20. e.Graphics.DrawString("c", fFont, bBrush, middleSite(ptA, ptB))
    21. End Sub
    22. Private Shared Function middleSite(ByVal a As PointF, ByVal b As PointF) As PointF
    23. Return New PointF(CSng(0.5 * (a.X + b.X)), CSng(0.5 * (a.Y + b.Y)))
    24. End Function
    25. End Class

    Wobei ich einen kleinen Wehrmutstropfen habe, das c der Seite A nach B ist innerhalb des Dreiecks. Das muss ich mir noch einmal anschauen.
    Danke an Euch alle
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    VB.NET-Quellcode

    1. Return New PointF(CSng(0.5 * (a.X + b.X)), CSng(0.5 * (a.Y + b.Y)))
    machst Du

    VB.NET-Quellcode

    1. Return New PointF(0.5F * (a.X + b.X), 0.5F * (a.Y + b.Y))
    und oben analog.
    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!
    Hallo @RodFromGermany...
    das hat den gleichen Effekt. Das F bedeutet float oder?
    was meinst du mit "oben analog" ?
    soll ich für die Seite c einfach eine eigene Function schreiben, wie in meinem vorherigen code?
    Wobei

    VB.NET-Quellcode

    1. Function middleSiteC(ByVal a As PointF, ByVal b As PointF) As PointF
    2. Return New PointF(CSng(0.5 * (a.X + b.X)), CSng(0.5 * (-a.Y + b.Y)))
    3. End Function

    leider nicht funktioniert. Du hattest ja vorher geschrieben das die y Koordinate das falsche Vorzeichen hatte, daher dachte ich, würde ein - vor a.y ausreichen. leider klappt das nicht.
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    oben analog

    VB.NET-Quellcode

    1. ptA = New PointF(ClientSize.Width / 2.0F, ClientSize.Height / 2.0F)
    Das PointF-Array kannst Du schon in Form1_MouseMove anlegen und als einzige PointF-Klassenvariavle vewenden.
    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!
    bringt immernoch keinerlei veränderung :(

    VB.NET-Quellcode

    1. Imports System.Drawing
    2. Public Class Form1
    3. Private ptA, ptB, ptC As PointF
    4. Private fFont As New Font("Arial", 10.0)
    5. Private bBrush As New SolidBrush(Color.Green)
    6. Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
    7. ptA = New PointF(ClientSize.Width / 2.0F, ClientSize.Height / 2.0F)
    8. ptB = New PointF(e.X, e.Y)
    9. ptC = New PointF(ptB.X, ptA.Y)
    10. Invalidate()
    11. End Sub
    12. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    13. Dim points() As PointF = {ptA, ptB, ptC}
    14. e.Graphics.DrawPolygon(Pens.Red, points)
    15. e.Graphics.DrawString("A", fFont, bBrush, ptA)
    16. e.Graphics.DrawString("B", fFont, bBrush, ptB)
    17. e.Graphics.DrawString("C", fFont, bBrush, ptC)
    18. e.Graphics.DrawString("a", fFont, bBrush, middleSite(ptB, ptC))
    19. e.Graphics.DrawString("b", fFont, bBrush, middleSite(ptA, ptC))
    20. e.Graphics.DrawString("c", fFont, bBrush, middleSite(ptA, ptB))
    21. End Sub
    22. Function middleSite(ByVal a As PointF, ByVal b As PointF) As PointF
    23. Return New PointF(0.5F * (a.X + b.X), 0.5F * (a.Y + b.Y))
    24. End Function
    25. End Class
    Bilder
    • forumForm.PNG

      26,35 kB, 589×518, 73 mal angesehen
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    leider nicht funktioniert
    Was ganz genau funktioniert da nicht?
    Bei mir ist das stimmig, bis auf die Zuordnung von A,B,C zu den Ecken.
    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!
    die Benennung der Seiten a und b ist ausserhalb des Dreiecks, c ist innerhalb, sollte auber auch außerhalb sein...
    Die Eckpunkte könnte ich mit new Size(-15,-10) noch anpassen. Wenn ich das allerdings mit der Function bei c versuche sieht es doof aus, da lass ich es lieber innerhalb des Dreiecks.
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    da lass ich es lieber innerhalb des Dreiecks
    Du musst nachsehen, ob die Spitze ober- oder unterhalb der Basis liegt und dass Du innerhalb der ClientArea schreibst.
    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!
    Hmmm... die Spitze ist ptB und das sind x und y koordinaten... und die sind größer 0 wenn sie oberhalb von der Basis (also ptA) sind, richtig?

    VB.NET-Quellcode

    1. Function middleSite(ByVal a As PointF, ByVal b As PointF) As PointF
    2. If ptB.X > 0 AndAlso ptB.Y > 0 Then
    3. Return New PointF(0.5F * (a.X + b.X), 0.5F * (a.Y + b.Y))
    4. Else
    5. Return New PointF(0.5F * (a.X + b.X), 0.5F * (-a.Y + b.Y))
    6. End If
    7. End Function

    das funktioniert leider nicht.... ich wieder mit den Koordinaten :(
    "Hier könnte Ihre Werbung stehen..."
    Dass die Beschriftungen immer aussen liegen kann ganz schön vertrackt werden. Guck mal das Bildle in post#1 nochmal an: Da siehst du, dass die Kantenbeschriftungen teilweise genau auf der Linie zwischen 2 Eck-Beschriftungen liegen, und manchmal aber eben auch nicht.
    Also auf die Schnelle wüsste ich garnet, wie das in dem Bild algorithmisch gelöst ist - evtl. steht auch gar kein Algo dahinter, sondern die Buchstaben sind einfach mit Photoshop plaziert worden, und nu seht man zu...
    Mal ein paar wilde Ideen zu der Beschriftung.

    Für die Eckpunkte könnte man jede Seite "virtuell" um einen festen Wert verlängern. Dann hast du bei jeder Ecke zwei neue Enden, davon die Mitte und dort den Buchstaben hin. Wie groß der feste Wert sein muss, würde ich von der Fontgrößte abhängig machen.

    Für die Seitenbeschriftung würde ich eine "virtuelle" Normale auf die Seitenhalbierende stellen und erst dort die Beschriftung setzen. Dafür brauchst du entweder eine Methode um herauszufinden welches die Normalenrichtung nach außen ist Oder du bist konsistent bei der Richtungsdefinition der Dreiecksseiten und kannst daraus schließen wohin außen zeigt...
    Bilder
    • 3eck.jpg

      19,84 kB, 640×400, 62 mal angesehen