Hi
Ich schwitze schon seit graumer Zeit an diesem Problem und es ist mir sogar zum Erklären kompliziert genug
Ich will folgendes erreichen:
Ein Mikrofon hat, abhängig von seiner Richtcharakteristik, in jedem Winkel verschiedene Reichweiten.
z.B: Nierenform: von vorne kommen 100% ins Mikro, von hinten 0%
Ein Kugelmikro bekommt von rundherum immer 100% Schall
Nun will ich berechnen, wo bei 2 oder mehr aufgestellten Mikros die Trennlinie verläuft, also wo beide Mikros denselben Schallpegel empfangen
Zum besseren Verständnis bitte mal dieses Script ausführen:
Spoiler anzeigen
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Global Const $PI = ATan(1) * 4
Global Const $Deg2Rad = $PI / 180
Global Const $Rad2Deg = 180 / $PI
Global $iWidth = 800;@DesktopWidth
Global $iHeight = 580;@DesktopHeight
Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Opt("MouseCoordMode", 2)
Global $iWidth = 800;@DesktopWidth
Global $iHeight = 580;@DesktopHeight
_GDIPlus_Startup()
Global $hGui = GUICreate("Test", $iWidth, $iHeight)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
_GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer, 2)
_GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)
Global $hPen = _GDIPlus_PenCreate(0xFF0088FF, 1)
Global $hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00)
GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUISetState(@SW_SHOW, $hGui)
While 1
_Draw()
Sleep(10)
WEnd
Func _CalcPoints($fX, $fY, $fW, $fH, $fPolar, $fAngle)
Local $fX1, $fY1, $fX2, $fY2, $fS1, $fS2, $fA, $fTemp
Local $aPoints[73][2] = [[72]]
For $i = 0 To 71
$fA = $i * 5 * $Deg2Rad ; 0-355 Grad
$fS1 = 1 + 0 * Cos($fA) ; Kugelform
$fS2 = 0.5 + 0.5 * Cos($fA) ; Nierenform
$fTemp = Abs(($fS1 * (1 - $fPolar)) + ($fS2 * $fPolar)) / 2 ; Mischung aus Kugel und Niere
$fX1 = $fTemp * Cos($fA) * $fW ; Länge
$fY1 = $fTemp * Sin($fA) * $fH ; Breite
$fX2 = $fX1 * Cos($fAngle * $Deg2Rad) - $fY1 * Sin($fAngle * $Deg2Rad) ; X um Winkel drehen
$fY2 = $fX1 * Sin($fAngle * $Deg2Rad) + $fY1 * Cos($fAngle * $Deg2Rad) ; Y um Winkel drehen
$aPoints[$i + 1][0] = $fX2 + $fX ; Ergebnis + X Mittelpunkt
$aPoints[$i + 1][1] = $fY2 + $fY ; Ergebnis + Y Mittelpunkt
Next
Return $aPoints
EndFunc ;==>_CalcPoints
Func _Draw()
_GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)
Local $aPnt1 = _CalcPoints(200, 200, 300, 150, 1, 45); Mittelpunkt 200,200; Länge 300; Breite 150; NierenForm; Winkel 45 Grad
Local $aPnt2 = _CalcPoints(300, 200, 300, 150, 1, 90); Mittelpunkt 300,200; Länge 300; Breite 150; NierenForm; Winkel 90 Grad
_GDIPlus_GraphicsDrawClosedCurve($hGfxBuffer, $aPnt1, $hPen)
_GDIPlus_GraphicsDrawClosedCurve($hGfxBuffer, $aPnt2, $hPen)
_GDIPlus_GraphicsFillRect($hGfxBuffer, 200 - 2, 200 - 2, 4, 4, $hBrush)
_GDIPlus_GraphicsFillRect($hGfxBuffer, 300 - 2, 200 - 2, 4, 4, $hBrush)
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
EndFunc ;==>_Draw
Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_PAINT
Func _Exit()
_GDIPlus_PenDispose($hPen)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGfxBuffer)
_GDIPlus_BitmapDispose($hBmpBuffer)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()
Exit
EndFunc ;==>_Exit
Hier wird 360° um den Mitteplunkt die Formel in _CalcPoints angewandt, um die Richtcharakteristik zu berechnen
-------------------------
Erreichen will ich nun wie es folgendes Script zeigt:
Spoiler anzeigen
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Opt("MouseCoordMode", 2)
Global Const $PI = ATan(1) * 4
Global Const $Deg2Rad = $PI / 180
Global Const $Rad2Deg = 180 / $PI
Global $iWidth = 800;@DesktopWidth
Global $iHeight = 580;@DesktopHeight
Global $aMic[33][20] = [[3]]
$aMic[1][0] = 100
$aMic[1][1] = 100
$aMic[1][2] = 45
$aMic[1][3] = 1
$aMic[1][4] = 1.4
$aMic[1][5] = 1
$aMic[2][0] = 600
$aMic[2][1] = 50
$aMic[2][2] = 135
$aMic[2][3] = 1
$aMic[2][4] = 1.4
$aMic[2][5] = 1
$aMic[3][0] = 400
$aMic[3][1] = 500
$aMic[3][2] = 270
$aMic[3][3] = 1
$aMic[3][4] = 1.4
$aMic[3][5] = 1
_GDIPlus_Startup()
Global $hGui = GUICreate("Test", $iWidth, $iHeight)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
_GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer, 2)
_GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)
Global $hPen = _GDIPlus_PenCreate(0xFF00FF00, 1)
[/autoit] [autoit][/autoit] [autoit]GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUISetState(@SW_SHOW, $hGui)
_Draw()
[/autoit] [autoit][/autoit] [autoit]While 1
Sleep(10)
WEnd
Func _Draw()
[/autoit] [autoit][/autoit] [autoit]Local $fX, $fY, $fScale
Local $bAdd
Local $aPath[$aMic[0][0] + 1][3]
[/autoit] [autoit][/autoit] [autoit]Local $aResult
For $i = 1 To $aMic[0][0]
$aResult = DllCall($ghGDIPDll, "uint", "GdipCreatePath", "int", 0, "int*", 0)
$aPath[$i][0] = $aResult[2]
$aPath[$i][1] = DllStructCreate("float[142];")
$aPath[$i][2] = DllStructGetPtr($aPath[$i][1])
Next
For $s = 350 To 500 Step 2
_GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)
For $i = 1 To $aMic[0][0]
For $j = 0 To 70
$fScale = _CalcPolarScale($aMic[$i][2], $j * 5, $aMic[$i][3], $aMic[$i][4], $aMic[$i][5])
$fX = Cos($j * 5 * $Deg2Rad) * $s * $fScale + $aMic[$i][0]
$fY = Sin($j * 5 * $Deg2Rad) * $s * $fScale + $aMic[$i][1]
$bAdd = True
For $k = 1 To $aMic[0][0]
$aResult = DllCall($ghGDIPDll, "uint", "GdipIsVisiblePathPoint", "hwnd", $aPath[$k][0], "float", $fX, "float", $fY, "hwnd", 0, "int*", 0)
If $aResult[5] Then
$bAdd = False
ExitLoop
EndIf
Next
If $bAdd Then
DllStructSetData($aPath[$i][1], 1, $fX, $j * 2 + 1)
DllStructSetData($aPath[$i][1], 1, $fY, $j * 2 + 2)
EndIf
Next
DllCall($ghGDIPDll, "uint", "GdipResetPath", "hwnd", $aPath[$i][0])
DllCall($ghGDIPDll, "uint", "GdipAddPathClosedCurve2", "hwnd", $aPath[$i][0], "ptr", $aPath[$i][2], "int", 71, "float", 0.4)
DllCall($ghGDIPDll, "uint", "GdipDrawPath", "hwnd", $hGfxBuffer, "hwnd", $hPen, "hwnd", $aPath[$i][0])
Next
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
Next
For $i = 1 To $aMic[0][0]
DllCall($ghGDIPDll, "uint", "GdipDeletePath", "hwnd", $aPath[$i][0])
Next
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
EndFunc ;==>_Draw
Func _CalcPolarScale($fA1, $fA2, $fP, $fSX, $fSY)
$fA2 = ($fA2 - $fA1) * $Deg2Rad
Local $fX = Cos($fA2) / $fSX
Local $fY = Sin($fA2) / $fSY
Local $fA = ATan($fY / $fX)
If $fX < 0 Then $fA = $PI + $fA
If $fX >= 0 And $fY < 0 Then $fA = $PI * 2 + $fA
Local $fS1 = 1 + 0 * Cos($fA)
Local $fS2 = 0.5 + 0.5 * Cos($fA)
Local $fT = Abs($fS1 * (1 - $fP) + $fS2 * $fP) / 2
[/autoit] [autoit][/autoit] [autoit]Local $fX1 = $fT * Cos($fA) * $fSX
Local $fY1 = $fT * Sin($fA) * $fSY
Local $fRet = Sqrt($fX1 ^ 2 + $fY1 ^ 2)
If $fRet < 0.01 Then $fRet = 0.01
Return $fRet
EndFunc ;==>_CalcPolarScale
Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_PAINT
Func _Exit()
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hGfxBuffer)
_GDIPlus_BitmapDispose($hBmpBuffer)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()
Exit
EndFunc ;==>_Exit
Grob gesagt hab ich eine Formel, die um jeden Winkel um die eigene Achse verschienden Ergebnisse liefert und ich will herausfinden, wo die Grenze zwischen mehreren Mittelpunkten liegt...
Kann man das überhaupt berechnen, oder ist mein zweites Script (immer Bereich vergrößern und überprüfen, ob ein Punkt schon im "fremden" Bereich liegt) schon die beste Lösung?!
Ich hoffe, ich hab mein Anliegen gut genug erklärt, denn ich bin am Ende meines Lateins
Danke