Moin,
Es ist eigentlich nichts großes, aber ich habe genau so ein Beispiel letztens gesucht und falls irgendwer sonst mal auf die Idee kommt den Casteljau3 (mit q = 3) Algorithmus (er ist wirklich trivial) zu basteln hat er hier eine kleine Vorlage (außerdem endet Casteljau3 auf "au3". Allein deshalb muss das hier ins Forum).
Mit den Variablen $bDrawXYZ (zeile 17 & 18) kann man auswählen in welchen Iterationsstufen man das Zwischenergebnis anzeigen lassen will.
Edit: Habe noch ein Beispiel für BezierN gebastelt.
AutoIt
#include <GDIPlus.au3>
Opt('GUIOnEventMode', 1)
Global Const $sTitle = 'Casteljau3'
Global Const $iW = 512
Global Const $iH = 512
Global Const $COL_HELLBLAU = 0xFF8EDFFF
Global Const $COL_ORANGE = 0xFFFDB961
Global Const $COL_GRUEN = 0xFF45ED67
Global Const $COL_VIOLETT = 0xFFD980E1
Global Const $COL_RED = 0xFFE28576
Global Const $COL_TUERKIS = 0xFF76E2B4
Global Const $aCol = [$COL_HELLBLAU, $COL_ORANGE, $COL_GRUEN, $COL_VIOLETT, $COL_RED, $COL_TUERKIS]
Global Const $bDrawLines = [True, False, False, False, False, True]
Global Const $bDrawPoints = [True, False, False, False, False, False]
Global Const $MaxIter = UBound($bDrawLines) - 1
Global $aInput = [[0.15, 0.85], [0.5, 0.1], [0.8, 0.3], [0.7, 0.8]]
Global $bExit = False
_GDIPlus_Startup()
Global $hGUI = GUICreate($sTitle, $iW, $iH)
Global $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Global $hBMP = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGFX)
Global $hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)
Global $hPEN = _GDIPlus_PenCreate()
_GDIPlus_PenSetStartCap($hPEN, 2)
_GDIPlus_PenSetEndCap($hPEN, 2)
_GDIPlus_GraphicsSetSmoothingMode($hBUF, 2)
GUISetOnEvent(-3, 'EVENT', $hGUI)
OnAutoItExitRegister('Xit')
GUISetState(@SW_SHOW, $hGUI)
Local $Timer = TimerInit(), $t = 0
While Not $bExit And Sleep(10)
$t = TimerDiff($Timer)/1000
_GDIPlus_GraphicsClear($hBUF)
Casteljau3($aInput)
$aInput[0][0] = 0.15 + Cos($t)/15
$aInput[0][1] = 0.85 + Sin($t)/15
$aInput[1][0] = 0.5 + Cos($t/2)/15
$aInput[1][1] = 0.1 + Sin($t/2)/15
$aInput[2][0] = 0.8 + Cos($t/3)/15
$aInput[2][1] = 0.3 + Sin($t/3)/15
$aInput[3][0] = 0.7 + Cos($t/5)/15
$aInput[3][1] = 0.8 + Sin($t/5)/15
_GDIPlus_GraphicsDrawImageRect($hGFX, $hBMP, 0, 0, $iW, $iH)
WEnd
Func Casteljau3($a, $iter = 0)
Local $iCol = $aCol[$iter]
_GDIPlus_PenSetColor($hPEN, $iCol)
_GDIPlus_PenSetWidth($hPEN, 0.005 * $iW * 0.9^$iter)
_GDIPlus_PenSetDashStyle($hPEN, 0)
For $i = 0 To UBound($a, 1) - 1 Step 1
If $bDrawPoints[$iter] Then Circle($a[$i][0], $a[$i][1], 0.025 * 0.9^$iter)
Next
_GDIPlus_PenSetWidth($hPEN, ($iter = $MaxIter ? 0.0035 : 0.0025) * $iW)
_GDIPlus_PenSetDashStyle($hPEN, $iter = $MaxIter ? 0 : 1)
For $i = 0 To UBound($a, 1) - 2 Step 1
If $bDrawLines[$iter] Then Line($a[$i][0], $a[$i][1], $a[$i+1][0], $a[$i+1][1])
Next
If $iter < $MaxIter Then
; Neue Eckpunkte berechnen: Es gibt 7 Punkte, der Mittlere ist doppelt.
Local $p0 = [$a[0][0], $a[0][1]]
Local $p1 = [($a[0][0] + $a[1][0])/2, ($a[0][1] + $a[1][1])/2]
Local $p5 = [($a[2][0] + $a[3][0])/2, ($a[2][1] + $a[3][1])/2]
Local $p6 = [$a[3][0], $a[3][1]]
Local $m = [($a[1][0] + $a[2][0])/2, ($a[1][1] + $a[2][1])/2] ; Mittelpunkt
Local $p2 = [($m[0] + $p1[0])/2, ($m[1] + $p1[1])/2]
Local $p4 = [($m[0] + $p5[0])/2, ($m[1] + $p5[1])/2]
Local $p3 = [($p2[0] + $p4[0])/2, ($p2[1] + $p4[1])/2]
Local $aL = [[$p0[0], $p0[1]], [$p1[0], $p1[1]], [$p2[0], $p2[1]], [$p3[0], $p3[1]]]
Local $aR = [[$p3[0], $p3[1]], [$p4[0], $p4[1]], [$p5[0], $p5[1]], [$p6[0], $p6[1]]]
Casteljau3($aL, $iter + 1)
Casteljau3($aR, $iter + 1)
EndIf
EndFunc
Func Line($x1, $y1, $x2, $y2)
_GDIPlus_GraphicsDrawLine($hBUF, $x1 * $iW, $y1 * $iH, $x2 * $iW, $y2 * $iH, $hPEN)
EndFunc
Func Circle($x, $y, $d)
_GDIPlus_GraphicsDrawEllipse($hBUF, $x * $iW - $d/2 * $iW, $y * $iH - $d/2 * $iH, $d * $iW, $d * $iH, $hPEN)
EndFunc
Func EVENT()
Switch @GUI_CtrlId
Case -3
$bExit = True
EndSwitch
EndFunc
Func Xit()
_GDIPlus_PenDispose($hPEN)
_GDIPlus_GraphicsDispose($hBUF)
_GDIPlus_BitmapDispose($hBMP)
_GDIPlus_GraphicsDispose($hGFX)
_GDIPlus_Shutdown()
EndFunc
Alles anzeigen
AutoIt
#include <GDIPlus.au3>
#include <Misc.au3>
Opt('GUIOnEventMode', 1)
Opt('MouseCoordMode', 2)
Global Const $sTitle = 'BezierN'
Global Const $iW = 512
Global Const $iH = 512
Global Const $nBezierPoints = 35
Global $aKontrollPunkte[0]
AddPoint($aKontrollPunkte, 0.1, 0.2)
AddPoint($aKontrollPunkte, 0.1, 0.3)
AddPoint($aKontrollPunkte, 0.3, 0.7)
AddPoint($aKontrollPunkte, 0.6, 0.8)
AddPoint($aKontrollPunkte, 0.9, 0.2)
AddPoint($aKontrollPunkte, 0.9, 0.9)
AddPoint($aKontrollPunkte, 0.5, 0.5)
Func AddPoint(ByRef $a, $x, $y)
Local $z = [$x, $y], $u = UBound($a)
ReDim $a[$u + 1] ; Jaaah macht man ja nur 1x am Anfang. Bitte NICHT oft nutzen, langsam.
$a[$u] = $z
EndFunc
Global $aBezierN = BezierN($aKontrollPunkte, $nBezierPoints)
; Input : Array[i] = Array[2] = [x, y] für beliebige Punktmengen
; Output: Array[i] = Array[2] = [x, y] mit $n Einträgen
Func BezierN(ByRef $aPoints, $n = 25)
Local $u = UBound($aPoints), $aBuf[$u][2], $aRet[$n], $r = 0, $t = 0, $a[2], $b[2], $c[2], $m = 0
For $tt = 0 To $n - 1 Step 1
$t = $tt / ($n - 1)
For $i = 0 To $u - 1 Step 1
$aBuf[$i][0] = $aPoints[$i]
Next
For $sub = 2 To $u Step 1
$m = IsInt($sub/2)
For $i = 0 To $u - $sub Step 1
$a = $aBuf[$i][1-$m]
$b = $aBuf[$i+1][1-$m]
$c[0] = $a[0] + $t * ($b[0] - $a[0])
$c[1] = $a[1] + $t * ($b[1] - $a[1])
$aBuf[$i][$m] = $c
If $sub = $u Then
$aRet[$r] = $aBuf[$i][$m]
$r += 1
EndIf
Next
Next
Next
Return $aRet
EndFunc
Global $bExit = False
_GDIPlus_Startup()
Global $hGUI = GUICreate($sTitle, $iW, $iH)
Global $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Global $hBMP = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGFX)
Global $hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)
Global $hPEN = _GDIPlus_PenCreate()
_GDIPlus_PenSetStartCap($hPEN, 2)
_GDIPlus_PenSetEndCap($hPEN, 2)
_GDIPlus_GraphicsSetSmoothingMode($hBUF, 2)
GUISetOnEvent(-3, 'EVENT', $hGUI)
OnAutoItExitRegister('Xit')
GUISetState(@SW_SHOW, $hGUI)
While Not $bExit And Sleep(10)
_GDIPlus_GraphicsClear($hBUF)
$aBezierN = BezierN($aKontrollPunkte, $nBezierPoints)
Print($aBezierN, 0.015, 0xFFFF6050)
Print($aKontrollPunkte, 0.025, 0xFF808080)
Mouse($aKontrollPunkte)
_GDIPlus_GraphicsDrawImageRect($hGFX, $hBMP, 0, 0, $iW, $iH)
WEnd
Func Mouse(ByRef $aPoints)
Local $mPos = MouseGetPos(), $a[2]
Local Static $iDrag = -1
_GDIPlus_PenSetColor($hPEN, 0xFF80FF00)
_GDIPlus_PenSetWidth($hPEN, (0.035 / 5.0) * $iW)
_GDIPlus_PenSetDashStyle($hPEN, 0)
For $i = 0 To UBound($aPoints) - 1 Step 1
If Sqrt(($mPos[0]/$iW - ($aPoints[$i])[0])^2 + ($mPos[1]/$iH - ($aPoints[$i])[1])^2) < 0.0325 Then
If _IsPressed('01') Then
$iDrag = $i
Else
$iDrag = -1
EndIf
Circle($aPoints[$i], 0.035)
EndIf
Next
If $iDrag <> -1 Then
$a[0] = $mPos[0] / $iW
$a[1] = $mPos[1] / $iH
$aPoints[$iDrag] = $a
EndIf
EndFunc
Func Print(ByRef $aPoints, $d = 0.025, $iCol = 0xFFFFFFFF)
_GDIPlus_PenSetColor($hPEN, $iCol)
_GDIPlus_PenSetWidth($hPEN, ($d / 5.0) * $iW)
_GDIPlus_PenSetDashStyle($hPEN, 0)
For $i = 0 To UBound($aPoints) - 1 Step 1
Circle($aPoints[$i], $d)
Next
_GDIPlus_PenSetWidth($hPEN, ($d / 8.0) * $iW)
_GDIPlus_PenSetDashStyle($hPEN, 1)
For $i = 0 To UBound($aPoints) - 2 Step 1
Line($aPoints[$i], $aPoints[$i+1])
Next
EndFunc
Func Line($p1, $p2)
_GDIPlus_GraphicsDrawLine($hBUF, $p1[0] * $iW, $p1[1] * $iH, $p2[0] * $iW, $p2[1] * $iH, $hPEN)
EndFunc
Func Circle($p, $d)
_GDIPlus_GraphicsDrawEllipse($hBUF, $p[0] * $iW - $d/2 * $iW, $p[1] * $iH - $d/2 * $iH, $d * $iW, $d * $iH, $hPEN)
EndFunc
Func EVENT()
Switch @GUI_CtrlId
Case -3
$bExit = True
EndSwitch
EndFunc
Func Xit()
_GDIPlus_PenDispose($hPEN)
_GDIPlus_GraphicsDispose($hBUF)
_GDIPlus_BitmapDispose($hBMP)
_GDIPlus_GraphicsDispose($hGFX)
_GDIPlus_Shutdown()
EndFunc
Alles anzeigen
lg
M