Jump to content

Some Graphical Examples using GDI+ Vol. I


UEZ
 Share

Recommended Posts

Warp speed Mr. Sulu

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

Opt("GUIOnEventMode", 1)
Global Const $width = 800
Global Const $height = 500
$hWnd = GUICreate("SineWorm", $width, $height)
GUISetOnEvent($GUI_EVENT_CLOSE, "close")
GUISetState()

_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
_GDIPlus_GraphicsSetSmoothingMode($backbuffer,4)


$inc = 0

Local $aFact[4] = [0.0, 0.25, 0.5, 1]
$lgbrush = _GDIPlus_CreateLineBrushFromRect(0, 00, $width, $height, $aFact, -1, 0x7Fffffff, 0x7FFFFFFF,0)
tantan()
Func tantan()
Do
_GDIPlus_GraphicsClear($backbuffer, 0xFF000000)



$ymod = Random(0,600)
For $i = 0 To $width Step 2
$xmod = $i
_GDIPlus_GraphicsFillEllipse($backbuffer, $xmod, $ymod, 8, 8, $lgbrush)
Next
$ymod2 = Random(0,600)
For $i = 0 To $width Step 2
$xmod = $i
_GDIPlus_GraphicsFillEllipse($backbuffer, $xmod, $ymod2, 8, 8, $lgbrush)
Next
$ymod3 = Random(0,600)
For $i = 0 To $width Step 2
$xmod = $i
_GDIPlus_GraphicsFillEllipse($backbuffer, $xmod, $ymod3, 8, 8, $lgbrush)
Next
$enterprise = _GDIPlus_ImageLoadFromFile(@ScriptDir"\enterprise side view.png")
    _GDIPlus_GraphicsDrawImageRect($backbuffer,$enterprise,100,0,600,600)
_GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height)
Until Not Sleep(20)
EndFunc

Func close()
_GDIPlus_BrushDispose($lgbrush)
_GDIPlus_GraphicsDispose($backbuffer)
_GDIPlus_BitmapDispose($bitmap)
_GDIPlus_GraphicsDispose($graphics)
_GDIPlus_Shutdown()
Exit
EndFunc;==>close












;==== GDIPlus_CreateLineBrushFromRect ===
;Description - Creates a LinearGradientBrush object from a set of boundary points and boundary colors.
; $aFactors - If non-array, default array will be used.
; Pointer to an array of real numbers that specify blend factors. Each number in the array
; specifies a percentage of the ending color and should be in the range from 0.0 through 1.0.
;$aPositions - If non-array, default array will be used.
; Pointer to an array of real numbers that specify blend factors' positions. Each number in the array
; indicates a percentage of the distance between the starting boundary and the ending boundary
; and is in the range from 0.0 through 1.0, where 0.0 indicates the starting boundary of the
; gradient and 1.0 indicates the ending boundary. There must be at least two positions
; specified: the first position, which is always 0.0, and the last position, which is always
; 1.0. Otherwise, the behavior is undefined. A blend position between 0.0 and 1.0 indicates a
; line, parallel to the boundary lines, that is a certain fraction of the distance from the
; starting boundary to the ending boundary. For example, a blend position of 0.7 indicates
; the line that is 70 percent of the distance from the starting boundary to the ending boundary.
; The color is constant on lines that are parallel to the boundary lines.
; $iArgb1 - First Top color in 0xAARRGGBB format
; $iArgb2 - Second color in 0xAARRGGBB format
; $LinearGradientMode - LinearGradientModeHorizontal = 0x00000000,
; LinearGradientModeVertical = 0x00000001,
; LinearGradientModeForwardDiagonal = 0x00000002,
; LinearGradientModeBackwardDiagonal = 0x00000003
; $WrapMode - WrapModeTile = 0,
; WrapModeTileFlipX = 1,
; WrapModeTileFlipY = 2,
; WrapModeTileFlipXY = 3,
; WrapModeClamp = 4
; GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect, ARGB color1, ARGB color2,
; LinearGradientMode mode, GpWrapMode wrapMode, GpLineGradient **lineGradient)
; Reference: http://msdn.microsoft.com/en-us/library/ms534043(VS.85).aspx
;
Func _GDIPlus_CreateLineBrushFromRect($iX, $iY, $iWidth, $iHeight, $aFactors, $aPositions, _
$iArgb1 = 0xFF0000FF, $iArgb2 = 0xFFFF0000, $LinearGradientMode = 0x00000001, $WrapMode = 0)

