Hier mal meine Version von dem Ganzen in GDI+
(Hab nicht bei Andy abgeschaut, sondern mich nur inspirieren lassen :P)
Ist aber komplett in AutoIt. mit ASM geht da also nix
Spoiler anzeigen
#include <GDIPlus.au3>
#include <Array.au3>
Opt('GUIOnEventMode', 1)
Opt('MustDeclareVars', 1)
; p = Dichte
; PI = 3.1415926536
; r = Radius
; m = Masse = 4/3*PI*r³*p
; d(m) = Durchmesser(Masse) = 2*(3/(4*PI)*(m/p))^(1/3)
; G = Gravitationskonstante = 6.67384 * 10^(-11)
; F(r) = Anziehungskraft(Abstand) = G*m1*m2/r²
Global Const $VierDrittelPi = ATan(1) * 16 / 3
Global Const $DreiDurchVierPi = 3 / (ATan(1) * 16)
Global Const $Gravi = 6.67384 * 10 ^ (-11)
Global $Dichte = 10^10 ; Dichte der Materie (Größer -> Kleinere Partikel) in Kilogramm / m³
Global $GesamtMasse = 10^13 ; Gesamte Masse in unserem Universum in Kilogramm
Global $AnzahlPartikel = 25 ; Anzahl Brocken auf die die Masse aufgeteilt wird
Global $ZentralMasse = 10^10 ; Masse im Zentrum
Global $iW = 768, $iH = 768, $iD = ($iH ^ 2 + $iW ^ 2) ^ 0.5 ; Größe des Fensters
Global $aPartikel[$AnzahlPartikel][7]
; [0] - x Koord
; [1] - y Koord
; [2] - z Koord
; [3] - vX
; [4] - vY
; [5] - vZ
; [6] - Masse
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]Global $hGUI, $hDC, $hGFX, $hIMG, $hBUF, $hBRU, $hBRU2
$hGUI = GUICreate('Test', $iW, $iH)
$hDC = _WinAPI_GetDC($hGUI)
$hIMG = _Image_Create($iW, $iH)
$hBUF = DllStructGetData($hIMG, 1, 1)
$hGFX = _GDIPlus_GraphicsCreateFromHDC($hBUF)
$hBRU = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
$hBRU2 = _GDIPlus_BrushCreateSolid(0x20000000)
_GDIPlus_GraphicsSetSmoothingMode($hGFX, 4)
_Load()
[/autoit] [autoit][/autoit] [autoit]GUISetOnEvent(-3, 'EVENT', $hGUI)
OnAutoItExitRegister('_Freigeben')
GUIRegisterMsg(0xF, 'WM_PAINT')
GUISetState(@SW_SHOW, $hGUI)
While Sleep(10)
_Run()
WEnd
Func _Run()
Local Static $c = 0
$c += 1
_Calc()
If IsInt($c/2) Then
_Draw()
WM_PAINT()
EndIf
EndFunc ;==>_Run
Func _Calc()
Local $aTMP
For $i = $AnzahlPartikel - 1 To 0 Step - 1
For $e = 0 To $AnzahlPartikel - 1 Step 1
_GetVector($i, 0, 0, 0)
If $i = $e Then ContinueLoop
_GetVector($i, $e)
Next
Next
For $i = $AnzahlPartikel - 1 To 0 Step - 1
If $aPartikel[$i][6] = 1 Then
_ArrayDelete($aPartikel, $i)
$AnzahlPartikel -= 1
ContinueLoop
EndIf
$aPartikel[$i][0] += $aPartikel[$i][3]
$aPartikel[$i][1] += $aPartikel[$i][4]
$aPartikel[$i][2] += $aPartikel[$i][5]
Next
EndFunc ;==>_Calc
Func _Draw()
Local $d
_GDIPlus_GraphicsFillRect($hGFX, 0, 0, $iW, $iH, $hBRU2)
For $i = 0 To $AnzahlPartikel - 1 Step 1
$d = 2 * ($DreiDurchVierPi * $aPartikel[$i][6] / $Dichte)^(1/3)
DllCall($ghGDIPDll, "int", "GdipFillEllipse", "handle", $hGFX, "handle", $hBRU, "float", $aPartikel[$i][0]-$d/2 + $iW/2, "float", $aPartikel[$i][1]-$d/2 + $iH/2, "float", $d, "float", $d)
Next
$d = 2 * ($DreiDurchVierPi * $ZentralMasse / $Dichte)^(1/3)
DllCall($ghGDIPDll, "int", "GdipFillEllipse", "handle", $hGFX, "handle", $hBRU, "float", $iW/2-$d/2, "float", $iH/2-$d/2, "float", $d, "float", $d)
EndFunc ;==>_Draw
Func _GetVector($i, $e, $y = 1, $z = 1)
Local $a[3], $L, $F, $d, $mGes
If $e = 0 And $y = 0 And $z = 0 Then ; Unbewegliches Massezentrum
$a[0] = $e - $aPartikel[$i][0]
$a[1] = $y - $aPartikel[$i][1]
$a[2] = $z - $aPartikel[$i][2]
$L = ($a[0] ^ 2 + $a[1] ^ 2 + $a[2] ^ 2) ^ 0.5 ; Abstand der Partikel (Betrag des Vektors)
$F = $Gravi * $aPartikel[$i][6] * $ZentralMasse / $L ^ 3 ; Direkt um L vermindert
$d = ($DreiDurchVierPi * $aPartikel[$i][6] / $Dichte)^(1/3) + ($DreiDurchVierPi * $ZentralMasse / $Dichte)^(1/3); Durchmesser
If $L > $iD/32 Then
For $o = 0 To 2 Step 1
$aPartikel[$i][$o + 3] += $a[$o] * $F / $aPartikel[$i][6]
Next
EndIf
Else
For $o = 0 To 2 Step 1
$a[$o] = $aPartikel[$e][$o] - $aPartikel[$i][$o]
Next
$L = ($a[0] ^ 2 + $a[1] ^ 2 + $a[2] ^ 2) ^ 0.5 ; Abstand der Partikel (Betrag des Vektors)
$F = $Gravi * $aPartikel[$i][6] * $aPartikel[$e][6] / $L ^ 3 ; Direkt um L vermindert
$d = ($DreiDurchVierPi * $aPartikel[$i][6] / $Dichte)^(1/3) + ($DreiDurchVierPi * $aPartikel[$e][6] / $Dichte)^(1/3); Durchmesser
If $d > $L Then
$mGes = $aPartikel[$i][6] + $aPartikel[$e][6]
For $o = 0 To 2 Step 1
$aPartikel[$i][$o] = ($aPartikel[$i][$o]*$aPartikel[$i][6] + $aPartikel[$e][$o]*$aPartikel[$e][6])/$mGes
$aPartikel[$i][$o+3] = ($aPartikel[$i][$o+3]*$aPartikel[$i][6] + $aPartikel[$e][$o+3]*$aPartikel[$e][6])/$mGes
Next
$aPartikel[$i][6] = $mGes
$aPartikel[$e][6] = 1
Else
For $o = 0 To 2 Step 1
$aPartikel[$i][$o + 3] += $a[$o] * $F / $aPartikel[$i][6]
Next
EndIf
EndIf
EndFunc ;==>_GetVector
Func _Load()
Local $aTMP
For $i = 0 To $AnzahlPartikel - 1 Step 1
$aTMP = _3DRandom(-$iD / 4, $iD / 4)
$aPartikel[$i][0] = $aTMP[0]
$aPartikel[$i][1] = $aTMP[1]
$aPartikel[$i][2] = $aTMP[2]
$aPartikel[$i][3] = Random(-1, 1)
$aPartikel[$i][4] = Random(-1, 1)
$aPartikel[$i][5] = Random(-1, 1)
$aPartikel[$i][6] = $GesamtMasse / $AnzahlPartikel
Next
EndFunc ;==>_Load
Func _3DRandom($Min, $Max)
Local $x, $y, $z
Do
$x = Random($Min, $Max)
$y = Random($Min, $Max)
$z = Random($Min, $Max)
Until ($x ^ 2 + $y ^ 2 + $z ^ 2) ^ 0.5 < $Max ; Liegt der Vektor in der Sphere ?
Local $a[3] = [$x, $y, $z]
Return $a
EndFunc ;==>_3DRandom
Func WM_PAINT()
_WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hBUF, 0, 0, 0xCC0020)
EndFunc ;==>WM_PAINT
Func EVENT()
Switch @GUI_CtrlId
Case -3
Exit
EndSwitch
EndFunc ;==>EVENT
Func _Freigeben()
_GDIPlus_BrushDispose($hBRU2)
_GDIPlus_BrushDispose($hBRU)
_GDIPlus_GraphicsDispose($hGFX)
_WinAPI_ReleaseDC($hGUI, $hDC)
_Image_Delete($hIMG)
_GDIPlus_Shutdown()
EndFunc ;==>_Freigeben
Func _Image_Create($iW, $iH)
Local $Ptr, $hDC, $hBmp, $tBMI, $aDIB, $vStruct
$hDC = _WinAPI_CreateCompatibleDC(0)
$tBMI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4)
DllStructSetData($tBMI, "Width", $iW)
DllStructSetData($tBMI, "Height", -$iH)
DllStructSetData($tBMI, "Planes", 1)
DllStructSetData($tBMI, "BitCount", 32)
$aDIB = DllCall('GDI32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
$hBmp = $aDIB[0]
$Ptr = $aDIB[4]
_WinAPI_SelectObject($hDC, $hBmp)
$vStruct = DllStructCreate('int[5]')
DllStructSetData($vStruct, 1, $hDC, 1)
DllStructSetData($vStruct, 1, $iW, 2)
DllStructSetData($vStruct, 1, $iH, 3)
DllStructSetData($vStruct, 1, $Ptr, 4)
DllStructSetData($vStruct, 1, $hBmp, 5)
Return $vStruct
EndFunc ;==>_Image_Create
Func _Image_Delete(ByRef $vStruct)
_WinAPI_DeleteObject(DllStructGetData($vStruct, 1, 5))
_WinAPI_DeleteDC(DllStructGetData($vStruct, 1, 1))
$vStruct = 0
EndFunc ;==>_Image_Delete