Alek Posted October 10, 2009 Share 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] Link to comment Share on other sites More sharing options...
Marlo Posted October 10, 2009 Share Posted October 10, 2009 That's incredibly clever well done mate. Click here for the best AutoIt help possible.Currently Working on: Autoit RAT Link to comment Share on other sites More sharing options...
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