Physikalisch: Coulombkraft



  • Nein daran kanns nicht liegen, dx wird nie 0, sieht man aber auch nur, wenn man sich das ganze kompiliert anschaut. Somit wird r dann auch nie 0. Btw. würde dann das Programm abstürzen und ne Fehlermeldung kommen, oder?



  • Was hat das mit WinApi zu tun?



  • Ich wusste nicht genau wo ich es hinposten soll, hab dann WinAPI genommen, weil das Programm eben mit der WinAPI geschrieben ist und evt. dort irgendwo der Fehler vergraben ist...Wenn jemand anderer Meinung ist ➡ bitte verschieben 😉



  • du machst Haufenweise gdi-leaks:

    case WM_PAINT:
    
            hdc = BeginPaint(hWnd, &ps);
    
            SelectObject(hdc, CreateSolidBrush(RGB(0,0,255))); // BOOOMMM!!!
            Ellipse(hdc, targetX-5, targetY-5, targetX+5, targetY+5);
    
            SelectObject(hdc, CreateSolidBrush(RGB(255,0,0)));  // BOOOMMM!!!
            Ellipse(hdc, offsetX + (int)bulletX - 5, offsetY + (int)bulletY - 5, offsetX + (int)bulletX + 5, offsetY + (int)bulletY + 5);
    
            EndPaint(hWnd, &ps);
    
            return 0;
    

    du muss den Brush auch wieder entfernen: sowohl außem hdc als auch außem Speicher: DeleteObject(), sag ich nur!
    das is zwar nit die Lösung des problems, aber die sollte man trotzdem nit machen



  • Vermutlich wird die Lösung deiner Gleichung mit der Laufzeit infolge Fehlerfortpflanzung (besser: Ungenauigkeitsfortpflanzung) immer instabiler.

    Insbesondere Ausdrücke wie (0.5 * (Fx/0.001) * (t*t)), die dann im nächsten Durchlauf wiederum in Quadrierungen, atan() und sqrt() weiterverarbeitet werden und somit auf sich selbst zurückwirken, lassen das jedenfalls erwarten. Nur eine Vermutung...

    Walter Zorn



  • Hm, ja das ist ne Möglichkeit....wobei der Fehler ja erst so krass auftritt, wenn das Teilchen vollständig abgebremst wurde. Gibt es irgendwelche "genaueren" Datentypen, bei welchen das Runden vermieden wird?

    Das Problem mit den Speicherleaks ist mir eigentlich bekannt, ka wieso ich es vergessen hab. Danke für den Tipp.

    MfG



  • Evtl. die Gleichung so umstellen, dass nirgendwo als Zwischenergebnis betragsmäßig sehr kleine (<< 1.0) oder sehr große Werte auftreten? Falls nötig, sogar mehrere Versionen der Gleichung zur Vefügung stellen, die jeweils auf bestimmte Parametergrößen bzw. Zwischenergebnisse hin optimiert sind und entsprechend aufgerufen werden?

    Ich kann mir aber irgendwie nicht vorstellen, dass so etwas in der Facharbeit erwartet wird...

    Ups, sorry, inzwischen ziemlich offtopic.

    Walter Zorn



  • Also in die Facharbeit muss ein praktischer Teil mit rein. Da mein Thema nun mal Kernfusion ist und ich schlecht eine Fusion herstellen kann 😉 hab ich beschlossen eine Simulation zu programmieren.
    Ich hab nun auch mal den Datentyp long double ausprobiert, hilft aber auch nichts. Ich denk mir wird nichts anderes übrig bleiben also wirklich alles zu erweitern bis keine Kommazahlen mehr rauskommen...

    Vielen Dank für die Hilfe, ich meld mich nochmal 😉



  • Hi,

    Ich hoffe ihr habt den Thread noch nicht vergessen 🙂

    Ich glaube langsam nicht mehr dran, dass es an den Rundungsfehlern liegt...Ich weiß nimmer was ich machen soll, ich habs in Flash (Actionscript) probiert, ich habs in C probiert, ich habs in Pascal probiert und immer mit den aller größten Datentypen (long double/extended)...irgendwas muss an der Formel nicht stimmen schätz ich mal, ich kann mirs echt anders nimmer erklären...Bitte helft mir 🙂 Ich muss die Facharbeit in 3 Wochen abgeben und da muss alles funktionieren....

    MfG



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum WinAPI in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • hi,

    schmeiß mal den winkel raus: du kannst das ganze viel schöner rein vektoriell machen. es kann sein, dass bei kleinen geschwindigkeiten dy/dx nicht mehr viel mit dem "echten" winkel zu tun hat. obs aber wirklich daran liegt kann ich natürlich nicht sagen 😉



  • Edit: Hier stand Mist.



  • Herr-Vorragend schrieb:

    static UINT		offsetX, offsetY;
    	static UINT		targetX, targetY;
    
    //...
    
    	bulletX = offsetX + speedX*t	- (0.5 * (Fx/0.001) * (t*t));
    	bulletY = offsetY + speedY*t	- (0.5 * (Fy/0.001) * (t*t));
    

    Kann es vieleicht sein, das das Ergebnis aus

    speedX*t - (0.5 * (Fx/0.001) * (t*t))
    

    nach UINT (OffsetX & OffsetY) konvertiert und somit (vorzeichenlos) gerundet wird?

    Probiers mal mit

    bulletX = (double)offsetX + speedX*t	- (0.5 * (Fx/0.001) * (t*t));
    	bulletY = (double)offsetY + speedY*t	- (0.5 * (Fy/0.001) * (t*t));
    

    oder mit:

    bulletX = ( speedX*t	- (0.5 * (Fx/0.001) * (t*t)) ) + (double)offsetX;
    	bulletY = ( speedY*t	- (0.5 * (Fy/0.001) * (t*t)) ) + (double)offsetY;
    


  • Herr-Vorragend schrieb:

    case WM_TIMER:
    
    		dx = targetX - bulletX;
    		dy = targetY - bulletY;
    
    		alpha = atan(dy/dx);
    
    		r = sqrt(dx*dx + dy*dy);
    
    		F = 1/(r*r);
    
    		Fx = cos(alpha)*F;
    		Fy = sin(alpha)*F;
    
    		bulletX = offsetX + speedX*t	- (0.5 * (Fx/0.001) * (t*t));
    		bulletY = offsetY + speedY*t	- (0.5 * (Fy/0.001) * (t*t));
    		t++;
    
    		InvalidateRect(hWnd, NULL, TRUE);
    
    		return 0;
    

    Ok, mal gucken. Das läuft also schrittweise. In jedem Schritt berechnest Du die momentane relative Position zwischen den beiden Teilchen, dann den momentanen Winkel. dann die momentane Kraft. So, jetzt kommt es Du zählst die Zeit immer weiter hoch. Das heißt, Du lässt die Kraft, die du für einen bestimmten Zeitpunkt berechnet hast, über die gesamte Zeit wirken. Dein Algorithmus soll offensichtlich plötzlich nichtmehr schrittweise funktionieren, sondern stattdessen willst Du einfach die Zeit in eine vorbereitete Formel einsetzen. Da vermischt Du zwei Dinge, die IMHO so nicht zu vermischen sind. Entweder Du musst die Trajektorie komplett vorher berechnen und dann nur noch die Zeit einsetzen oder Du musst komplett schrittweise arbeiten.



  • Und bitte nicht hau deine Algorithmen nicht in den GUI-Code. Das ist ja schrecklich.



  • @Gregor: Ich glaub du hast wirklich Recht, ich hab die Sache mit der Kraft zu sehr vereinfacht...Am einfachsten wär es glaub ich zu der Position ständig etwas hinzuzuaddieren, also so ne Art Momentangeschwindigkeit*Zeitintervall...Nur wie kann ich in diesem Fall die Momentangeschwindigkeit errechnen? Die hängt ja auch von der Kraft ab...KAnn mir da jemand helfen?

    Schonmal Tausend Dank für die Tipps!



  • Ich hätte da einen Ansatz, aber damit auch ein Problem 🙂

    Also, ich hab mir gedacht, ich mach einfach eine Endlosschleife und addiere in jedem Durchlauf eine Strecke zur Position des Protons hinzu. Diese ergibt sich durch s = v*t wobei v die Momentangeschwindigkeit ist, die bei jedem Schleifendurchlauf aufgrund des sich ändernden Abstandes variiert. t ist das "Aktualisierungsintervall". Nur wie komm ich an die Momentangeschwindigkeit?

    Dazu hab ich mir gedacht, dass das Proton im unendlichen eine kinetische Energie E_kin hat und diese nach und nach in potentielle (elektrische) Energie umgewandelt wird. Also dann

    Epot+Ekin=EkinE_{pot} + E_{kin}^{'} = E_{kin}

    Nach Einsetzen und Auflösen nach v in E_kin' ergibt sich dann:

    v = \sqrt{\frac{2(E_{kin} - \frac{Q_{1}\*Q_{2}}{4\*\pi*\epsilon_{0}*r})}{m}}

    Ich hoffe da steckt bisher kein Fehler drin und der Ansatz ist richtig...Wenn nicht bitte melden! 🙂

    Nun ist das Problem, das das ganze zwar schön abgebremst wird, aber das Proton bewegt sich wenn es stehen geblieben ist nicht in die andere Richtung bleibt einfach wo es ist, was ja klar ist, weil E_pot = E_kin und sich das so schnell mit dieser Formel nicht ändert...

    Steckt jetzt ein Fehler in meinem Ansatz oder muss ich nur was ergänzen?

    MfG, Herr-Vorragend (für jede Hilfe dankbar)



  • hi,

    grob gesagt fehlt die trägheit des teilchens. die 0-8-15-lösung sieht so aus:

    Fneu = q1 q2q / ( bla* r2)
    aneu = Fneu/m
    vneu = valt + Δtaneu
    xneu = xalt + Δt
    vneu

    wobei f,a,v,x vektorielle größen sind und jeweils eine x- und eine y-komponente haben. (die formeln gelten für jede komponente einzeln, bis auf die erste: da musst du für r pythagoras benutzen.)

    @gregor:
    wieso mist? ich dachte, das, was du gepostet hast, benutzt man auch für numerische integration 😕



  • 4db814f0-13ac-4521-a7e4-1 schrieb:

    @gregor:
    wieso mist? ich dachte, das, was du gepostet hast, benutzt man auch für numerische integration 😕

    Was ich da in dem einen Beitrag geschrieben habe, hatte nichts mit dem Problem hier zu tun. Ich hatte das geschrieben, ohne den Sourcecode überhaupt anzugucken oder den entsprechenden Beitrag wirklich zu lesen. Hatte einfach mal auf einen Fehler getippt und eine Lösung für das entsprechende Problem beschrieben. Es hat sich hier aber doch um ein anderes Problem gehandelt, was ich dann kurz danach festgestellt habe. 🙄

    Mit "Mist" meinte ich da also, dass es an der Stelle nicht in den Thread gepasst hat.


Anmelden zum Antworten