Erstmal Hallo an alle, die sich hierher verirrt haben
ich habe mir gedacht, dass es doch bestimmt ganz witzig wäre, am PC ein Chaos-Pendel zu simulieren
(vor allem, weil mein Physik-Lehrer gemeint hat, dass es nicht möglich sei, die Position des Pendels zu einem bestimmten Zeitpunkt zu ermitteln)
Mein simuliertes Pendel besteht in diesem Fall aus einem Gewicht, welches über eine Feder mit der Decke verbunden ist, und schwingen kann (auf der Ebene, also nicht nach vorne und hinten)
nun lenkt man das Pendel aus und lässt es los -> wir haben hier verschiedene Kräfte (naja eigentlich ja 2: Gewichtskraft und Federkraft...)
da ich selbst mit GDI+ nicht wirklich bewandert bin (habs gestern zum 1.mal gehört...) und auch gerne wüsste, ob mir nicht bei der Berechnung ein dummer Fehler unterlaufen ist,
wär's cool, wenn ihr (v.a. GDI+ Kenner & Physikbewanderte) euch das mal anschauen könntet + evtl. Verbesserungsvorschläge bringen oder Fehler aufzeigen
achja: die decke ist natürlich nur gedacht (im Programm als x-Achse dargestellt, ansatzpunkt der feder an der decke ist (0|0) - das pendel kann auch drüber schwingen - vllt bau ich iwann noch ne abprallfunktion ein... aber im moment gehts noch durch
V1.10: Ich habe jetzt 3 Graphen hinzugefügt (anzeigbar und wieder versteckbar mit [Strg]+[G]: ein x-t, ein y-t und ein e-t Schaubild (e: Auslenkung der Feder aus der entspannten Lage))
es empfiehlt isch aber momentan noch, dass ganze erst bisschen ohne die Graphen laufen zu lassen und sie dann anzuzeigen...
hat wer ne idee, wie man das vllt so ändern könnte, dass es etwas schneller abläuft?
V1.11: Die Graphen wurden bei Zurücksetzen nicht zurückgesetzt... das werden sie zum Glüück jetzt
V1.12: Hab versucht, das Script bissle zu optimieren Wenn der Graph ausgeschaltet ist, zeichnet es jetzt mehr als doppelt so schnell wie in V1.11
(genauer hab ich eine steigerung von 1323 auf 2960 Zeitschritte / Minute gemessen - d.h. Steigerung im 1637 Zeitschritte / Min vllt hat noch wer optimierungsideen?)
Danke schonmal und hier kommt jetzt noch der Code: (aktualisiert: v1.12)
(Achtung: knapp 800 Zeilen)
Spoiler anzeigen
#cs ----------------------------------------------------------------------------
[/autoit] [autoit][/autoit] [autoit]AutoIt Version: 3.3.6.1
Author: fr34q
Script Function:
Simulates an chaotic pendulum. (? in German: Chaos-Pendel)
#ce ----------------------------------------------------------------------------
[/autoit] [autoit][/autoit] [autoit]#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Array.au3> ; nur für Debug
#include <WinApi.au3>
$SCRIPT_VERSION = "1.12"
[/autoit] [autoit][/autoit] [autoit]$D_WIDTH = 900
$D_HEIGHT = 700
$G_WIDTH = 700
$G_HEIGHT = 700
Global $GUIGraph = 0
$GG_WIDTH = 700 ; Breite eines Schaubilds
$GG_HEIGHT = 200 ; Höhe eines Schaubilds
$DG_WIDTH = $GG_WIDTH+20
$DG_HEIGHT = 3*(30+$GG_HEIGHT)+10
$SCALE_FACTOR = 200 ; 1m -> 200px (1cm -> 2px)
$TIME_FACTOR = 0.01 ; sec Schritte
$PI=3.1415926535897932384626433832795
[/autoit] [autoit][/autoit] [autoit]$TRACE = True
$SHOWTRACE= True
$MOVEACTIVE = True
$MAKEGRAPH = False
Dim $NULL[2] ; Nullpunkt festlegen
$NULL[0] = $G_WIDTH/2 ; X
$NULL[1] = 50 ; Y
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]#region Physikalische Variablen/Konstanten
$FEDER_D = 20 ; N/m - Federhärte
$FEDER_S = .2 ; m - Feder entspannt
$OBJKT_M = .5 ; kg - Masse des Objekts
$UMGEB_G = 9.8 ; m/s² - Erdbeschleunigung
$FEDER_S0 = $FEDER_S+$OBJKT_M*$UMGEB_G/$FEDER_D ; Nur mit x Auslenkung = 0 ; wird eigentlich auch nicht gebraucht
[/autoit] [autoit][/autoit] [autoit]Dim $STARTPOS[2]
$STARTPOS[0] = 0.3
$STARTPOS[1] = -$FEDER_S-.5
Dim $POS[2] ; Position des Chaos-Pendels
$POS[0] = $STARTPOS[0] ; X
$POS[1] = $STARTPOS[1] ; Y
Dim $SPEED[2] ; Geschw.keitsvektor in m/s
$SPEED[0] = 0
$SPEED[1] = 0
Dim $BESCHL[2] ; m/s²
$BESCHL[0] = 0
$BESCHL[1] = 0
$TIME = 0 ; s
#endregion
;Graphen
Global $hGr_Fb_Graph ; Frontbuffer für die Graphen
Dim $hBitmap_Bb_Graph[4] ; Backbuffer für die Graphen
Dim $hGr_Bb_Graph[4]
; Wertetabelle der Graphen
Dim $aGraph[4][Int($GG_WIDTH)+1][2] ; [a][b][code=c] -> a: Nummer des Graphen, b: Stelle des Graphen, c: 0 - Zeit, 1 - Wert
$aGraph[0][0][0] = Int($GG_WIDTH) ; Anzahl Stellen
$aGraph[0][0][1] = 1 ; Momentan zu beschreibende Stelle -> zählt hoch
;[a][0][code=c] -> c: 0 - Minimaler Wert, 1 - scale
For $g=1 To 3
$aGraph[$g][0][0] = 0
$aGraph[$g][0][1] = 0
For $i=1 To $aGraph[0][0][0]
$aGraph[$g][$i][0] = -($aGraph[0][0][0]-$i+1)*$TIME_FACTOR
$aGraph[$g][$i][1] = 0
Next
Next
; Physikalische Größen
Global $VAR_DELTA, $VAR_L, $VAR_S0
;Backup-Vars
$bFEDER_D = $FEDER_D
$bFEDER_S = $FEDER_S
$bOBJKT_M = $OBJKT_M
$bUMGEB_G = $UMGEB_G
$bTIME_FACTOR = $TIME_FACTOR
$bSCALE_FACTOR = $SCALE_FACTOR
Dim $bNULL[2]
$bNULL[0] = $NULL[0]
$bNULL[1] = $NULL[1]
Dim $bPOS[2]
$bPOS[0] = $POS[0]
$bPOS[1] = $POS[1]
Dim $bSPEED[2]
$bSPEED[0] = $SPEED[0]
$bSPEED[1] = $SPEED[1]
$bTRACE = $TRACE
$bSHOWTRACE = $SHOWTRACE
$bMOVEACTIVE = $MOVEACTIVE
$bMAKEGRAPH = $MAKEGRAPH
$winactive = True
$run = False
$arun = Not $run
Dim $apos[2]
$apos[0] = $POS[0]
$apos[1] = $POS[1]
Dim $apos2[2]
$apos2[0] = $POS[0]
$apos2[1] = $POS[1]
Dim $abeschl[2]
Dim $aspeed[2]
$atime=$TIME
$amakegraph = $MAKEGRAPH
Dim $anull[2]
$anull[0] = $NULL[0]-1
$anull[1] = $NULL[1]-1
$ascfact = $SCALE_FACTOR-1
$atime2 = $TIME
$hPen_Trace = _GDIPlus_PenCreate(0xFF0000FF, 2)
Dim $hPen_Graph[4]
$hPen_Graph[1] = _GDIPlus_PenCreate(0xFFFF0000, 1)
$hPen_Graph[2] = _GDIPlus_PenCreate(0xFF00FF00, 1)
$hPen_Graph[3] = _GDIPlus_PenCreate(0xFF00FFFF, 1)
Global $GUI = GUICreate("ChaosPendel v"&$SCRIPT_VERSION&" - Autor: fr34q",$D_WIDTH,$D_HEIGHT)
[/autoit] [autoit][/autoit] [autoit]GUICtrlCreateLabel("Federhärte D: [N/m]",$G_WIDTH+10,10)
$gui_inp_FederD=GUICtrlCreateInput($FEDER_D,$G_WIDTH+10,30,$D_WIDTH-$G_WIDTH-20,20)
GUICtrlCreateLabel("Länge Feder entspannt: [m]",$G_WIDTH+10,60)
$gui_inp_FederS=GUICtrlCreateInput($FEDER_S,$G_WIDTH+10,80,$D_WIDTH-$G_WIDTH-20,20)
GUICtrlCreateLabel("Masse m: [kg]",$G_WIDTH+10,110)
$gui_inp_ObjktM=GUICtrlCreateInput($OBJKT_M,$G_WIDTH+10,130,$D_WIDTH-$G_WIDTH-20,20)
GUICtrlCreateLabel("Erdbeschleunigung g: [m/s²]",$G_WIDTH+10,160)
$gui_inp_UmgebG=GUICtrlCreateInput($UMGEB_G,$G_WIDTH+10,180,$D_WIDTH-$G_WIDTH-20,20)
GUICtrlCreateLabel("Zeitschritt: [s]",$G_WIDTH+10,210)
$gui_inp_TFact=GUICtrlCreateInput($TIME_FACTOR,$G_WIDTH+10,230,$D_WIDTH-$G_WIDTH-20,20)
GUICtrlCreateLabel("Achsen-Skalierung: [px/m]",$G_WIDTH+10,260)
$gui_inp_ScFact=GUICtrlCreateInput($SCALE_FACTOR,$G_WIDTH+10,280,$D_WIDTH-$G_WIDTH-20,20)
GUICtrlCreateLabel("Nullpunkt: [px]",$G_WIDTH+10,310)
$gui_inp_Null0=GUICtrlCreateInput($NULL[0],$G_WIDTH+10,330,int(($D_WIDTH-$G_WIDTH-30)/2),20)
$gui_inp_Null1=GUICtrlCreateInput($NULL[1],$G_WIDTH+20+int(($D_WIDTH-$G_WIDTH-30)/2),330,int(($D_WIDTH-$G_WIDTH-30)/2),20)
$gui_chk_trace=GUICtrlCreateCheckbox("Spur zeichnen",$G_WIDTH+10,360)
If $TRACE Then GUICtrlSetState(-1,$GUI_CHECKED)
$gui_chk_showtrace=GUICtrlCreateCheckbox("Spur anzeigen",$G_WIDTH+20+int(($D_WIDTH-$G_WIDTH-30)/2),360)
If $SHOWTRACE Then GUICtrlSetState(-1,$GUI_CHECKED)
$gui_chk_moveactive=GUICtrlCreateCheckbox("Nur wenn aktiv bewegen",$G_WIDTH+10,390)
If $MOVEACTIVE Then GUICtrlSetState(-1,$GUI_CHECKED)
GUICtrlCreateLabel("Zeit t: [s]",$G_WIDTH+10,$D_HEIGHT-280)
$gui_inp_time=GUICtrlCreateInput(StringFormat("%.3f",$TIME),$G_WIDTH+10,$D_HEIGHT-260,$D_WIDTH-$G_WIDTH-20,20)
GUICtrlSetState(-1,$GUI_DISABLE)
GUICtrlCreateLabel("Position: [m]",$G_WIDTH+10,$D_HEIGHT-230)
$gui_inp_pos0=GUICtrlCreateInput($POS[0],$G_WIDTH+10,$D_HEIGHT-210,int(($D_WIDTH-$G_WIDTH-30)/2),20)
$gui_inp_pos1=GUICtrlCreateInput($POS[1],$G_WIDTH+20+int(($D_WIDTH-$G_WIDTH-30)/2),$D_HEIGHT-210,int(($D_WIDTH-$G_WIDTH-30)/2),20)
GUICtrlCreateLabel("Geschwindigkeit: [m/s]",$G_WIDTH+10,$D_HEIGHT-180)
$gui_inp_speed0=GUICtrlCreateInput($SPEED[0],$G_WIDTH+10,$D_HEIGHT-160,int(($D_WIDTH-$G_WIDTH-30)/2),20)
$gui_inp_speed1=GUICtrlCreateInput($SPEED[1],$G_WIDTH+20+int(($D_WIDTH-$G_WIDTH-30)/2),$D_HEIGHT-160,int(($D_WIDTH-$G_WIDTH-30)/2),20)
GUICtrlCreateLabel("Beschleunigung: [m/s²]",$G_WIDTH+10,$D_HEIGHT-130)
$gui_inp_beschl0=GUICtrlCreateInput($BESCHL[0],$G_WIDTH+10,$D_HEIGHT-110,int(($D_WIDTH-$G_WIDTH-30)/2),20)
GUICtrlSetState(-1,$GUI_DISABLE)
$gui_inp_beschl1=GUICtrlCreateInput($BESCHL[1],$G_WIDTH+20+int(($D_WIDTH-$G_WIDTH-30)/2),$D_HEIGHT-110,int(($D_WIDTH-$G_WIDTH-30)/2),20)
GUICtrlSetState(-1,$GUI_DISABLE)
$gui_btn_reset=GUICtrlCreateButton("Zurücksetzen",$G_WIDTH+10,$D_HEIGHT-80,$D_WIDTH-$G_WIDTH-20,30)
$gui_btn_start=GUICtrlCreateButton("Starten",$G_WIDTH+10,$D_HEIGHT-40,$D_WIDTH-$G_WIDTH-20,30)
GUISetState(@SW_SHOW,$GUI)
[/autoit] [autoit][/autoit] [autoit]$hGr_Frontbuffer = _GDIPlus_GraphicsCreateFromHWND($GUI)
[/autoit] [autoit][/autoit] [autoit]$hBitmap_Backbuffer = _GDIPlus_BitmapCreateFromGraphics($G_WIDTH, $G_HEIGHT, $hGr_Frontbuffer)
$hGr_Backbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap_Backbuffer)
$hBitmap_Backbuffer2 = _GDIPlus_BitmapCreateFromGraphics($G_WIDTH, $G_HEIGHT, $hGr_Frontbuffer)
$hGr_Backbuffer2 = _GDIPlus_ImageGetGraphicsContext($hBitmap_Backbuffer2)
$hBitmap_BackbufferAx = _GDIPlus_BitmapCreateFromGraphics($G_WIDTH, $G_HEIGHT, $hGr_Frontbuffer)
$hGr_BackbufferAx = _GDIPlus_ImageGetGraphicsContext($hBitmap_BackbufferAx)
_GDIPlus_GraphicsSetSmoothingMode($hGr_Backbuffer, 4)
_GDIPlus_GraphicsSetSmoothingMode($hGr_Backbuffer2, 4)
DrawAxis()
DrawGraphic()
If $MAKEGRAPH Then CreateGraphGUI()
[/autoit] [autoit][/autoit] [autoit]HotKeySet("^q","ende")
HotKeySet("^g","ToggleGraphGUI")
HotKeySet("^d","Debug")
While 1
Switch GUIGetMsg($GUI)
Case $gui_btn_start
If Not $run Then
$run = True
Else
$run = False
EndIf
Case $gui_btn_reset
$run=False
$arun=True
$SPEED[0]=0
$SPEED[1]=0
$TIME=0
$POS[0]=$STARTPOS[0]
$POS[1]=$STARTPOS[1]
$apos2[0]=$POS[0]
$apos2[1]=$POS[1]
$BESCHL[0]=0
$BESCHL[1]=0
$ascfact = $SCALE_FACTOR-1
_GDIPlus_GraphicsClear($hGr_Backbuffer2, 0x00FFFFFF)
For $g=1 To 3
$aGraph[$g][0][0] = 0
$aGraph[$g][0][1] = 0
For $i=1 To $aGraph[0][0][0]
$aGraph[$g][$i][0] = -($aGraph[0][0][0]-$i+1)*$TIME_FACTOR
$aGraph[$g][$i][1] = 0
Next
Next
Case -3
ende()
EndSwitch
If $MAKEGRAPH = Not $amakegraph Then
If $MAKEGRAPH Then CreateGraphGUI()
If Not $MAKEGRAPH Then DeleteGraphGUI()
$amakegraph = $MAKEGRAPH
EndIf
If $MAKEGRAPH Then
Switch GUIGetMsg($GUIGraph)
Case -3
ToggleGraphGUI()
EndSwitch
EndIf
If (($run=True Or $arun<>$run) And (WinActive($GUI) Or Not $MOVEACTIVE)) Then
;If ($arun<>$run) Then DrawAxis() ; Achsen laden
RefreshDisplay()
DrawGraphic()
If $MAKEGRAPH Then RefreshGraph()
ElseIf (WinActive($GUI) And Not $winactive) Then
RefreshDisplay()
DrawAxis()
DrawGraphic()
If $MAKEGRAPH Then RefreshGraph()
EndIf
$winactive = WinActive($GUI)
[/autoit] [autoit][/autoit] [autoit]If $run And $TIME>0 And Round($SPEED[0],5)=0 And Round($SPEED[1],5)=0 And Round($POS[0],5)=Round($STARTPOS[0],5) And Round($POS[1],5)=Round($STARTPOS[1],5) Then
$run=False
MsgBox(-1,"Momentane Position & Geschwindigkeit gleich wie am Anfang!","Zeit: "&$TIME&@CRLF&"Position: "&Round($POS[0],10)&" , "&Round($POS[1],10)&@CRLF _
&"Anfangspos.: "&Round($STARTPOS[0],10)&" , "&Round($STARTPOS[1],10)&@CRLF _
&"Geschwindigkeit: "&Round($SPEED[0],10)&" , "&Round($SPEED[1],10)&@CRLF _
&"Anfangsgeschw.: 0 , 0")
EndIf
If $run And ($winactive Or Not $MOVEACTIVE) Then
;ToolTip("Zeit: "&$TIME&@CRLF&"Geschw.1: "&$SPEED[0]&@CRLF&"Geschw.2: "&$SPEED[1]&@CRLF&"Beschl.1: "&$BESCHL[0]&@CRLF&"Beschl.2: "&$BESCHL[1]&@CRLF&"Pos.X: "&$POS[0]&@CRLF&"Pos.Y: "&$POS[1],0,0,"Chaos-Pendel")
;DrawGraphic()
;ConsoleWrite("Zeit: "&$TIME&@CRLF&"Geschw.1: "&$SPEED[0]&@CRLF&"Geschw.2: "&$SPEED[1]&@CRLF&"Beschl.1: "&$BESCHL[0]&@CRLF&"Beschl.2: "&$BESCHL[1]&@CRLF&"Pos.X: "&$POS[0]&@CRLF&"Pos.Y: "&$POS[1]&@CRLF&"==========="&@CRLF)
SetPhysVars()
[/autoit] [autoit][/autoit] [autoit]$BESCHL = GetA()
[/autoit] [autoit][/autoit] [autoit]$SPEED[0] += $BESCHL[0]*$TIME_FACTOR
$SPEED[1] += $BESCHL[1]*$TIME_FACTOR
$POS[0] += $SPEED[0]*$TIME_FACTOR
$POS[1] += $SPEED[1]*$TIME_FACTOR
GraphSetNewValue(1,$TIME,$POS[0]) ; x-t-Schaubild)
GraphSetNewValue(2,$TIME,$POS[1]) ; y-t-Schaubild)
GraphSetNewValue(3,$TIME,$VAR_L-$FEDER_S) ; e-t-Schaubild)
;ToolTip(GetEnergieGesamt(),0,0,"Gesamtenergie in J")
[/autoit] [autoit][/autoit] [autoit]$TIME += Round($TIME_FACTOR,3)
[/autoit] [autoit][/autoit] [autoit];Sleep(1000*$TIME_FACTOR)
Else
If CheckInputs() Then
BackupVars()
InputsToVars()
If Not CompBackupVars() Then
DrawAxis()
DrawGraphic()
EndIf
If BitAND(GUICtrlGetState($gui_btn_start),$GUI_DISABLE) Then GUICtrlSetState($gui_btn_start,$GUI_ENABLE)
Else
If BitAND(GUICtrlGetState($gui_btn_start),$GUI_ENABLE) Then GUICtrlSetState($gui_btn_start,$GUI_DISABLE)
EndIf
EndIf
WEnd
#region Positions-Funktionen (Ausgabe in px, Eingabe in m)
Func GetXPos($_pos="...")
If $_pos="..." Then $_pos=$POS[0]
Return Round($NULL[0]+$_pos*$SCALE_FACTOR,0)
EndFunc
Func GetYPos($_pos="...")
If $_pos="..." Then $_pos=$POS[1]
Return Round($NULL[1]-$_pos*$SCALE_FACTOR,0)
EndFunc
#endregion
#region Physikalische Größen-Bestimmung
Func SetPhysVars()
$VAR_L = sqrt($POS[0]^2+$POS[1]^2)
If $POS[1]>0 Then
$VAR_DELTA = $PI+ATan($POS[0]/$POS[1])
Else
$VAR_DELTA = ATan($POS[0]/$POS[1]);ASin($POS[0]/GetL())
EndIf
$VAR_S0 = $FEDER_S + Cos($VAR_DELTA)*$OBJKT_M*$UMGEB_G/$FEDER_D
EndFunc
#cs Veraltet wegen SetPhysVars()
Func GetL()
Return sqrt($POS[0]^2+$POS[1]^2)
EndFunc
Func Getdelta()
If $POS[1]>0 Then
Return $PI+ATan($POS[0]/$POS[1])
Else
Return ATan($POS[0]/$POS[1]);ASin($POS[0]/GetL())
EndIf
EndFunc
Func GetS0()
Return $FEDER_S + Cos(Getdelta())*$OBJKT_M*$UMGEB_G/$FEDER_D
EndFunc
#ce
#endregion
#region wirkende Kräfte
#cs ausgebaut, solang nicht separiert benötigt, in GetA() zusammengefasst
Func GetForce()
$forceG = GetFG()
$forceF = GetFF()
Dim $array[2]
$array[0] = $forceG[0]+$forceF[0]
$array[1] = $forceG[1]+$forceF[1]
Return $array
EndFunc
Func GetFG()
Dim $array[2]
$array[0]=0
$array[1]=-$OBJKT_M*$UMGEB_G
Return $array
EndFunc
Func GetFF()
Dim $array[2]
$array[0]=Sin($VAR_DELTA)*$FEDER_D*($VAR_L-$FEDER_S)
$array[1]=Cos($VAR_DELTA)*$FEDER_D*($VAR_L-$FEDER_S)
Return $array
EndFunc
#ce
#endregion
#region Beschleunigung
Func GetA()
Dim $array[2]
;$force = GetForce()
$array[0] = (Sin($VAR_DELTA)*$FEDER_D*($VAR_L-$FEDER_S)) / $OBJKT_M ;$force[0] / $OBJKT_M
$array[1] = (Cos($VAR_DELTA)*$FEDER_D*($VAR_L-$FEDER_S)-$OBJKT_M*$UMGEB_G) / $OBJKT_M ;$force[1] / $OBJKT_M
Return $array
EndFunc
#endregion
#region Energie Funktionen
#cs solang nicht separiert benötigt, in GetEnergieGesamt() zusammengefasst
Func GetEnergieLage()
Return $OBJKT_M*$UMGEB_G*$POS[1]
EndFunc
Func GetEnergieBewegung()
Return 0.5*$OBJKT_M*($SPEED[0]^2+$SPEED[1]^2)
EndFunc
Func GetEnergieSpann()
Return 0.5*$FEDER_D*($VAR_L-$FEDER_S)^2
EndFunc
#ce
Func GetEnergieGesamt()
Return $OBJKT_M*$UMGEB_G*$POS[1] + 0.5*$OBJKT_M*($SPEED[0]^2+$SPEED[1]^2) + 0.5*$FEDER_D*($VAR_L-$FEDER_S)^2 ;GetEnergieLage()+GetEnergieBewegung()+GetEnergieSpann()
EndFunc
#endregion
#region Anzeige-Funktionen
Func RefreshDisplay()
If $abeschl[0]<>$BESCHL[0] Then GUICtrlSetData($gui_inp_beschl0,round($BESCHL[0],10))
If $abeschl[1]<>$BESCHL[1] Then GUICtrlSetData($gui_inp_beschl1,round($BESCHL[1],10))
If $aspeed[0]<>$SPEED[0] Then GUICtrlSetData($gui_inp_speed0,round($SPEED[0],10))
If $aspeed[1]<>$SPEED[1] Then GUICtrlSetData($gui_inp_speed1,round($SPEED[1],10))
If $apos[0]<>$POS[0] Then GUICtrlSetData($gui_inp_pos0,round($POS[0],10))
If $apos[1]<>$POS[1] Then GUICtrlSetData($gui_inp_pos1,round($POS[1],10))
If $atime<>$TIME Then GUICtrlSetData($gui_inp_time,StringFormat("%.3f",$TIME))
$abeschl[0]=$BESCHL[0]
$abeschl[1]=$BESCHL[1]
$aspeed[0]=$SPEED[0]
$aspeed[1]=$SPEED[1]
$apos[0]=$POS[0]
$apos[1]=$POS[1]
$atime=$TIME
If $arun <> $run Then
Switch $run
Case True
GUICtrlSetData($gui_btn_start,"Anhalten")
GUICtrlSetState($gui_inp_speed0,$GUI_DISABLE)
GUICtrlSetState($gui_inp_speed1,$GUI_DISABLE)
GUICtrlSetState($gui_inp_pos0,$GUI_DISABLE)
GUICtrlSetState($gui_inp_pos1,$GUI_DISABLE)
GUICtrlSetState($gui_inp_Null0,$GUI_DISABLE)
GUICtrlSetState($gui_inp_Null1,$GUI_DISABLE)
GUICtrlSetState($gui_inp_ScFact,$GUI_DISABLE)
GUICtrlSetState($gui_inp_TFact,$GUI_DISABLE)
GUICtrlSetState($gui_inp_UmgebG,$GUI_DISABLE)
GUICtrlSetState($gui_inp_ObjktM,$GUI_DISABLE)
GUICtrlSetState($gui_inp_FederS,$GUI_DISABLE)
GUICtrlSetState($gui_inp_FederD,$GUI_DISABLE)
GUICtrlSetState($gui_chk_trace,$GUI_DISABLE)
GUICtrlSetState($gui_chk_showtrace,$GUI_DISABLE)
GUICtrlSetState($gui_chk_moveactive,$GUI_DISABLE)
Case False
GUICtrlSetData($gui_btn_start,"Starten")
GUICtrlSetState($gui_inp_speed0,$GUI_ENABLE)
GUICtrlSetState($gui_inp_speed1,$GUI_ENABLE)
GUICtrlSetState($gui_inp_pos0,$GUI_ENABLE)
GUICtrlSetState($gui_inp_pos1,$GUI_ENABLE)
GUICtrlSetState($gui_inp_Null0,$GUI_ENABLE)
GUICtrlSetState($gui_inp_Null1,$GUI_ENABLE)
GUICtrlSetState($gui_inp_ScFact,$GUI_ENABLE)
GUICtrlSetState($gui_inp_TFact,$GUI_ENABLE)
GUICtrlSetState($gui_inp_UmgebG,$GUI_ENABLE)
GUICtrlSetState($gui_inp_ObjktM,$GUI_ENABLE)
GUICtrlSetState($gui_inp_FederS,$GUI_ENABLE)
GUICtrlSetState($gui_inp_FederD,$GUI_ENABLE)
GUICtrlSetState($gui_chk_trace,$GUI_ENABLE)
GUICtrlSetState($gui_chk_showtrace,$GUI_ENABLE)
GUICtrlSetState($gui_chk_moveactive,$GUI_ENABLE)
EndSwitch
$arun=$run
EndIf
EndFunc
Func DrawGraphic()
_GDIPlus_GraphicsClear($hGr_Backbuffer, 0xFFFFFFFF)
If $TRACE Then DrawTrace()
If $SHOWTRACE Then _GDIPlus_GraphicsDrawImage($hGr_Backbuffer, $hBitmap_Backbuffer2, 0, 0)
; Achse
_GDIPlus_GraphicsDrawImage($hGr_Backbuffer, $hBitmap_BackbufferAx, 0, 0)
_GDIPlus_GraphicsDrawEllipse($hGr_Backbuffer,GetXPos()-10,GetYPos()-10,20,20)
_GDIPlus_GraphicsDrawLine($hGr_Backbuffer,$NULL[0],$NULL[1],GetXPos(),GetYPos())
_GDIPlus_GraphicsDrawImage($hGr_Frontbuffer, $hBitmap_Backbuffer, 0, 0)
EndFunc
Func DrawAxis()
_GDIPlus_GraphicsClear($hGr_BackbufferAx, 0x00FFFFFF)
;X-Achse
_GDIPlus_GraphicsDrawLine($hGr_BackbufferAx,10,$NULL[1],$G_WIDTH-10,$NULL[1])
_GDIPlus_GraphicsDrawLine($hGr_BackbufferAx,$G_WIDTH-10,$NULL[1],$G_WIDTH-13,$NULL[1]-3)
_GDIPlus_GraphicsDrawLine($hGr_BackbufferAx,$G_WIDTH-10,$NULL[1],$G_WIDTH-13,$NULL[1]+3)
_GDIPlus_GraphicsDrawString($hGr_BackbufferAx,"x",$G_WIDTH-20,$NULL[1]-20)
;X-Achsen-Einheitenstriche alle 10cm
For $i=-(int(($NULL[0]-10)/$SCALE_FACTOR*10)) To (int(($G_WIDTH-$NULL[0]-10)/$SCALE_FACTOR*10))
If IsInt($i/10) Then
_GDIPlus_GraphicsDrawLine($hGr_BackbufferAx,$NULL[0]+$i*$SCALE_FACTOR/10,$NULL[1]-10,$NULL[0]+$i*$SCALE_FACTOR/10,$NULL[1]+10)
ElseIf IsInt($i/5) Then
_GDIPlus_GraphicsDrawLine($hGr_BackbufferAx,$NULL[0]+$i*$SCALE_FACTOR/10,$NULL[1]-6,$NULL[0]+$i*$SCALE_FACTOR/10,$NULL[1]+6)
Else
_GDIPlus_GraphicsDrawLine($hGr_BackbufferAx,$NULL[0]+$i*$SCALE_FACTOR/10,$NULL[1]-3,$NULL[0]+$i*$SCALE_FACTOR/10,$NULL[1]+3)
EndIf
Next
EndFunc
Func DrawTrace()
If ($apos2[0]<>$POS[0] Or $apos2[1]<>$POS[1]) Then
_GDIPlus_GraphicsDrawLine($hGr_Backbuffer2,GetXPos($apos2[0]),GetYPos($apos2[1]),GetXPos(),GetYPos(),$hPen_Trace)
$apos2[0]=$POS[0]
$apos2[1]=$POS[1]
EndIf
EndFunc
#endregion
#region Input und Variablen-Funktionen
Func CheckInputs()
$input = GUICtrlRead($gui_inp_FederD)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
$input = GUICtrlRead($gui_inp_FederS)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
$input = GUICtrlRead($gui_inp_ObjktM)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
$input = GUICtrlRead($gui_inp_UmgebG)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
$input = GUICtrlRead($gui_inp_TFact)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
$input = GUICtrlRead($gui_inp_ScFact)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
$input = GUICtrlRead($gui_inp_Null0)
If $input="" Or Not (StringIsInt($input)) Then Return False
$input = GUICtrlRead($gui_inp_Null1)
If $input="" Or Not (StringIsInt($input)) Then Return False
$input = GUICtrlRead($gui_inp_pos0)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
$input = GUICtrlRead($gui_inp_pos1)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
$input = GUICtrlRead($gui_inp_speed0)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
$input = GUICtrlRead($gui_inp_speed1)
If $input="" Or Not (StringIsInt($input) Or StringIsFloat($input)) Then Return False
Return True
EndFunc
Func InputsToVars()
$FEDER_D = Number(GUICtrlRead($gui_inp_FederD))
$FEDER_S = Number(GUICtrlRead($gui_inp_FederS))
$OBJKT_M = Number(GUICtrlRead($gui_inp_ObjktM))
$UMGEB_G = Number(GUICtrlRead($gui_inp_UmgebG))
$TIME_FACTOR = Number(GUICtrlRead($gui_inp_TFact))
$SCALE_FACTOR = Number(GUICtrlRead($gui_inp_ScFact))
$NULL[0] = Int(GUICtrlRead($gui_inp_Null0))
$NULL[1] = Number(GUICtrlRead($gui_inp_Null1))
$POS[0] = Number(GUICtrlRead($gui_inp_pos0))
$POS[1] = Number(GUICtrlRead($gui_inp_pos1))
If $TIME=0 Then
$STARTPOS[0]=$POS[0]
$STARTPOS[1]=$POS[1]
EndIf
$SPEED[0] = Number(GUICtrlRead($gui_inp_speed0))
$SPEED[1] = Number(GUICtrlRead($gui_inp_speed1))
If BitAND(GUICtrlRead($gui_chk_trace),$GUI_CHECKED) Then
$TRACE=True
Else
$TRACE=False
EndIf
If BitAND(GUICtrlRead($gui_chk_showtrace),$GUI_CHECKED) Then
$SHOWTRACE=True
Else
$SHOWTRACE=False
EndIf
If BitAND(GUICtrlRead($gui_chk_moveactive),$GUI_CHECKED) Then
$MOVEACTIVE=True
Else
$MOVEACTIVE=False
EndIf
$apos2[0]=$POS[0]
$apos2[1]=$POS[1]
EndFunc
Func BackupVars()
$bFEDER_D = $FEDER_D
$bFEDER_S = $FEDER_S
$bOBJKT_M = $OBJKT_M
$bUMGEB_G = $UMGEB_G
$bTIME_FACTOR = $TIME_FACTOR
$bSCALE_FACTOR = $SCALE_FACTOR
$bNULL[0] = $NULL[0]
$bNULL[1] = $NULL[1]
$bPOS[0] = $POS[0]
$bPOS[1] = $POS[1]
$bSPEED[0] = $SPEED[0]
$bSPEED[1] = $SPEED[1]
$bTRACE = $TRACE
$bSHOWTRACE = $SHOWTRACE
$bMOVEACTIVE = $MOVEACTIVE
$bMAKEGRAPH = $MAKEGRAPH
EndFunc
Func CompBackupVars()
Select
Case $bFEDER_D <> $FEDER_D
Return False
Case $bFEDER_S <> $FEDER_S
Return False
Case $bOBJKT_M <> $OBJKT_M
Return False
Case $bUMGEB_G <> $UMGEB_G
Return False
Case $bTIME_FACTOR <> $TIME_FACTOR
Return False
Case $bSCALE_FACTOR <> $SCALE_FACTOR
Return False
Case $bNULL[0] <> $NULL[0]
Return False
Case $bNULL[1] <> $NULL[1]
Return False
Case $bPOS[0] <> $POS[0]
Return False
Case $bPOS[1] <> $POS[1]
Return False
Case $bSPEED[0] <> $SPEED[0]
Return False
Case $bSPEED[1] <> $SPEED[1]
Return False
Case $bTRACE <> $TRACE
Return False
Case $bSHOWTRACE <> $SHOWTRACE
Return False
Case $bMOVEACTIVE <> $MOVEACTIVE
Return False
Case $bMAKEGRAPH <> $MAKEGRAPH
Return False
EndSelect
Return True
EndFunc
#endregion
#region Graphen
Func ToggleGraphGUI()
$MAKEGRAPH = Not $MAKEGRAPH
EndFunc
Func CreateGraphGUI()
If WinExists($GUIGraph) Then DeleteGraphGUI()
Global $GUIGraph = GUICreate("ChaosPendel v"&$SCRIPT_VERSION&" - Graphen-Fenster - Autor: fr34q",$DG_WIDTH,$DG_HEIGHT)
[/autoit] [autoit][/autoit] [autoit]Global $hGr_Fb_Graph = _GDIPlus_GraphicsCreateFromHWND($GUIGraph) ; Frontbuffer für die Graphen
[/autoit] [autoit][/autoit] [autoit]Dim $hBitmap_Bb_Graph[4] ; Backbuffer für die Graphen
Dim $hGr_Bb_Graph[4]
; Wertetabelle der Graphen
;Dim $aGraph[4][Int($GG_WIDTH)+1][2] ; [a][b][code=c] -> a: Nummer des Graphen, b: Stelle des Graphen, c: 0 - Zeit, 1 - Wert
;$aGraph[0][0][0] = Int($GG_WIDTH) ; Anzahl Stellen
GUICtrlCreateLabel("x-t-Schaubild:",10,10)
; 10,30 -> Graph
$hBitmap_Bb_Graph[1] = _GDIPlus_BitmapCreateFromGraphics($GG_WIDTH, $GG_HEIGHT, $hGr_Fb_Graph) ; Backbuffer für den Graphen erstellen
$hGr_Bb_Graph[1] = _GDIPlus_ImageGetGraphicsContext($hBitmap_Bb_Graph[1])
GUICtrlCreateLabel("y-t-Schaubild:",10,40+$GG_HEIGHT)
; 10, 60+$GG_HEIGHT
$hBitmap_Bb_Graph[2] = _GDIPlus_BitmapCreateFromGraphics($GG_WIDTH, $GG_HEIGHT, $hGr_Fb_Graph) ; Backbuffer für den Graphen erstellen
$hGr_Bb_Graph[2] = _GDIPlus_ImageGetGraphicsContext($hBitmap_Bb_Graph[2])
GUICtrlCreateLabel("e-t-Schaubild:",10,70+2*$GG_HEIGHT)
; 10, 90+2*$GG_HEIGHT
$hBitmap_Bb_Graph[3] = _GDIPlus_BitmapCreateFromGraphics($GG_WIDTH, $GG_HEIGHT, $hGr_Fb_Graph) ; Backbuffer für den Graphen erstellen
$hGr_Bb_Graph[3] = _GDIPlus_ImageGetGraphicsContext($hBitmap_Bb_Graph[3])
GUISetState(@SW_SHOW,$GUIGraph)
[/autoit] [autoit][/autoit] [autoit]RefreshGraph()
EndFunc
Func DeleteGraphGUI()
If Not WinExists($GUIGraph) Then Return False
_GDIPlus_GraphicsDispose($hGr_Fb_Graph)
For $i=1 To 3
_WinAPI_DeleteObject($hBitmap_Bb_Graph[$i])
_GDIPlus_GraphicsDispose($hGr_Bb_Graph[$i])
Next
GUIDelete($GUIGraph)
;Evtl werte zurücksetzen?
Return True
EndFunc
Func RefreshGraph()
For $g=1 To 3
_GDIPlus_GraphicsClear($hGr_Bb_Graph[$g], 0xFFFFFFFF)
GetGraphMinMax($g)
DrawGraphAxis($g)
For $i=2 To $aGraph[0][0][0]
$x = $aGraph[0][0][0]-$aGraph[0][0][1]+$i
If $x > ($aGraph[0][0][0]+1) Then $x -= $aGraph[0][0][0]
_GDIPlus_GraphicsDrawLine($hGr_Bb_Graph[$g],$x-1,GetYPosGraph($g,$aGraph[$g][$i-1][1]),$x,GetYPosGraph($g,$aGraph[$g][$i][1]),$hPen_Graph[$g])
Next
_GDIPlus_GraphicsDrawLine($hGr_Bb_Graph[$g],$aGraph[0][0][0]-$aGraph[0][0][1]-1,GetYPosGraph($g,$aGraph[$g][$aGraph[0][0][0]-1][1]),$aGraph[0][0][0]-$aGraph[0][0][1],GetYPosGraph($g,$aGraph[$g][$aGraph[0][0][0]][1]),$hPen_Graph[$g])
_GDIPlus_GraphicsDrawImage($hGr_Fb_Graph, $hBitmap_Bb_Graph[$g], 10, 30+($g-1)*(30+$GG_HEIGHT))
Next
EndFunc
Func GetYPosGraph($_graph,$_pos)
;$aGraph[$_graph][0][0] ; -> Minimum
;$aGraph[$_graph][0][1] ; -> Scale-Faktor
If $aGraph[$_graph][0][1] = 0 Then ; Division by Zero
Return 0.5*$GG_HEIGHT - 10*$_pos
EndIf
Return $GG_HEIGHT-5-($_pos-$aGraph[$_graph][0][0])/$aGraph[$_graph][0][1]
EndFunc
Func GetGraphMinMax($_graph)
;$aGraph[$_graph][0][0] ; -> Minimum
;$aGraph[$_graph][0][1] ; -> Maximum / der Scale-Faktor !!
For $_i=1 To $aGraph[0][0][0]
If $aGraph[$_graph][$_i][1] < $aGraph[$_graph][0][0] Then
$aGraph[$_graph][0][0] = $aGraph[$_graph][$_i][1]
ElseIf $aGraph[$_graph][$_i][1] > $aGraph[$_graph][0][1] Then
$aGraph[$_graph][0][1] = $aGraph[$_graph][$_i][1]
EndIf
Next
$aGraph[$_graph][0][1] = ($aGraph[$_graph][0][1]-$aGraph[$_graph][0][0])/($GG_HEIGHT-10)
EndFunc
Func DrawGraphAxis($_graph)
Local $_nullx = $GG_WIDTH-($TIME*$TIME_FACTOR)
Local $_nully = GetYPosGraph($_graph,0)
If Not ( $_nullx >= 3 And $_nullx <= ($GG_WIDTH-6) ) Then $_nullx = 3
_GDIPlus_GraphicsDrawLine($hGr_Bb_Graph[$_graph],$_nullx,3,$_nullx,$GG_HEIGHT-3) ; Y-Achse
_GDIPlus_GraphicsDrawLine($hGr_Bb_Graph[$_graph],$_nullx,3,$_nullx-3,6)
_GDIPlus_GraphicsDrawLine($hGr_Bb_Graph[$_graph],$_nullx,3,$_nullx+3,6)
Switch $_graph
Case 1 ; x-t-Schaubild
_GDIPlus_GraphicsDrawString($hGr_Bb_Graph[$_graph],"x",$_nullx+5,-2,"Arial",8)
Case 2 ; y-t-Schaubild
_GDIPlus_GraphicsDrawString($hGr_Bb_Graph[$_graph],"y",$_nullx+5,-2,"Arial",8)
Case 3 ; e-t-Schaubild
_GDIPlus_GraphicsDrawString($hGr_Bb_Graph[$_graph],"e",$_nullx+5,-2,"Arial",8)
EndSwitch
If Not ( $_nully >= 3 And $_nully <= ($GG_HEIGHT-6) ) Then $_nully = 0
_GDIPlus_GraphicsDrawLine($hGr_Bb_Graph[$_graph],3,$_nully,$GG_WIDTH-3,$_nully) ; X-Achse
_GDIPlus_GraphicsDrawLine($hGr_Bb_Graph[$_graph],$GG_WIDTH-3,$_nully,$GG_WIDTH-6,$_nully-3)
_GDIPlus_GraphicsDrawLine($hGr_Bb_Graph[$_graph],$GG_WIDTH-3,$_nully,$GG_WIDTH-6,$_nully+3)
_GDIPlus_GraphicsDrawString($hGr_Bb_Graph[$_graph],"t",$GG_WIDTH-10,$_nully-18,"Arial",8)
EndFunc
Func GraphSetNewValue($_graph,$_time,$_value)
If $atime2<>$TIME Then
$atime2=$TIME
If $aGraph[0][0][1] = $aGraph[0][0][0] Then $aGraph[0][0][1]=0
$aGraph[0][0][1] +=1
EndIf
#cs veraltet -> hat ja auch massig zeit gebraucht
For $i=2 To $aGraph[0][0][0]
$aGraph[$_graph][$i-1][0] = $aGraph[$_graph][$i][0]
$aGraph[$_graph][$i-1][1] = $aGraph[$_graph][$i][1]
Next
#ce
$aGraph[$_graph][$aGraph[0][0][1]][0] = $_time
$aGraph[$_graph][$aGraph[0][0][1]][1] = $_value
EndFunc
#endregion
Func Debug()
Dim $array[$aGraph[0][0][0]+1][2]
For $i=0 To $aGraph[0][0][0]
$array[$i][0] = $aGraph[1][$i][0]
$array[$i][1] = $aGraph[1][$i][1]
Next
_ArrayDisplay($array,"x-t-Schaubild")
Dim $array[$aGraph[0][0][0]+1][2]
For $i=0 To $aGraph[0][0][0]
$array[$i][0] = $aGraph[2][$i][0]
$array[$i][1] = $aGraph[2][$i][1]
Next
_ArrayDisplay($array,"y-t-Schaubild")
Dim $array[$aGraph[0][0][0]+1][2]
For $i=0 To $aGraph[0][0][0]
$array[$i][0] = $aGraph[3][$i][0]
$array[$i][1] = $aGraph[3][$i][1]
Next
_ArrayDisplay($array,"s-t-Schaubild")
EndFunc
Func ende()
DeleteGraphGUI()
For $i=1 To 3
_GDIPlus_PenDispose($hPen_Graph[$i])
Next
_GDIPlus_PenDispose($hPen_Trace)
_GDIPlus_GraphicsDispose($hGr_Frontbuffer)
_WinAPI_DeleteObject($hBitmap_Backbuffer)
_GDIPlus_GraphicsDispose($hGr_Backbuffer)
_WinAPI_DeleteObject($hBitmap_Backbuffer2)
_GDIPlus_GraphicsDispose($hGr_Backbuffer2)
_WinAPI_DeleteObject($hBitmap_BackbufferAx)
_GDIPlus_GraphicsDispose($hGr_BackbufferAx)
_GDIPlus_Shutdown()
Exit
EndFunc