绿色风's Blog
专注AutoIT(Au3)
  • 首页
  • 流●年
  • 笔●记
    • 学习随记
    • 源码示例
  • 脚●本
    • UDF(收集)
    • 工作室UDF
    • 工具●教程
    • 教程之GDI
  • 作●品
  • 下●载
  • 情怀ExcelTip
9月142023

有点意思的代码-模拟混沌单摆

作者:绿色风   发布:2023-9-14 1:47 Thursday   分类:源码示例   阅读:3512次   评论:0条  

#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




本文固定链接: http://www.jianyiit.com/post-414.html

blogger
该日志由 绿色风 于2023-9-14 1:47 Thursday发表在 源码示例 分类下。
版权所有:《绿色风's Blog》 → 《有点意思的代码-模拟混沌单摆》;
除特别标注,本博客很多文章均为原创. 互联分享,尊重版权,转载请以链接形式标明本文地址;
本文标签:

扫描二维码,在手机上阅读
上一篇::996素材剑甲怪后置处理
下一篇:有点意思的代码-画个五角星

热门文章

相关文章

  • 分享个老代码,程序名锁定
  • pubmed 文献应助 抢单源码
  • Au3小游戏 2048
  • AU3窗口跟随与吸附
  • Au3中仿高阶函数的使用示例
取消回复

发表评论

亲,头像对么?

29 + 31 =

提交中,请稍候……


木有头像就木JJ啦!还木有头像吗?点这里申请属于你的个性Gravatar头像吧!


    站点统计
    • 运行时间: 20254 天
    • 日志总数: 365 篇
    • 评论数量: 7222 条
    • 微语数量: 6 条
    • 附件总量: 388 件
  • 逝出的青春

  • 打赏"绿色风"



      扫码关注本站公众号 可搜本站内容

  • Autoit V3 脚本交流群

      常驻群1:905774875
      常驻群2:40672266


  • 链接

    • AU3中文论坛
    • Excel资料库
    • 完美者博客
    • 顺网小哥'S Blog
    • 猛牛哥的博客
    • 网吧系统下载
  • 分类

    • 流●年(66)
    • 笔●记(0)
    • 脚●本(0)
    • 作品(21)
    • 学习随记(51)
    • 源码示例(68)
    • UDF(收集)(26)
    • 工作室UDF(30)
    • 工具●教程(62)
    • 教程之GDI(24)
Copyright © 2013 绿色风's Blog. Powered by emlog. Theme by 射雕天龙. 鄂ICP备2021011689号-1 鄂公网安备42102302000078号 sitemap