Alek Posted October 10, 2009 Posted October 10, 2009 (edited) Bin working on some bezier UDFs, wanted to be able to get coords along a bezier curve. here is a example of what i came up with. just click around on the GUI and see what happens expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <GDIPlus.au3> #include <WinApi.au3> Opt("GUIOnEventMode", 1) ; Create GUI $hGUI = GUICreate("GDI+", 800, 600, -1, -1, $WS_SIZEBOX) ; Draw a cardinal spline _GDIPlus_Startup () $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI) $BackBuffer = _GDIPlus_BitmapCreateFromGraphics(400, 300, $hGraphic) $MainGraphic = _GDIPlus_ImageGetGraphicsContext($BackBuffer) _GDIPlus_GraphicsClear($MainGraphic, 0xFFFFFFFF) _GDIPlus_GraphicsSetSmoothingMode($MainGraphic, 2) Global $Bezier Global $MovePoint = -1 GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "GUI_EVENT_MOUSEMOVE") GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "GUI_EVENT_PRIMARYDOWN") GUISetOnEvent($GUI_EVENT_PRIMARYUP, "GUI_EVENT_PRIMARYUP") GUISetOnEvent($GUI_EVENT_CLOSE, "GUI_EVENT_CLOSE") GUISetState() While True Sleep(10) _Draw() WEnd Func GUI_EVENT_MOUSEMOVE() Local $ginfo = GUIGetCursorInfo() If $MovePoint > -1 Then _Bezier_SetControlPoint($Bezier, $MovePoint, $ginfo) EndIf EndFunc Func GUI_EVENT_PRIMARYDOWN() Local $ginfo = GUIGetCursorInfo() If UBound($Bezier) = 0 Then Local $point[2] $point[0] = $ginfo[0] $point[1] = $ginfo[1] $Bezier = _Bezier_Create($point) Return EndIf For $t = 0 To _Bezier_GetPointCount($Bezier) $P = _Bezier_GetControlPoint($Bezier, $t) If _InRange($ginfo, $P, 3) Then $MovePoint = $t Return EndIf Next $MovePoint = _Bezier_AddControlPoint($Bezier, $ginfo) EndFunc Func GUI_EVENT_PRIMARYUP() $MovePoint = -1 EndFunc Func GUI_EVENT_CLOSE() _GDIPlus_GraphicsDispose ($hGraphic) _GDIPlus_Shutdown () Exit EndFunc Func _InRect($point, $rectp1, $rectp2) If $point[0] > $rectp1[0] And $point[0] < $rectp2[0] And $point[1] > $rectp1[1] And $point[1] < $rectp2[1] Then Return True EndIf Return False EndFunc Func _InRange($point1, $point2, $range) If Sqrt(($point1[0] - $point2[0])^2 + ($point1[1] - $point2[1])^2) < $range Then Return True EndIf Return False EndFunc Func _Draw() Local $timer = TimerInit() _GDIPlus_GraphicsClear($MainGraphic, 0xFFFFFFFF) If UBound($Bezier) <> 0 Then _Bezier_Draw($MainGraphic, $Bezier, 40) EndIf _GDIPlus_GraphicsDrawImage($hGraphic, $BackBuffer, 0, 0) WinSetTitle($hGUI, "", "FPS: " & Round(1000 / TimerDiff($timer), 2)) EndFunc Func WM_SIZE($hWnd, $Msg, $wParam, $lParam) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose ($BackBuffer) _GDIPlus_BitmapDispose($BackBuffer) $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI) ConsoleWrite($lParam & @CRLF) $BackBuffer = _GDIPlus_BitmapCreateFromGraphics(_WinAPI_LoWord($lParam), _WinAPI_HiWord($lParam), $hGraphic) $MainGraphic = _GDIPlus_ImageGetGraphicsContext($BackBuffer) _GDIPlus_GraphicsSetSmoothingMode($MainGraphic, 2) _Draw() EndFunc Func _Bezier_Draw($Graphics, $B, $subdivid = 25) Local $oldPoint = _Bezier_GetPoint($B, 0) Local $point For $x = 0 To 1 Step 1/$subdivid $point = _Bezier_GetPoint($B, $x) _GDIPlus_GraphicsDrawLine($Graphics, $oldPoint[0], $oldPoint[1], $point[0], $point[1]) $oldPoint = $point Next $point = _Bezier_GetPoint($B, 1) _GDIPlus_GraphicsDrawLine($Graphics, $oldPoint[0], $oldPoint[1], $point[0], $point[1]) Local $pen = _GDIPlus_PenCreate() _GDIPlus_PenSetDashStyle($pen, $GDIP_DASHSTYLEDASH) ;_GDIPlus_GraphicsDrawLine($Graphics, $B[0][0], $B[0][1], $B[1][0], $B[1][1], $pen) ;_GDIPlus_GraphicsDrawLine($Graphics, $B[2][0], $B[2][1], $B[3][0], $B[3][1], $pen) Local $oldPoint = _Bezier_GetControlPoint($B, 0) Local $point For $x = 0 To UBound($B) - 1 $point = _Bezier_GetControlPoint($B, $x) _GDIPlus_GraphicsDrawLine($Graphics, $oldPoint[0], $oldPoint[1], $point[0], $point[1], $pen) $oldPoint = $point _GDIPlus_GraphicsFillEllipse($Graphics, $B[$x][0] - 3, $B[$x][1] - 3, 6, 6) Next EndFunc #cs This is where the real bezier UDF start #ce Func _Bezier_GetPoint($B, $t) Local $n = UBound($B) - 1 For $k = 1 To $n For $i = 0 To $n - $k $B[$i][0] = (1 - $t) * $B[$i][0] + $t * $B[$i + 1][0] $B[$i][1] = (1 - $t) * $B[$i][1] + $t * $B[$i + 1][1] Next Next Local $ret[2] $ret[0] = $B[0][0] $ret[1] = $B[0][1] Return $ret EndFunc Func _Bezier_Create($points) If Mod(UBound($points), 2) <> 0 Then Return SetError(1, 0, -1) EndIf Local $B[UBound($points) / 2][2] For $x = 0 To UBound($B) - 1 $B[$x][0] = $points[$x * 2] $B[$x][1] = $points[($x * 2) + 1] Next Return $B EndFunc Func _Bezier_GetPointCount($B) Return UBound($B) - 1 EndFunc Func _Bezier_GetControlPoint($B, $point) If $point > UBound($B) - 1 Then Return SetError(1, 0, -1) EndIf Local $ret[2] $ret[0] = $B[$point][0] $ret[1] = $B[$point][1] Return $ret EndFunc Func _Bezier_SetControlPoint(ByRef $B, $point, $newpoint) If $point > UBound($B) - 1 Then Return SetError(1, 0, -1) EndIf $B[$point][0] = $newpoint[0] $B[$point][1] = $newpoint[1] Return $B EndFunc Func _Bezier_AddControlPoint(ByRef $B, $point) ReDim $B[UBound($B) + 1][UBound($B, 2)] $B[UBound($B) - 1][0] = $point[0] $B[UBound($B) - 1][1] = $point[1] Return UBound($B) - 1 EndFunc Edited October 10, 2009 by Alek [font="Impact"]Never fear, I is here.[/font]
Marlo Posted October 10, 2009 Posted October 10, 2009 That's incredibly clever well done mate. Click here for the best AutoIt help possible.Currently Working on: Autoit RAT
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now