9月142023
有点意思的代码-模拟混沌单摆
#cs ----------------------------------------------------------------------------
AutoIt Version: 3.3.6.1
Author: fr34q
Script Function:
模拟混沌摆. (? in German: Chaos-Pendel)
#ce ----------------------------------------------------------------------------
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Array.au3> ; 仅用于调试
#include <WinApi.au3>
$SCRIPT_VERSION = "1.12"
$D_WIDTH = 900
$D_HEIGHT = 700
$G_WIDTH = 700
$G_HEIGHT = 700
Global $GUIGraph = 0
$GG_WIDTH = 700 ; 图表的宽度
$GG_HEIGHT = 200 ; 图表的高度
$DG_WIDTH = $GG_WIDTH + 20
$DG_HEIGHT = 3 * (30 + $GG_HEIGHT) + 10
$SCALE_FACTOR = 200 ; 1m -> 200px (1cm -> 2px)
$TIME_FACTOR = 0.01 ; 秒步骤
$PI = 3.1415926535897932384626433832795
$TRACE = True
$SHOWTRACE = True
$MOVEACTIVE = True
$MAKEGRAPH = False
Dim $NULL[2] ; 设置零点
$NULL[0] = $G_WIDTH / 2 ; X
$NULL[1] = 50 ; Y
_GDIPlus_Startup()
#Region Physikalische Variablen/Konstanten
$FEDER_D = 20 ; N/m - 回弹率
$FEDER_S = .2 ; m - 弹簧松弛
$OBJKT_M = .5 ; kg - 物体的质量
$UMGEB_G = 9.8 ; m/s² - 重力加速度
$FEDER_S0 = $FEDER_S + $OBJKT_M * $UMGEB_G / $FEDER_D ; 只有x偏转 = 0 ;实际上并不需要
Dim $STARTPOS[2]
$STARTPOS[0] = 0.3
$STARTPOS[1] = -$FEDER_S - .5
Dim $POS[2] ; 混沌摆的位置
$POS[0] = $STARTPOS[0] ; X
$POS[1] = $STARTPOS[1] ; Y
Dim $SPEED[2] ; 速度矢量以m/s为单位
$SPEED[0] = 0
$SPEED[1] = 0
Dim $BESCHL[2] ; m/s²
$BESCHL[0] = 0
$BESCHL[1] = 0
$TIME = 0 ; s
#EndRegion Physikalische Variablen/Konstanten
;图表
Global $hGr_Fb_Graph ; 图的前缓冲区
Dim $hBitmap_Bb_Graph[4] ; 图的后备缓冲
Dim $hGr_Bb_Graph[4]
; 图表的值表
Dim $aGraph[4][Int($GG_WIDTH) + 1][2] ; [a][b][code=c] -> a: 图表的编号, b: 图表的位置, c: 0 - 时间, 1 - 值
$aGraph[0][0][0] = Int($GG_WIDTH) ; 位数
$aGraph[0][0][1] = 1 ; 当前的位置将被描述 -> 很高
;[a][0][code=c] -> c: 0 - 最低价值, 1 - 比例
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
; 物理尺寸
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("超单摆 v" & $SCRIPT_VERSION & " - Autor: fr34q", $D_WIDTH, $D_HEIGHT)
GUICtrlCreateLabel("回弹率 D: [N/m]", $G_WIDTH + 10, 10)
$gui_inp_FederD = GUICtrlCreateInput($FEDER_D, $G_WIDTH + 10, 30, $D_WIDTH - $G_WIDTH - 20, 20)
GUICtrlCreateLabel("长弹簧松弛: [m]", $G_WIDTH + 10, 60)
$gui_inp_FederS = GUICtrlCreateInput($FEDER_S, $G_WIDTH + 10, 80, $D_WIDTH - $G_WIDTH - 20, 20)
GUICtrlCreateLabel("质量 m: [kg]", $G_WIDTH + 10, 110)
$gui_inp_ObjktM = GUICtrlCreateInput($OBJKT_M, $G_WIDTH + 10, 130, $D_WIDTH - $G_WIDTH - 20, 20)
GUICtrlCreateLabel("重力加速度 g: [m/s²]", $G_WIDTH + 10, 160)
$gui_inp_UmgebG = GUICtrlCreateInput($UMGEB_G, $G_WIDTH + 10, 180, $D_WIDTH - $G_WIDTH - 20, 20)
GUICtrlCreateLabel("时间步长: [s]", $G_WIDTH + 10, 210)
$gui_inp_TFact = GUICtrlCreateInput($TIME_FACTOR, $G_WIDTH + 10, 230, $D_WIDTH - $G_WIDTH - 20, 20)
GUICtrlCreateLabel("轴缩放: [px/m]", $G_WIDTH + 10, 260)
$gui_inp_ScFact = GUICtrlCreateInput($SCALE_FACTOR, $G_WIDTH + 10, 280, $D_WIDTH - $G_WIDTH - 20, 20)
GUICtrlCreateLabel("零点: [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("画一条痕迹", $G_WIDTH + 10, 360)
If $TRACE Then GUICtrlSetState(-1, $GUI_CHECKED)
$gui_chk_showtrace = GUICtrlCreateCheckbox("查看轨道", $G_WIDTH + 20 + Int(($D_WIDTH - $G_WIDTH - 30) / 2), 360)
If $SHOWTRACE Then GUICtrlSetState(-1, $GUI_CHECKED)
$gui_chk_moveactive = GUICtrlCreateCheckbox("只有积极地移动", $G_WIDTH + 10, 390)
If $MOVEACTIVE Then GUICtrlSetState(-1, $GUI_CHECKED)
GUICtrlCreateLabel("时间 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("位置: [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("速度: [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("加速度: [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("返回", $G_WIDTH + 10, $D_HEIGHT - 80, $D_WIDTH - $G_WIDTH - 20, 30)
$gui_btn_start = GUICtrlCreateButton("启动", $G_WIDTH + 10, $D_HEIGHT - 40, $D_WIDTH - $G_WIDTH - 20, 30)
GUISetState(@SW_SHOW, $GUI)
$hGr_Frontbuffer = _GDIPlus_GraphicsCreateFromHWND($GUI)
$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()
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)
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, "当前位置 & 速度与开始时相同!", "时间: " & $TIME & @CRLF & "位置: " & Round($POS[0], 10) & " , " & Round($POS[1], 10) & @CRLF _
& "最初姿势.: " & Round($STARTPOS[0], 10) & " , " & Round($STARTPOS[1], 10) & @CRLF _
& "速度: " & 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()
$BESCHL = GetA()
$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")
$TIME += Round($TIME_FACTOR, 3)
;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 ;==>GetXPos
Func GetYPos($_pos = "...")
If $_pos = "..." Then $_pos = $POS[1]
Return Round($NULL[1] - $_pos * $SCALE_FACTOR, 0)
EndFunc ;==>GetYPos
#EndRegion Positions-Funktionen (Ausgabe in px, Eingabe in m)
#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 ;==>SetPhysVars
#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 Physikalische Größen-Bestimmung
#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 wirkende Kräfte
#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 ;==>GetA
#EndRegion Beschleunigung
#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 ;==>GetEnergieGesamt
#EndRegion Energie Funktionen
#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, "停止")
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, "启动")
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 ;==>RefreshDisplay
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 ;==>DrawGraphic
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 ;==>DrawAxis
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 ;==>DrawTrace
#EndRegion Anzeige-Funktionen
#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 ;==>CheckInputs
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 ;==>InputsToVars
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 ;==>BackupVars
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 ;==>CompBackupVars
#EndRegion Input und Variablen-Funktionen
#Region Graphen
Func ToggleGraphGUI()
$MAKEGRAPH = Not $MAKEGRAPH
EndFunc ;==>ToggleGraphGUI
Func CreateGraphGUI()
If WinExists($GUIGraph) Then DeleteGraphGUI()
Global $GUIGraph = GUICreate("ChaosPendel v" & $SCRIPT_VERSION & " - Graphen-Fenster - Autor: fr34q", $DG_WIDTH, $DG_HEIGHT)
Global $hGr_Fb_Graph = _GDIPlus_GraphicsCreateFromHWND($GUIGraph) ; 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
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)
RefreshGraph()
EndFunc ;==>CreateGraphGUI
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 ;==>DeleteGraphGUI
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 ;==>RefreshGraph
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 ;==>GetYPosGraph
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 ;==>GetGraphMinMax
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 ;==>DrawGraphAxis
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 ;==>GraphSetNewValue
#EndRegion Graphen
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 ;==>Debug
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 ;==>ende
扫描二维码,在手机上阅读
发表评论
木有头像就木JJ啦!还木有头像吗?点这里申请属于你的个性Gravatar头像吧!