Reflektion eines Lichtstrahls im Quadrat visuell darstellen

  • VB.NET

Es gibt 31 Antworten in diesem Thema. Der letzte Beitrag () ist von Brötchen29.

    Reflektion eines Lichtstrahls im Quadrat visuell darstellen

    Hallo Zusammen,

    ich bin kein regelmäßiger Programmierer in Sachen Visual Basic, daher würde gerne höflichst um Eure Hilfe bitten! :)

    Ich schreibe zur Zeit ein Programm zum Thema Lichtbrechung in einem Glaswürfel. Damit die Problemstellung nicht zu schwierig wird, soll der Würfel 2-Dimensional betrachtet werden (also quasi als Quadrat). Durch Eingabe von Einfallswinkel, Brechungsindex und Kantenlänge werden die verschiedenen Winkelgrößen, die der Lichtstrahl durch die Reflektion erzeugt, über eine Textbox ausgegeben. Die Berechnung der Winkel funktioniert, ist kein Problem und klappt soweit.

    Der für mich Schwierige Teil ist, dass das ganze grafisch ausgegeben werden soll. Ich habe im Anhang eine Skizze angefügt, wie die Ausgabe nachher aussehen soll.
    Durch Eingabe der Kantenlänge soll das Quadrat mit dieser Kantenlänge erzeugt werden. Der Strahl fällt an einer der vier Würfelseiten immer mittig auf. Durch die bereits berechneten Winkel soll der Lichtstrahl dann entsprechend in der Rotation gedreht werden, so dass dieser Lichtstrahl im Würfel letzten Endes simuliert wird.

    Leider habe ich bisher noch keine Idee, wie ich diese Visualisierung umsetzen kann. Ich weiß leider nicht einmal, wie ich durch Eingabe der Kantenlänge ein entsprechendes Quadrat erzeugen kann.

    Könnt Ihr mir bei diesem Problem helfen? Ich habe gefühlt jede Seite bei Google durchstöbert, bin aber nicht zum gewünschten Aufschluss gekommen.

    Ich danke Euch im Voraus für die Mühen! :) :)

    VG
    Benni
    Bilder
    • Lichtbrechung.jpg

      15,76 kB, 708×491, 134 mal angesehen
    Auch hier brauchst du ein Datenmodell.
    Das ist eine tolle Übung in Abstraktion! :thumbsup:
    Für alles, was auf deinem Bild mehrfach auftritt, musst du eigene Klassen schreiben, und die dann auch in richtige Beziehung zueinander setzen.
    Am Ende kannst du dann den einfallenden Strahl mittels Angabe 2er Punkte definieren, zuzüglich Brechungs-Index, und das Proggi kann den Rest errechnen und darstellen.

    Also konzipiere und mach zuerst die Eingabe: Wie willst du die 2 Punkte definieren, wie das Rechteck, und wie den Button-Click, dass eine solche Methode aufgerufen werden kann:

    VB.NET-Quellcode

    1. Private Sub CalculateBeam(pt1 as Point, pt2 As Point, glasBlock As Rectangle, refractionIndex As Double)
    Beachte, dass ich mit dieser einfachen Signatur schon einen erheblichen Teil der Konzipierungs-Arbeit vorlege, im Grunde alles, was den erforderlichen Input angeht.
    Willkommen im Forum. :thumbup:

    Brötchen29 schrieb:

    ein entsprechendes Quadrat erzeugen
    Du hast hier eine Reihe von Problemen, die alle sehr ineinander greifen und die Du alle auf ein Mal lösen willst. Das wird so nicht funktionieren.
    Zerlege Dein Problem in disjunkte Einzelaufgaben, die Du jedes für sich in je einem separaten Projekt löst.
    Wenn dann alle Teilprobleme zu Deiner Zufriedenheit gelöst sind, fasse sie wiederum in einem neuem Projekt zusammen.
    Das Quadrat gestaltest Du so. Input der Kantenlänge in Pixeln über ein NumericUpDown, Darstellung auf der Form:

    VB.NET-Quellcode

    1. Private Quadrat As Integer
    2. Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
    3. Me.Quadrat = CInt(Me.NumericUpDown1.Value)
    4. Me.Invalidate()
    5. End Sub
    6. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
    7. e.Graphics.DrawRectangle(Pens.Black, New Rectangle(50, 50, Me.Quadrat, Me.Quadrat))
    8. 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!
    Hey!

    Vielen Dank schonmal für die schnelle und hilfreiche Aussage! :)

    Grundsätzlich verstehe ich glaube ich was du meinst. Mir fehlt allerdings noch etwas der zusammenhang zu meinem Programm. So sieht mein aktueller Quellcode aus (ist zwar Primitiv geschrieben, funktioniert aber immerhin :D). Wie müsste ich die Methode speziell in meinem Code einbauen?

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles berechnen.Click
    3. Dim bi As Double
    4. Dim kl As Double
    5. Dim ew As Double
    6. Dim sine1 As Double
    7. Dim wi1 As Double
    8. Dim wi2 As Double
    9. Dim wi3 As Double
    10. Dim wi4 As Double
    11. Dim wi5 As Double
    12. bi = Convert.ToDouble(brechungsindex.Text)
    13. kl = Convert.ToDouble(Kantenlaenge.Text)
    14. ew = Convert.ToDouble(einfallwinkel.Text)
    15. sine1 = (1 / bi) * Math.Sin(ew / 180 * Math.PI)
    16. wi1 = Math.Round(Math.Asin(sine1) * 180 / Math.PI, 2)
    17. E1.Text = Convert.ToString(wi1)
    18. wi2 = 90 - wi1
    19. E2.Text = Convert.ToString(wi2)
    20. wi3 = 90 - wi2
    21. E3.Text = Convert.ToString(wi3)
    22. wi4 = 90 - wi3
    23. E4.Text = Convert.ToString(wi4)
    24. wi5 = 90 - wi4
    25. E5.Text = Convert.ToString(wi5)




    Danke nochmal für die Hilfe! :)

    Gruß
    Benni
    kann man sich ja nicht angucken - hier mal eine lesbarere Überarbeitung:

    VB.NET-Quellcode

    1. Private Sub berechnen_Click(sender As Object, e As EventArgs) Handles berechnen.Click
    2. Dim bi = Convert.ToDouble(brechungsindex.Text)
    3. Dim kl = Convert.ToDouble(Kantenlaenge.Text)
    4. Dim ew = Convert.ToDouble(einfallwinkel.Text)
    5. Dim sine1 = (1 / bi) * Math.Sin(ew / 180 * Math.PI)
    6. Dim wi1 = Math.Round(Math.Asin(sine1) * 180 / Math.PI, 2)
    7. E1.Text = Convert.ToString(wi1)
    8. Dim wi2 = 90 - wi1
    9. E2.Text = Convert.ToString(wi2)
    10. Dim wi3 = 90 - wi2
    11. E3.Text = Convert.ToString(wi3)
    12. Dim wi4 = 90 - wi3
    13. E4.Text = Convert.ToString(wi4)
    14. Dim wi5 = 90 - wi4
    15. E5.Text = Convert.ToString(wi5)
    16. End Sub
    Beachte, dass deine ganzen Vorausdeklarationenen (bei dir zeilen #7 - #23) nicht .Net-gemäß sind.



    Zur Frage:
    naja, du kopierst Rods Snippet halt bei dir ein - in dein Form, als zusätzliche 2 Methoden zu deim Button1Click.
    Dabei wird auffallen, dass dein Form kein NumericUpdown-Control enthält, also geh in den Form-Designer, und pack ein NumericUpdown aufs Form.
    Und dann Testlauf.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Brötchen29 schrieb:

    VB.NET-Quellcode

    1. bi = Convert.ToDouble(brechungsindex.Text)
    Was passiert, wenn in der TextBox "Roullade mit Klößen" drin steht?
    Also: Keine TextBoxen, sondern NumericUpdowns.
    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 Euch schonmal für die Antworten! Ich bin eigentlich SAP-Berater und habe mit Programmieren nichts am Hut, daher entschuldigt mein Leyenhaftes Coding. :D
    Ich muss das Programm im Rahmen meines Studiums entwerfen.

    Also das mit dem Rechteck funktioniert jetzt dank NumericUpDown. Jetzt muss ich es nur noch hinkriegen, den Lichtstrahl dortdrin abzubilden :)
    siehe post#2: Nu musst du hinkriegen, eine Methode aufzurufen, die die Aufgabe übernimmt.
    Und dann gehts los mit dem Datenmodell: Es können ja 1, 2 oder 3 Grenzflächen-Kontakte auftreten - ganz sicher bin ich in der Physik nicht - evtl. sogar noch mehr, oder?
    Und an jedem Kontakt musst du folgendes aussagen können:
    • Position
    • Winkel der Grenzfläche (zumindest hor oder vert)
    • Einfallswinkel
    • Ausfallswinkel
    • obs eine Spiegelung ist oder eine Brechung
    Für diese Kontakt-Punkte musst du eine Klasse entwerfen - zunächstmal gänzlich unabhängig von der Frage, wie du diese Info dann präsentieren willst.

    Du siehst, es wird anspruchsvoll, also ich mach erst weiter, wenn du zeigst, dass du die von mir als erforderlich erachtete Methode aufrufst.
    Hi! Also, habe gerade nochmal probiert Eure Ansätze umzusetzen. Ich bin jetzt soweit gekommen, dass zusätzlich zum Quadrat eine Strecke erzeugt wird. Leider ist diese momentan noch Fix, also mit festen Koordianten hinterlegt. Bin ich auf dem richtigen Weg?

    VB.NET-Quellcode

    1. Private Sub grafik_Click(sender As Object, e As EventArgs) Handles grafik.Click
    2. ' Stift generieren.
    3. Dim blackPen As New Pen(Color.Black, 1)
    4. ' Koordinatenpunkte festlegen
    5. Dim x1 As Single = 100
    6. Dim y1 As Single = 100
    7. Dim x2 As Single = 500
    8. Dim y2 As Single = 100
    9. ' Strahl auf Form abbilden.
    10. Dim g As Graphics = Me.CreateGraphics()
    11. g.DrawLine(blackPen, x1, y1, x2, y2)
    12. blackPen.Dispose()
    13. End Sub


    Ich habe mich damit den ganzen Nachmittag auseinandergesetzt und mein Kopf ist wirklich am rauchen weil ich eben vorher nicht viel mit VB zu tun hatte..

    Grüße
    Fast. Geziehcnet wird nur im Paint-Event, du musst das ganze leicht abändern:
    Im Click-Event wird nur ein Boolean auf True geändert. Das Paint-Event der Form wird jedes mal aufgerufen, wenn die FOrm neugezeichnet werden muss.
    Da wird abgefragt, ob die Variable schon wahr ist, dann gezeichnet.

    VB.NET-Quellcode

    1. Private _allowPainting As Boolean = False
    2. Private Sub grafik_Click(sender As Object, e As EventArgs) Handles grafik.Click
    3. _allowPainting = True
    4. End Sub
    5. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
    6. If Not _allowPainting Then Exit Sub 'Oder Return, bin mir nicht sicher
    7. ' Koordinatenpunkte festlegen
    8. Dim x1 As Single = 100
    9. Dim y1 As Single = 100
    10. Dim x2 As Single = 500
    11. Dim y2 As Single = 100
    12. ' Strahl auf Form abbilden.
    13. e.Graphics.DrawLine(Pens.Black, x1, y1, x2, y2)
    14. End Sub
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
    Wie @ErfinderDesRades bereits gesagt hast währe hier ein Datenmodell angebracht.
    Mach dir für die Strahlen eine Klasse z.B. Ray, welche alle nötigen Informationen enthält, die der Strahl so hat.
    In deiner Form hast du dann zugriff auf eine List(Of Ray) und im Paint event zeichnest du einfach nur noch jedes Element einzeln aus dieser Liste.
    Wenn du dann also einen Strahl hinzufügen möchtest fügst du einfach nur ein Ray-Objekt in diese List ein und rufst Invalidate auf, schon wird der neue Strahl gezeichnet.

    P.S.: du könntest deinem Ray auch Subrays geben, sodass ein einzelner Ray sogar die Brechungen durch seine eigenen Subrays beinhaltet.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    Brötchen29 schrieb:

    Bin ich auf dem richtigen Weg?
    Die korrekte Darstellung mit Paint steht oben in Post #3.
    Probiere das genau so aus, wie es da oben steht. Wenn Du es verstanden hast, erweitere den Code.
    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!

    Brötchen29 schrieb:

    Also, habe gerade nochmal probiert Eure Ansätze umzusetzen.
    Und dabei bist du nicht mal so weit gekommen, die von mir für erforderlich gehaltene Methode (s. post#2) in dein Form einzukopieren und aufzurufen?
    Kannst du nicht erkennen, wie diese Methode entscheidend beiträgt, das Problem zu fokussieren?

    Sie verlangt 2 Points, das Rectangle und den Brechungs-Index.
    Das sind genau die Parameter, die benötigt werden, um das Problem rechnerisch überhaupt anfassen zu können.
    Und das Problem muss rechnerisch gelöst sein, sonst kann eine Lösung logischerweise nicht angezeigt werden.

    Auch Rods Code hast du noch nicht geschafft, in dein Form einzupasten - das ist der Ansatz von der anderen Seite - dass überhaupt mal ein Rechteck gezeichnet wird.
    Stattdessen wartest du mit iwas aus dem INet auskopiertes auf, was es auch noch macht, wie mans genau nicht machen soll.

    Unsere Hilfe ist viel kleinschrittiger, einfach mal es ganz genau so machen, wie's dir vorgekaut wird, einkopieren, Testlauf, und dann ggfs. fragen, warum s nicht geht, wenn nicht geht.
    Aber wenn du dich selbst verrückt machst, mit allem aus dem INet, was dir in den Browser gerät, und dabei gleichzeitig die konkreten für dich gemachten Vorschläge garnicht ausprobierst, dann hast du schnell den Stempel "Beratungs-Resistent" weg, und grad kompetentere VBP-User halten es dann nicht mehr der Mühe für wert, auf deine Fragen einzugehen.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    @ErfinderdesRads, es tut mir leid falls ich bei dir den Eindruck geweckt habe, dass ich die Vorschläge ignorieren würde. Im Gegenteil, das ganze Umzsuetzen ist das erste was ich versucht habe, allerdings bin ich danach nicht weitergekommen. Ich kam mir ehrlich gesagt direkt nach dem scheitern etwas "blöd" vor, Euch mit der nächsten Kleinigkeit zu beschäftigen, daher habe ich erst einmal das Internet durchforstet. So kam halt eins auf das andere und dadurch bin ich wahrscheinlich vom Roten Pfaden abgekommen. Um das nochmal klar zu stellen, ich bin dankbar für jede Hilfe und es ist keinesfalls meine Absicht gewesen, die Vorschläge zu ignorieren bzw. ungetestet zu lassen.
    Ich möchte jeden Vorschlag beherzigen und überprüfen!

    Ich denke, das Hauptproblem liegt vor allem bei mir. Für mich sind Eure Codings noch nicht so selbstverständlich wie für Euch, ich muss nebenher immer viel nachlesen. Da kann es vielleicht auch sein, dass ich etwas falsch interpretiert und als logische Konsequenz etwas falsch umgesetzt habe.


    Ich werde mich der ganzen Sachen gleich morgen Früh wieder widmen. Ich bin auf jeden Fall sehr motiviert, die Aufgabenstellung bald zu Lösen! :)

    Brötchen29 schrieb:

    allerdings bin ich danach nicht weitergekommen. Ich kam mir ehrlich gesagt direkt nach dem scheitern etwas "blöd" vor, Euch mit der nächsten Kleinigkeit zu beschäftigen, daher habe ich erst einmal das Internet durchforstet.
    Das ist grad die nicht-zielführende Kommunikations-Strategie.
    Jo - es erfordert bischen Mut, blöd zu fragen, aber das muss man trotzdem, und ganz unbefangen. Kennst doch die Sprüche: "Es gibt keine dummen Fragen, es gibt nur dumme Antworten". Oder Sesamstrasse: "Wer nicht fragt bleibt dumm.", und's gibt noch mehr in die Richtung, und das hat seinen Grund, dasses davon so viel gibt.

    Und die Wirkung ist iwie komplett andersrum, als du dir vorstellst: Wenn du nachfragst, egal wie dumm, dann weiß ich, dass da ein Kontakt zustande kommt, und Interesse besteht.
    Wenn du gar kein Feedback gibst, dann nehme ich an, du hast dein Problem sonstwie gelöst - vlt. sogar mit meiner Hilfe, aber ohne es rückzumelden.
    Wenn du aber mit ieinem ganz anderen Sch... aus dem Internet ankommst, der ühaupt keinen Zusammenhang hat mit unserer bisherigen Kommunikation - ja, was denkst du, wie das bei mir ankommt?
    Ich gewinne da den starken Eindruck, ein Selbstgespräch geführt zu haben, so wie auch du nur Selbstgespräche führst, wenn du so agierst.
    Und das merk ich mir natürlich, weil statt Gespräche zu führen, die sich im Nachhinein als Selbstgespräch entpuppen - da pöbel ich doch lieber eine Oma auf der Strasse an - da kommt jdfs. was zurück.
    Ja du hast recht. Ich habe mich ja auch entschuldigt und das sollte auch nicht so rüberkommen. Vergessen wir das bitte einfach. Jetzt weiß ich ich, wie die Kommunikation in einem Forum funktioniert :D selbst in einem Forum war ich bisher noch nie aktiv :O

    lange gerade kurzer Sinn: werde morgen früh nochmal deine Posts durcharbeiten und dann Feedback geben !
    ErfinderDesRads, ich habe mich gerade nochmal in deinen Vorschlag reingedacht und mittlerweile macht es tatsächlich Sinn für mich ! :) Ich verstehe jetzt, was diese Methode bezwecken soll und das sie als "Teppich" für weiteres fungiert.

    Ich habe den Code jetzt bei mir eingebaut:
    [vbnet][
    Private Sub CalculateBeam(pt1 As Point, pt2 As Point, glasBlock As Rectangle, refractionIndex As Double)

    End Sub
    /vbnet]

    Jetzt stellt sich für mich schon die Frage: Wie gehts weiter? Jetzt muss ich ja sicher erstmal die Punkte und das Quadrat genauer Definieren damit diese überhaupt entstehen, oder? Das muss ich dann über seperate Klassen machen?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Brötchen29“ ()

    Brötchen29 schrieb:

    Wie gehts weiter?
    Hast Du bereits das vektorielle Brechungsgesetz implementiert?
    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!
    Ja, in dem Fall das Snelliussche Brechungsgesetz. Das steht weiter oben und gibt Teil I des Programms aus: Die tabellarische Ausgabe:

    VB.NET-Quellcode

    1. Dim bi = Convert.ToDouble(brechungsindex.Text)
    2. Dim kl = Convert.ToDouble(Kantenlaenge.Text)
    3. Dim ew = Convert.ToDouble(einfallwinkel.Text)
    4. Dim sine1 = (1 / bi) * Math.Sin(ew / 180 * Math.PI)
    5. Dim wi1 = Math.Round(Math.Asin(sine1) * 180 / Math.PI, 2)
    6. E1.Text = Convert.ToString(wi1)
    7. Dim wi2 = 90 - wi1
    8. E2.Text = Convert.ToString(wi2)
    9. Dim wi3 = 90 - wi2
    10. E3.Text = Convert.ToString(wi3)
    11. Dim wi4 = 90 - wi3
    12. E4.Text = Convert.ToString(wi4)
    13. Dim wi5 = 90 - wi4
    14. E5.Text = Convert.ToString(wi5)

    Brötchen29 schrieb:

    Brechungsgesetz
    in der Ebene.
    Bei einem Würfel, später mit Rotation, wird die vektorielle Form erforderlich.
    Diese ist auch wesentlich besser geeignet, Dein Strahlproblem zu beschreiben.
    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!