Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Opt('GUIOnEventMode', 1)
- #include <GDIPlus.au3>
- #include <Array.au3>
- #include <WindowsConstants.au3>
- Global $iAnzahl = 30
- Global $fKnotenMasse = 0.05 ; Kilogramm
- Global $fLenRuhe = 0.5 ; Meter
- Global $fZeitschritt = 1/60/2 ; Sekunden
- Global $iMaxSteps = 9
- Global $iD = 6
- Global $dtQuadratDurchZwei = $fZeitschritt * $fZeitschritt * 0.5
- Global $dtQuadrat = $fZeitschritt * $fZeitschritt
- Global $fFederKonstanteProLen_Struktur = 50 ; Größere Zahlen = härtere federn
- Global $fFederKonstanteProLen_Biege1 = 10 ;
- Global $fFederKonstanteProLen_Biege2 = 2.0 ;
- Global $fDaempfungsgrad_Struktur = 0.2 ; 0.0 = Ungedämpft
- Global $fDaempfungsgrad_Biege1 = 0.2 ; 0.5 = Etwas gedämpft
- Global $fDaempfungsgrad_Biege2 = 0.1 ; 1.0 = Aperiodischer Grenzfall (kein Überschwingen)
- Global $fGravityZ = 9.81
- Global $aOffset = Vec2()
- Global $fLen_Struktur = 1 * $fLenRuhe
- Global $fLen_Biege1 = 2 * $fLenRuhe
- Global $fLen_Biege2 = 3 * $fLenRuhe
- Global $fFederKonstante_Struktur = $fFederKonstanteProLen_Struktur * $fLen_Struktur
- Global $fFederKonstante_Biege1 = $fFederKonstanteProLen_Biege1 * $fLen_Biege1
- Global $fFederKonstante_Biege2 = $fFederKonstanteProLen_Biege2 * $fLen_Biege2
- Global $fDaempfungskonstante_Struktur = 2 * Sqrt($fKnotenMasse * $fFederKonstante_Struktur) * $fDaempfungsgrad_Struktur
- Global $fDaempfungskonstante_Biege1 = 2 * Sqrt($fKnotenMasse * $fFederKonstante_Biege1) * $fDaempfungsgrad_Biege1
- Global $fDaempfungskonstante_Biege2 = 2 * Sqrt($fKnotenMasse * $fFederKonstante_Biege2) * $fDaempfungsgrad_Biege2
- Global $afLen = [$fLen_Struktur, $fLen_Biege1, $fLen_Biege2]
- Global $afFederKonstante = [$fFederKonstante_Struktur, $fFederKonstante_Biege1, $fFederKonstante_Biege2]
- Global $afDaempfungskonstante = [$fDaempfungskonstante_Struktur, $fDaempfungskonstante_Biege1, $fDaempfungskonstante_Biege2]
- Global $aPos_Minus1[$iAnzahl][2]
- Global $aPos[$iAnzahl][4]
- Global $aVel[$iAnzahl][2]
- ;~ Global $aFedern[][2]
- Reset2()
- ;~ Func Knoten($x = 0, $x_minus_1 = 0, $v = 0)
- ;~ Local $v = DllStructCreate('float x;float y;float x_minus1;float y_minus1;float vx;float vy')
- ;~ EndFunc
- ;~ Func Feder($i, $j, $fLen, $fFederKonst, $fDaempfungsKonst)
- ;~ EndFunc
- Global $bExit = False
- _GDIPlus_Startup()
- Global $iW = 500, $iH = 600
- Global $hGUI = GUICreate('Pendel', $iW, $iH)
- Global Const $hDC = _WinAPI_GetDC($hGUI)
- Global Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC)
- Global Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH)
- Global Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap)
- Global Const $hBUF = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)
- Global $hBRU = _GDIPlus_BrushCreateSolid(0xFFE5BE01)
- Global $hPEN = _GDIPlus_PenCreate(0xFFD4D9DB)
- _GDIPlus_GraphicsSetSmoothingMode($hBUF, 2)
- _GDIPlus_GraphicsSetPixelOffsetMode($hBUF, 2)
- GUISetOnEvent(-3, EVENT, $hGUI)
- GUISetState(@SW_SHOW, $hGUI)
- Global $iTimer = TimerInit()
- Global $fFrameTime, $fOverlap, $iStepCounter = 0, $count = 0
- While Not $bExit And Sleep(0)
- $fFrameTime = TimerDiff($iTimer)
- $iTimer = TimerInit()
- _GDIPlus_GraphicsClear($hBUF, 0xFF606060)
- $iStepCounter = 0
- For $i = $fFrameTime + $fOverlap To 0 Step -$fZeitschritt * 1000
- Verlet2()
- $iStepCounter += 1
- If $iStepCounter = $iMaxSteps Then
- $fFrameTime = -($fOverlap - $iStepCounter * $fZeitschritt * 1000)
- ExitLoop
- EndIf
- Next
- $count += 1
- ;~ ConsoleWrite($iStepCounter & ' ')
- ;~ If IsInt($count/50) Then ConsoleWrite(@CRLF)
- $fOverlap = $fFrameTime + $fOverlap - $iStepCounter * $fZeitschritt * 1000
- Render()
- _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY)
- WEnd
- _GDIPlus_PenDispose($hPEN)
- _GDIPlus_BrushDispose($hBRU)
- _GDIPlus_GraphicsDispose($hBUF)
- _WinAPI_SelectObject($hDC_backbuffer, $DC_obj)
- _WinAPI_DeleteDC($hDC_backbuffer)
- _WinAPI_DeleteObject($hHBitmap)
- _WinAPI_DeleteObject($hDC_backbuffer)
- _WinAPI_ReleaseDC($hGUI, $hDC)
- _GDIPlus_Shutdown()
- Func Render($bKugel = 1)
- For $i = 0 To $iAnzahl - 1 Step 1
- $aPos[$i][2] = $aPos[$i][0] * $iW / ($iAnzahl + 1) + $iW/2 - $iD/2
- $aPos[$i][3] = $aPos[$i][1] * $iW / ($iAnzahl - 10) + $iH/10 - $iD/2
- If $i > 0 Then
- DllCall($__g_hGDIPDll, "int", "GdipDrawLine", "handle", $hBUF, "handle", $hPEN, "float", $aPos[$i][2] + $iD / 2, "float", $aPos[$i][3] + $iD / 2, _
- "float", $aPos[$i - 1][2] + $iD / 2, "float", $aPos[$i - 1][3] + $iD / 2)
- EndIf
- Next
- If $bKugel Then
- For $i = 0 To $iAnzahl - 1 Step 1
- DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hBUF, "handle", $hBRU, "float", $aPos[$i][2], "float", $aPos[$i][3], "float", $iD, "float", $iD)
- Next
- EndIf
- EndFunc
- Func EVENT()
- Switch @GUI_CtrlId
- Case -3
- $bExit = True
- EndSwitch
- EndFunc
- Func Verlet2()
- Local $f, $aPos_Plus1[$iAnzahl][2], $pos_plus_1
- For $i = 0 To $iAnzahl - 1 Step 1
- $aVel[$i][0] = ($aPos[$i][0] - $aPos_Minus1[$i][0])/$fZeitschritt
- $aVel[$i][1] = ($aPos[$i][1] - $aPos_Minus1[$i][1])/$fZeitschritt
- Next
- For $i = 0 To $iAnzahl - 1 Step 1
- $f = Kraft2($i, $aPos, $aVel)
- $aPos_Plus1[$i][0] = $aPos[$i][0] * 2 - $aPos_Minus1[$i][0] + $f[0] * $dtQuadrat
- $aPos_Plus1[$i][1] = $aPos[$i][1] * 2 - $aPos_Minus1[$i][1] + $f[1] * $dtQuadrat
- Next
- For $i = 0 To $iAnzahl - 1 Step 1
- $aPos_Minus1[$i][0] = $aPos[$i][0]
- $aPos_Minus1[$i][1] = $aPos[$i][1]
- $aPos[$i][0] = $aPos_Plus1[$i][0]
- $aPos[$i][1] = $aPos_Plus1[$i][1]
- Next
- EndFunc
- Func Reset2()
- Local $f, $pos0
- For $i = 0 To $iAnzahl - 1 Step 1
- $aPos_Minus1[$i][0] = $aOffset[0] + $i * $fLenRuhe / Sqrt(2); X
- $aPos_Minus1[$i][1] = $aOffset[1] + $i * $fLenRuhe / Sqrt(2); Y
- Next
- For $i = 0 To $iAnzahl - 1 Step 1
- $f = Kraft2($i, $aPos_Minus1, $aVel)
- $pos0 = Add2(Vec2($aPos_Minus1[$i][0], $aPos_Minus1[$i][1]), Mul2(Div2($f, $fKnotenMasse),$dtQuadratDurchZwei))
- $aPos[$i][0] = $Pos0[0]
- $aPos[$i][1] = $Pos0[1]
- Next
- EndFunc
- Func FederKraft2($i, $iOffset, ByRef $x, ByRef $v, ByRef $f)
- Local $xij = [$x[$i + $iOffset][0] - $x[$i][0], $x[$i + $iOffset][1] - $x[$i][1]]
- Local $bxij = Sqrt($xij[0] * $xij[0] + $xij[1] * $xij[1]), $nxij = [$xij[0] / $bxij, $xij[1] / $bxij], $o = Abs($iOffset) - 1
- Local $c = $afFederKonstante[$o] * ($bxij - $afLen[$o]) + $afDaempfungskonstante[$o] * (($v[$i + $iOffset][0] - $v[$i][0]) * $nxij[0] + ($v[$i + $iOffset][1] - $v[$i][1]) * $nxij[1])
- $f[0] += $c * $nxij[0]
- $f[1] += $c * $nxij[1]
- EndFunc
- Func Kraft2($i, ByRef $x, ByRef $v)
- If $i = 0 Then Return Vec2()
- Local $f = [0, $fGravityZ * $fKnotenMasse]
- Switch $i ; Federn nach oben
- Case 1 ; -1
- FederKraft2($i, -1, $x, $v, $f)
- Case 2 ; -1, -2
- FederKraft2($i, -2, $x, $v, $f)
- FederKraft2($i, -1, $x, $v, $f)
- Case 3 To $iAnzahl ; -1, -2, -3
- FederKraft2($i, -3, $x, $v, $f)
- FederKraft2($i, -2, $x, $v, $f)
- FederKraft2($i, -1, $x, $v, $f)
- EndSwitch
- Switch $iAnzahl - $i - 1
- Case 1
- FederKraft2($i, 1, $x, $v, $f)
- Case 2
- FederKraft2($i, 1, $x, $v, $f)
- FederKraft2($i, 2, $x, $v, $f)
- Case 3 To $iAnzahl
- FederKraft2($i, 1, $x, $v, $f)
- FederKraft2($i, 2, $x, $v, $f)
- FederKraft2($i, 3, $x, $v, $f)
- EndSwitch
- $f[0] /= $fKnotenMasse
- $f[1] /= $fKnotenMasse
- Return $f
- EndFunc
- Func Betrag2($a)
- Return Sqrt($a[0] * $a[0] + $a[1] * $a[1])
- EndFunc
- Func Norm2($a)
- Local $d = Sqrt($a[0] * $a[0] + $a[1] * $a[1]), $c = [$a[0] / $d, $a[1] / $d]
- Return $c
- EndFunc
- Func Vec2($a = 0, $b = 0)
- Local $c = [$a, $b]
- Return $c
- EndFunc
- Func Div2($a, $b)
- If IsArray($a) And Not IsArray($b) Then Return Vec2($a[0] / $b, $a[1] / $b)
- EndFunc
- Func Mul2($a, $b)
- If IsArray($a) Then
- If IsArray($b) Then
- Return $a[0] * $b[0] + $a[1] * $b[1]
- Else
- Return Vec2($a[0] * $b, $a[1] * $b)
- EndIf
- Else
- If IsArray($b) Then
- Return Vec2($b[0] * $a, $b[1] * $a)
- Else
- Return $a * $b
- EndIf
- EndIf
- EndFunc
- Func Add2($a, $b)
- Return Vec2($a[0] + $b[0], $a[1] + $b[1])
- EndFunc
- Func Sub2($a, $b)
- Return Vec2($a[0] - $b[0], $a[1] - $b[1])
- EndFunc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement