#include <GDIPlus.au3>

Opt("GUIOnEventMode", 1)

Global $hGUI, $hGraphic, $hBitmap, $hBackbuffer
Global $aGUIDIm[2] = [710, 300]
Global $aGraphicsRect[4] = [0, 0, 800, 300]

Global $aCircleRect[4] = [50, 50, 200, 200]
Global $aSinusRect[4] = [300, 50, 360, 200]
Global $aBrushes[10], $aPens[10]

Global $fPi = 3.14159265358979
Global $fDegToRad = $fPi / 180
Global $nPhi = 0

Global $iFrequency = 1, $iAmplitude = $aSinusRect[3] / 2, $iPhase = 0, $iLength = 380

$hGUI = GUICreate("Sinus im Einheitskreis by Nestos", $aGUIDIm[0], $aGUIDIm[1], -1, -1)
	GUISetOnEvent(-3, "_Exit")

	GUICtrlCreateGraphic($aGraphicsRect[0], $aGraphicsRect[1], $aGraphicsRect[2], $aGraphicsRect[3])
		$hGraphic = GUICtrlGetHandle(-1)

GUISetState()

_Startup()

While 1
	Sleep(10)
	_Draw()
	$nPhi += 0.5
WEnd

Func _Draw()
	_GDIPlus_GraphicsFillRect($hBackbuffer, 0, 0, $aGraphicsRect[2], $aGraphicsRect[3], $aBrushes[0])
	_GDIPlus_GraphicsDrawRect($hBackbuffer, 0, 0, $aGraphicsRect[2] - 1, $aGraphicsRect[3] - 1)

	_GDIPlus_GraphicsDrawLine($hBackbuffer, $aCircleRect[0], $aCircleRect[1] + ($aCircleRect[3] / 2), $aCircleRect[0] + $aCircleRect[2], $aCircleRect[1] + ($aCircleRect[3] / 2))
	_GDIPlus_GraphicsDrawLine($hBackbuffer, $aCircleRect[0] + ($aCircleRect[2] / 2), $aCircleRect[1], $aCircleRect[0] + ($aCircleRect[2] / 2), $aCircleRect[1] + $aCircleRect[3])

	_GDIPlus_GraphicsDrawLine($hBackbuffer, $aCircleRect[0] + ($aCircleRect[2] / 2), _
								$aCircleRect[1] + ($aCircleRect[3] / 2), _
								$aCircleRect[0] + ($aCircleRect[2] / 2) + (Cos($nPhi * $fDegToRad) * $iAmplitude), _
								$aCircleRect[1] + ($aCircleRect[3] / 2) - (Sin($nPhi * $fDegToRad) * $iAmplitude))

	_GDIPlus_GraphicsDrawArc($hBackbuffer, $aCircleRect[0] + ($aCircleRect[2] / 2) - 20, $aCircleRect[1] + ($aCircleRect[3] / 2) - 20, 40, 40, 0, -Mod($nPhi, 360), $aPens[3])

	_GDIPlus_GraphicsDrawLine($hBackbuffer, $aCircleRect[0] + ($aCircleRect[2] / 2) + (Cos($nPhi * $fDegToRad) * $iAmplitude), _
								$aCircleRect[1] + ($aCircleRect[3] / 2) - (Sin($nPhi * $fDegToRad) * $iAmplitude), _
								$aCircleRect[0] + ($aCircleRect[2] / 2) + (Cos($nPhi * $fDegToRad) * $iAmplitude), _
								$aCircleRect[1] + ($aCircleRect[3] / 2), $aPens[2])

	_GDIPlus_GraphicsDrawEllipse($hBackbuffer, $aCircleRect[0], $aCircleRect[1], $aCircleRect[2], $aCircleRect[3], $aPens[1])

	_GDIPlus_GraphicsDrawLine($hBackbuffer, $aCircleRect[0] + ($aCircleRect[2] / 2) + (Cos($nPhi * $fDegToRad) * $iAmplitude), _
			$aCircleRect[1] + ($aCircleRect[3] / 2) - (Sin($nPhi * $fDegToRad) * $iAmplitude), _
			$aSinusRect[0] + Mod($nPhi, 360) * $iFrequency, _
			$aSinusRect[1] + ($aSinusRect[3] / 2) - (Sin($nPhi * $fDegToRad) * $iAmplitude))

	_GDIPlus_GraphicsDrawLine($hBackbuffer, $aSinusRect[0] + Mod($nPhi, 360) * $iFrequency, _
								$aSinusRect[1] + ($aSinusRect[3] / 2) - (Sin($nPhi * $fDegToRad) * $iAmplitude), _
								$aSinusRect[0] + Mod($nPhi, 360) * $iFrequency, _
								$aSinusRect[1] + ($aSinusRect[3] / 2), $aPens[2])

	_GDIPlus_GraphicsDrawLine($hBackbuffer, $aSinusRect[0], $aSinusRect[1] + $iAmplitude, $aSinusRect[0] + $aSinusRect[2], $aSinusRect[1] + $iAmplitude)
	For $i = 0 To Int($aSinusRect[2] / (90 / $iFrequency))
		_GDIPlus_GraphicsDrawLine($hBackbuffer, $aSinusRect[0] + (90 / $iFrequency) * $i, $aSinusRect[1] - 10, $aSinusRect[0] + (90 / $iFrequency) * $i, $aSinusRect[1] + $aSinusRect[3] + 10, $aPens[0])
	Next
	_GDIPlus_GraphicsDrawSinus($hBackbuffer, $aSinusRect[0], $aSinusRect[1], $aSinusRect[2], $iFrequency, $iAmplitude, $iPhase, $aPens[1])

	_GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 0)
EndFunc   ;==>_Draw

Func _Startup()
	_GDIPlus_Startup()
	$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGraphic)
	_GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2)
	$hBitmap = _GDIPlus_BitmapCreateFromGraphics($aGraphicsRect[2], $aGraphicsRect[3], $hGraphic)
	$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
	_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)

	$aBrushes[0] = _GDIPlus_BrushCreateSolid(0xFFEEEEEE)
	$aPens[0] = _GDIPlus_PenCreate(0xFF000000)
	_GDIPlus_PenSetDashStyle($aPens[0], $GDIP_DASHSTYLEDASH)
	$aPens[1] = _GDIPlus_PenCreate(0xFF0000FF, 2)
	$aPens[2] = _GDIPlus_PenCreate(0xFFFF0000, 2)
	$aPens[3] = _GDIPlus_PenCreate(0xFF00AA00, 2)
EndFunc   ;==>_Startup

Func _Exit()
	For $i = 0 To UBound($aBrushes) - 1
		_GDIPlus_BrushDispose($aBrushes[$i])
	Next
	For $i = 0 To UBound($aPens) - 1
		_GDIPlus_PenDispose($aPens[$i])
	Next
	_GDIPlus_GraphicsDispose($hBackbuffer)
	_GDIPlus_BitmapDispose($hBitmap)
	_GDIPlus_GraphicsDispose($hGraphic)
	_GDIPlus_Shutdown()
	Exit
EndFunc   ;==>_Exit

Func _GDIPlus_GraphicsDrawSinus($hGraphic, $iX, $iY, $iLength, $iFrequency, $iAmplitude, $iPhase, $hPen = 0)
	Local $fPi = 3.14159265358979
	Local $fDegToRad = $fPi / 180
	Local $iPointCount = $iLength * $iFrequency
	Local $aPoints[$iPointCount + 1][2] = [[$iPointCount]]

	For $i = 0 To $iPointCount - 1
		$aPoints[$i + 1][0] = $iX + ($i / $iFrequency)
		$aPoints[$i + 1][1] = $iY + $iAmplitude - (Sin(($i + $iPhase) * $fDegToRad) * $iAmplitude)
	Next
	_GDIPlus_GraphicsDrawCurve($hGraphic, $aPoints, $hPen)
EndFunc   ;==>_GDIPlus_GraphicsDrawSinus

Func _GDIPlus_GraphicsDrawCosinus($hGraphic, $iX, $iY, $iLength, $iFrequency, $iAmplitude, $iPhase, $hPen = 0)
	Local $fPi = 3.14159265358979
	Local $fDegToRad = $fPi / 180
	Local $iPointCount = $iLength * $iFrequency
	Local $aPoints[$iPointCount + 1][2] = [[$iPointCount]]

	For $i = 0 To $iPointCount - 1
		$aPoints[$i + 1][0] = $iX + ($i / $iFrequency)
		$aPoints[$i + 1][1] = $iY + $iAmplitude + (Cos(($i + $iPhase) * $iPointCount) * $iAmplitude)
	Next
	_GDIPlus_GraphicsDrawCurve($hGraphic, $aPoints, $hPen)
EndFunc   ;==>_GDIPlus_GraphicsDrawCosinus