Local $tRect, $pRect, $aRet, $tFactors, $pFactors, $tPositions, $pPositions, $iCount

If $iArgb1 = -1 Then $iArgb1 = 0xFF0000FF
If $iArgb2 = -1 Then $iArgb2 = 0xFFFF0000
If $LinearGradientMode = -1 Then $LinearGradientMode = 0x00000001
If $WrapMode = -1 Then $WrapMode = 1

$tRect = DllStructCreate("float X;float Y;float Width;float Height")
$pRect = DllStructGetPtr($tRect)
DllStructSetData($tRect, "X", $iX)
DllStructSetData($tRect, "Y", $iY)
DllStructSetData($tRect, "Width", $iWidth)
DllStructSetData($tRect, "Height", $iHeight)

;Note: Withn _GDIPlus_Startup(), $ghGDIPDll is defined
$aRet = DllCall($ghGDIPDll, "int", "GdipCreateLineBrushFromRect", "ptr", $pRect, "int", $iArgb1, _
"int", $iArgb2, "int", $LinearGradientMode, "int", $WrapMode, "int*", 0)

If IsArray($aFactors) = 0 Then Dim $aFactors[4] = [0.0, 0.4, 0.6, 1.0]
If IsArray($aPositions) = 0 Then Dim $aPositions[4] = [0.0, 0.3, 0.7, 1.0]

$iCount = UBound($aPositions)
$tFactors = DllStructCreate("float[" & $iCount & "]")
$pFactors = DllStructGetPtr($tFactors)
For $iI = 0 To $iCount - 1
DllStructSetData($tFactors, 1, $aFactors[$iI], $iI + 1)
Next
$tPositions = DllStructCreate("float[" & $iCount & "]")
$pPositions = DllStructGetPtr($tPositions)
For $iI = 0 To $iCount - 1
DllStructSetData($tPositions, 1, $aPositions[$iI], $iI + 1)
Next

$hStatus = DllCall($ghGDIPDll, "int", "GdipSetLineBlend", "hwnd", $aRet[6], _
"ptr", $pFactors, "ptr", $pPositions, "int", $iCount)
Return $aRet[6]; Handle of Line Brush
EndFunc;==>_GDIPlus_CreateLineBrushFromRect

post-37433-1237917262_thumb.png

Giggity

Link to comment
Share on other sites

@youknowwho4eva: funny idea

but I did some very small modifications because you don't need to load the image in the DO ... UNTIL loop everytime :o

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

Opt("GUIOnEventMode", 1)
Global Const $width = 800
Global Const $height = 500
$hWnd = GUICreate("Enterprise Warp", $width, $height)
GUISetOnEvent($GUI_EVENT_CLOSE, "close")
GUISetState()

_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
_GDIPlus_GraphicsSetSmoothingMode($backbuffer, 4)


$inc = 0
$j = 0
Local $aFact[4] = [0.0, 0.25, 0.5, 1]
$lgbrush = _GDIPlus_CreateLineBrushFromRect(0, 00, $width, $height, $aFact, -1, 0x7Fffffff, 0x7FFFFFFF, 0)
$enterprise = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\enterprise_side_view.png")

Do
    $j += 1
    _GDIPlus_GraphicsClear($backbuffer, 0xFF000000)
    $random = Random(0, 1, 1)
    If $random = 0 Then ;draw image and then the lines
        Zulu()
        Warp()
    Else ;draw lines and then enterprise
        Warp()
        Zulu()
    EndIf
    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height)
Until Not Sleep(20)


Func Zulu ()
    _GDIPlus_GraphicsDrawImageRect($backbuffer, $enterprise, Tan($j * 3.14 / 180) * 100, Cos($j * 3.14 / 180) * 100, 600 * (1 + Cos($j * 3.14 / 180) / 4), 600 * (1 + Cos($j * 3.14 / 180) / 4))
EndFunc

Func Warp()
            $ymod = Random(0, 600)
        For $i = 0 To $width Step 2
            $xmod = $i
            _GDIPlus_GraphicsFillEllipse($backbuffer, $xmod, $ymod, 8, 8, $lgbrush)
        Next
        $ymod2 = Random(0, 600)
        For $i = 0 To $width Step 2
            $xmod = $i
            _GDIPlus_GraphicsFillEllipse($backbuffer, $xmod, $ymod2, 8, 8, $lgbrush)
        Next
        $ymod3 = Random(0, 600)
        For $i = 0 To $width Step 2
            $xmod = $i
            _GDIPlus_GraphicsFillEllipse($backbuffer, $xmod, $ymod3, 8, 8, $lgbrush)
        Next
EndFunc
   
Func close()
    _GDIPlus_BrushDispose($lgbrush)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($graphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>close

;==== GDIPlus_CreateLineBrushFromRect ===
;Description - Creates a LinearGradientBrush object from a set of boundary points and boundary colors.
; $aFactors - If non-array, default array will be used.
; Pointer to an array of real numbers that specify blend factors. Each number in the array
; specifies a percentage of the ending color and should be in the range from 0.0 through 1.0.
;$aPositions - If non-array, default array will be used.
; Pointer to an array of real numbers that specify blend factors' positions. Each number in the array
; indicates a percentage of the distance between the starting boundary and the ending boundary
; and is in the range from 0.0 through 1.0, where 0.0 indicates the starting boundary of the
; gradient and 1.0 indicates the ending boundary. There must be at least two positions
; specified: the first position, which is always 0.0, and the last position, which is always
; 1.0. Otherwise, the behavior is undefined. A blend position between 0.0 and 1.0 indicates a
; line, parallel to the boundary lines, that is a certain fraction of the distance from the
; starting boundary to the ending boundary. For example, a blend position of 0.7 indicates
; the line that is 70 percent of the distance from the starting boundary to the ending boundary.
; The color is constant on lines that are parallel to the boundary lines.
; $iArgb1 - First Top color in 0xAARRGGBB format
; $iArgb2 - Second color in 0xAARRGGBB format
; $LinearGradientMode - LinearGradientModeHorizontal = 0x00000000,
; LinearGradientModeVertical = 0x00000001,
; LinearGradientModeForwardDiagonal = 0x00000002,
; LinearGradientModeBackwardDiagonal = 0x00000003
; $WrapMode - WrapModeTile = 0,
; WrapModeTileFlipX = 1,
; WrapModeTileFlipY = 2,
; WrapModeTileFlipXY = 3,
; WrapModeClamp = 4
; GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect, ARGB color1, ARGB color2,
; LinearGradientMode mode, GpWrapMode wrapMode, GpLineGradient **lineGradient)
; Reference: [url="http://msdn.microsoft.com/en-us/library/ms534043%28VS.85%29.aspx"]http://msdn.microsoft.com/en-us/library/ms534043(VS.85).aspx[/url]
;
Func _GDIPlus_CreateLineBrushFromRect($iX, $iY, $iWidth, $iHeight, $aFactors, $aPositions, _
        $iArgb1 = 0xFF0000FF, $iArgb2 = 0xFFFF0000, $LinearGradientMode = 0x00000001, $WrapMode = 0)

    Local $tRect, $pRect, $aRet, $tFactors, $pFactors, $tPositions, $pPositions, $iCount

    If $iArgb1 = -1 Then $iArgb1 = 0xFF0000FF
    If $iArgb2 = -1 Then $iArgb2 = 0xFFFF0000
    If $LinearGradientMode = -1 Then $LinearGradientMode = 0x00000001
    If $WrapMode = -1 Then $WrapMode = 1

    $tRect = DllStructCreate("float X;float Y;float Width;float Height")
    $pRect = DllStructGetPtr($tRect)
    DllStructSetData($tRect, "X", $iX)
    DllStructSetData($tRect, "Y", $iY)
    DllStructSetData($tRect, "Width", $iWidth)
    DllStructSetData($tRect, "Height", $iHeight)

    ;Note: Withn _GDIPlus_Startup(), $ghGDIPDll is defined
    $aRet = DllCall($ghGDIPDll, "int", "GdipCreateLineBrushFromRect", "ptr", $pRect, "int", $iArgb1, _
            "int", $iArgb2, "int", $LinearGradientMode, "int", $WrapMode, "int*", 0)

    If IsArray($aFactors) = 0 Then Dim $aFactors[4] = [0.0, 0.4, 0.6, 1.0]
    If IsArray($aPositions) = 0 Then Dim $aPositions[4] = [0.0, 0.3, 0.7, 1.0]

    $iCount = UBound($aPositions)
    $tFactors = DllStructCreate("float[" & $iCount & "]")
    $pFactors = DllStructGetPtr($tFactors)
    For $iI = 0 To $iCount - 1
        DllStructSetData($tFactors, 1, $aFactors[$iI], $iI + 1)
    Next
    $tPositions = DllStructCreate("float[" & $iCount & "]")
    $pPositions = DllStructGetPtr($tPositions)
    For $iI = 0 To $iCount - 1
        DllStructSetData($tPositions, 1, $aPositions[$iI], $iI + 1)
    Next

    $hStatus = DllCall($ghGDIPDll, "int", "GdipSetLineBlend", "hwnd", $aRet[6], _
            "ptr", $pFactors, "ptr", $pPositions, "int", $iCount)
    Return $aRet[6]; Handle of Line Brush
EndFunc   ;==>_GDIPlus_CreateLineBrushFromRect

I hope you don't mind... :D

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Of course not. It was just a passing idea that I threw together, and when it worked I just accepted it :D

Edit: I was gonna put like warp controls in it... but ended up not feeling like it lol. Have 1 thru 10 even though 10 is never reached in the original, I believe the fastest they got was 8. In Voyager they reached 10. But had some side effects on the passengers.

Edited by youknowwho4eva

Giggity

Link to comment
Share on other sites

  • 2 weeks later...

Added one more GDI+ example: #09 Rotating Cube

Look to my first post for screenshot and source code!

:D

UEZ

PS: it is still in building phase

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Ok, that was amazing. I'm stunned, so nice :D

Here's my response, not equally good, but I think it's pretty nice.

Well done monoceres :o - your example is also great and thanks for feedback! :D

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Another one.

This one draws Lissajous curves.

...

:D

Great implementation of Lissajous Curve!

Currently I have no finished example for response :o Only a alpha version which I posted here to show border collision!

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Great implementation of Lissajous Curve!

Currently I have no finished example for response :P Only a alpha version which I posted here to show border collision!

UEZ

Thanks :D

Wow, if that's only 30% I really, really look forward to 100% :D Looks awesome already.

Also, I would like to say thanks for maintaining this topic, it's turning out to be a really good gallery :o

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

Thanks :D

Wow, if that's only 30% I really, really look forward to 100% :D Looks awesome already.

Current status at 30% because I'm not satisfied with the collision of the pixel with each other! And I'm planning to add a mouse function which manipulates the pixel beyond its radius...

I don't know when I can finish it because currently I'm really busy with my job and I've to spend more time with my family.

Also, I would like to say thanks for maintaining this topic, it's turning out to be a really good gallery :o

You're welcome!

I've the feeling that only a few users are really interested in GDI+ stuff...

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

How would you use this in another program[like for effects]?I mean having a GUI with one space plasma and having open space for buttons, etc?

Are you searching something like this: :o

Source code moved to my 1st post! -> #04 Plasma Variant

It is just an example! :D

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Here a sneak preview of a simple ball collision simulation (without mass deformation and ball spin) :D :

I will still add control panel where you can change values...

Look to my 1st post for screen shot and source code!

UEZ :o

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Aaw, I always wanted to do that, but somehow I always messed up the physics so it never turned out any good. Great job (as usual) :D

I continue with my curves and stuff. This time it's the butterfly curve

#include <GDIplus.au3>


#Region Settings for the animation
Global $ColorSpeed=0.004
Global $Iterations=100
Global $Speed=0.02
Global $Step=2
Global $ButterFlyW=100
Global $ButterFlyH=100
#EndRegion


Global Const $width = 650
Global Const $height = 600
Global Const $PI = 3.14159
Global Const $E = 2.71828183
Global $title = "Butterfly"


; Build your GUI here
Opt("GUIOnEventMode", 1)
$hwnd = GUICreate($title, $width, $height)
GUISetOnEvent(-3, "close")

_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
_GDIPlus_GraphicsSetSmoothingMode($backbuffer, 4)
$matrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($matrix, $width / 2, $height / 2)
_GDIPlus_GraphicsSetTransform($backbuffer, $matrix)

$brush = _GDIPlus_BrushCreateSolid(0x2F0000FF)

GUISetState()
$inc = 0
$inc2=Random(0,2^32-1)
_GDIPlus_GraphicsClear($backbuffer, 0xFF000000)
_GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height)



Do
    _GDIPlus_GraphicsClear($backbuffer, 0x0F000000)
    
    $inc2+=$ColorSpeed
    $red=Hex(((Sin($inc2)+1)/2)*255,2)
    $green=Hex(((Sin($inc2*2)+1)/2)*255,2)
    $blue=Hex(((Sin($inc2*3)+1)/2)*255,2)
    _GDIPlus_BrushSetSolidColor($brush,"0x0F"&$red&$green&$blue)

    $inc += $Speed
    For $i = 0 To $Iterations-1 Step $Step
        $pos = butterfly($inc + 2 * $PI / $Iterations * ($i + 1), $ButterFlyW, $ButterFlyH)
        $pos[1]-=50
        _GDIPlus_GraphicsFillEllipse($backbuffer, $pos[0], $pos[1], 10, 10, $brush)
    Next





    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height)
    Sleep(10)
Until False

Func butterfly($t, $sizex, $sizey)
    Local $aRet[2]

    $aRet[0] = $sizex * Sin($t) * ($E ^ Cos($t) - 2 * Cos($t * 4) - Sin($t / 12) ^ 5)
    $aRet[1] = $sizey * Cos($t) * ($E ^ Cos($t) - 2 * Cos($t * 4) - Sin($t / 12) ^ 5)

    Return $aRet

EndFunc  ;==>butterfly


Func _GDIPlus_BrushSetSolidColor($hBrush, $iARGB = 0xFF000000)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "hwnd", $hBrush, "int", $iARGB)
EndFunc  ;==>_GDIPlus_BrushSetSolidColor


Func close()
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($graphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc  ;==>close

You can change the behaviour by modifying the variables at the top :o

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

@UEZ, the light pink and the red ball got attached for a little while orbiting around each other. it was pretty neat looking.

....

See if this works for anyone else, Run the script in Scite, and hit F1 to bring up help. It runs another of the script.

Another edit: I changed the number of balls, the speed and the diameter. Now you see the orbiting a lot more often, and for me, it created what I'll call a black hole in the top left corner that sucked in the balls. I'd compare it too hydrogen fusion in the sun, mixed with a pool table.

;coded by UEZ 2009
#include <GUIConstantsEx.au3>
#include <GDIplus.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)

HotKeySet("{F5}", "Initialize")

Global Const $width = @DesktopWidth/2
Global Const $height = @DesktopHeight/2

Global $hwnd = GUICreate("Simple Ball Collision Simulation by UEZ 2009 (Press F5 to Refresh)", $width, $height, -1, -1, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
GUISetState(@SW_SHOW)

_GDIPlus_Startup()
Global $graphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
Global $bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
Global $backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
_GDIPlus_GraphicsClear($backbuffer)
_GDIPlus_GraphicsSetSmoothingMode($backbuffer, 4)
Global $brush_color
Global $brush = _GDIPlus_BrushCreateSolid()
_GDIPlus_BrushSetSolidColor($brush, $brush_color)

Global $max_dots = 50
Global $max_speed = 10
Global $pi = 3.1415926535897932384626
Global $pi_div_180 = $pi / 180
Global $diameter = @DesktopHeight / 48
Global $radius = $diameter / 2
Dim $coordinates[$max_dots][6]
Global $angle, $distance, $dist, $DX, $DY, $mass_tot, $matrix11, $matrix12, $matrix21, $matrix22, $vp1, $vp2, $vx1, $vx2, $vy1, $vy2
Global $q
Dim $brush[$max_dots]

Initialize()

Do
    _GDIPlus_GraphicsClear($backbuffer, 0xFF000000)
    Collision_Check()
    Draw_Dots()
    Calculate_New_Position()
    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height)
    Sleep(20)
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func Collision_Check()
    For $x = 0 To $max_dots - 1
        For $y = $x + 1 To $max_dots - 1
            $distance = Pixel_Distance($coordinates[$x][0], $coordinates[$x][1], $coordinates[$y][0], $coordinates[$y][1]);get distance
            If $distance <= $diameter Then
                $DX = $coordinates[$y][0] - $coordinates[$x][0];save delta x
                $DY = $coordinates[$y][1] - $coordinates[$x][1];save delta y
              ;matrix with new coordinate axis (orthographic / parallel to collision object)
                $matrix11 = $DX / $distance
                $matrix12 = -$DY / $distance
                $matrix21 = $DY / $distance
                $matrix22 = $DX / $distance
              ;scalar product of vectors
                $vx1 = $coordinates[$x][3] * $matrix11 + $coordinates[$x][4] * -$matrix12
                $vy1 = $coordinates[$x][3] * -$matrix21 + $coordinates[$x][4] * $matrix22
                $vx2 = $coordinates[$y][3] * $matrix11 + $coordinates[$y][4] * -$matrix12
                $vy2 = $coordinates[$y][3] * -$matrix21 + $coordinates[$y][4] * $matrix22
                $mass_tot = $coordinates[$x][5] + $coordinates[$y][5];total mass
              ;new vectors
                $vp1 = ($coordinates[$x][5] - $coordinates[$y][5]) / $mass_tot * $vx1 + 2 * $coordinates[$y][5] / $mass_tot * $vx2
                $vp2 = ($coordinates[$y][5] - $coordinates[$x][5]) / $mass_tot * $vx2 + 2 * $coordinates[$x][5] / $mass_tot * $vx1
              ;calculate new position using new vectors
                $coordinates[$x][3] = $vp1 * $matrix11 + $vy1 * $matrix12
                $coordinates[$x][4] = $vp1 * $matrix21 + $vy1 * $matrix22
                $coordinates[$y][3] = $vp2 * $matrix11 + $vy2 * $matrix12
                $coordinates[$y][4] = $vp2 * $matrix21 + $vy2 * $matrix22
            EndIf
        Next
    Next
EndFunc

Func Initialize()
    For $k = 0 To $max_dots - 1
        $brush_color = 0xFF000000 + Random(0x400000, 0xFFFFFF, 1)
        $brush[$k] = _GDIPlus_BrushCreateSolid($brush_color)
        New_Coordinates($k)
    Next
EndFunc ;==>Initialize


Func New_Coordinates($k)
        $coordinates[$k][0] = Random($radius + 1, $width - $radius - 1, 1);start x position
        $coordinates[$k][1] = Random($radius + 1, $height - $radius - 1, 1);start y position
        $q = 0
        If $k > 0 Then;check whether new coordinate is within other balls radius (collision)
            While 1
                $dist = Pixel_Distance($coordinates[$q][0], $coordinates[$q][1], $coordinates[$k][0], $coordinates[$k][1])
                If $dist <= 3 * $radius  Then;create new coordinate until distance of balls are > 3 * radius
                    $coordinates[$k][0] = Random($radius + 1, $width - $radius - 1, 1)
                    $coordinates[$k][1] = Random($radius + 1, $height - $radius - 1, 1)
                    $q = -1
                EndIf
                $q += 1
                If $q = $k Then ExitLoop
            WEnd
        EndIf
        $coordinates[$k][2] = Random(1, $max_speed, 1);speed of pixel
        $angle = Random(0, 359, 1)
  ;~     ConsoleWrite("Angel: " & $angle & "°" & @CRLF)
        $coordinates[$k][3] = $coordinates[$k][2] * Cos($angle * $pi_div_180);slope of x -> vector x
        $coordinates[$k][4] = $coordinates[$k][2] * Sin($angle * $pi_div_180);slope of y -> vector y
        $coordinates[$k][5] = 1;mass of the ball
EndFunc ;==>New_Coordinates

Func Calculate_New_Position()
    Local $k
    For $k = 0 To $max_dots - 1
        $coordinates[$k][0] += $coordinates[$k][3];increase x coordinate with appropriate slope (x vector)
        $coordinates[$k][1] += $coordinates[$k][4];increase y coordinate with appropriate slope (y vector)
        If $coordinates[$k][0] <= 0 Then;border collision x left
            $coordinates[$k][0] = 1
            $coordinates[$k][3] *= -1
        ElseIf $coordinates[$k][0] >= $width - $diameter Then;border collision x right
            $coordinates[$k][0] = $width - ($diameter + 1)
            $coordinates[$k][3] *= -1
        EndIf
        If $coordinates[$k][1] <= 0 Then;border collision y top
            $coordinates[$k][1] = 1
            $coordinates[$k][4] *= -1
        ElseIf $coordinates[$k][1] >= $height - $diameter Then;border collision y bottom
            $coordinates[$k][1] = $height - ($diameter + 1)
            $coordinates[$k][4] *= -1
        EndIf
    Next
EndFunc ;==>Calculate_New_Position

Func Pixel_Distance($x1, $y1, $x2, $y2)
    Local $a, $b, $c
    If $x2 = $x1 And $y2 = $y1 Then
        Return 0
    Else
        $a = $y2 - $y1
        $b = $x2 - $x1
        $c = Sqrt($a ^ 2 + $b ^ 2)
        Return Round($c, 0)
    EndIf
EndFunc ;==>Pixel_Distance

Func Draw_Dots()
    Local $i, $temp_x, $temp_y
    For $i = 0 To $max_dots - 1
        _GDIPlus_GraphicsFillEllipse($backbuffer, $coordinates[$i][0], $coordinates[$i][1], $diameter, $diameter, $brush[$i])
    Next
EndFunc ;==>Draw_Dots

Func close()
    _GDIPlus_BrushDispose($brush)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($graphics)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_Shutdown()
    Exit
EndFunc ;==>close

Func _GDIPlus_BrushSetSolidColor($hBrush, $iARGB = 0xFF000000)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "hwnd", $hBrush, "int", $iARGB)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_GDIPlus_BrushSetSolidColor
Edited by youknowwho4eva

Giggity

Link to comment
Share on other sites

Aaw, I always wanted to do that, but somehow I always messed up the physics so it never turned out any good. Great job (as usual) :D

I continue with my curves and stuff. This time it's the butterfly curve

...

You can change the behaviour by modifying the variables at the top :P

This is / was a really hard job :D I checked a lot of internet resource to get this stuff running passably. It is still not finished because "orbiting" is still possible!

Further I want to add mouse manipulation to the balls :o

Your butterfly curve is looking great and once again super job!

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Released beta version of "Simple Ball Collision Simulation" example!

Look to my 1st post for screen shot and source code!

Any kind of comment is welcome :D

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...