Schnittpunkt von 2 Kreisen

  • Hey :) ,

    ich hab mal eine etwas mathematischere Frage... In einem Koordinatensystem liegen zwei Punkte, A und B. Ihre Koordinaten sowie auch die Strecke zwischen ihnen sind bekannt. Die Koordinaten eines Punkt N, der auf der Strecke AB liegt, sind gesucht. Außerdem sind die Strecken AN und BN bekannt. Nun bin ich auf die Idee gekommen, dass man um A und B jeweils einen Kreis mit dem Radius AN beziehungsweise BN annehmen könnte. Wenn man nun den Schnittpunkt der beiden Kreise berechnen würde, hätte man die Koordinaten des Punktes N. Also habe ich mir gedacht: "Jetzt setze ich einfach die beiden Formeln gleich und..." aber genau da liegt mein Problem! Mir und meiner Formelsammlung ist keine Kreis-Formel bekannt, die Mittelpunkt und Radius/Durchmesser beinhaltet... ?(
    Also noch einmal zusammengefasst:
    Gegeben: Punkt A, Punkt B, Strecke AB, Strecke AN, Strecke BN
    Gesucht: Punkt N
    Das ganze habe ich schnell auch noch aufgemalt... ^^

  • Hi

    ich hab vor einiger Zeit mal dieses Testscript erstellt, das könnte dir weiterhelfen:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)
    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    Global $iWidth = 800
    Global $iHeight = 600

    [/autoit] [autoit][/autoit] [autoit]

    Global $aL1[4] = [Random(0, $iWidth), Random(0, $iHeight), Random(0, $iWidth), Random(0, $iHeight)]
    Global $aL2[4] = [Random(0, $iWidth), Random(0, $iHeight), 0, 0]

    [/autoit] [autoit][/autoit] [autoit]

    Global $aC1[3] = [$iWidth / 4 + Random(0, $iWidth / 2), $iHeight / 4 + Random(0, $iHeight / 2), Random(100, $iWidth / 4)]
    Global $aC2[3] = [$iWidth / 4 + Random(0, $iWidth / 2), $iHeight / 4 + Random(0, $iHeight / 2), Random(100, $iWidth / 4)]

    [/autoit] [autoit][/autoit] [autoit]

    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)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hPen = _GDIPlus_PenCreate(0xFF00AA00, 2)
    Global $hPen2 = _GDIPlus_PenCreate(0xFFFF0000, 2)
    Global $hPen3 = _GDIPlus_PenCreate(0xFF0000FF, 2)

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUIRegisterMsg($WM_ERASEBKGND, "WM_PAINT")
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    Global $aInfo, $bClick
    While 1
    Sleep(10)
    $aInfo = GUIGetCursorInfo()

    [/autoit] [autoit][/autoit] [autoit]

    Switch $aInfo[2]
    Case True
    If Not $bClick Then _Random()
    $bClick = True
    Case Else
    $bClick = False
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    $aL2[2] = $aInfo[0]
    $aL2[3] = $aInfo[1]
    $aC2[2] = Sqrt(($aInfo[0] - $aC2[0]) ^ 2 + ($aInfo[1] - $aC2[1]) ^ 2)

    [/autoit] [autoit][/autoit] [autoit]

    _Intersect($aL1, $aL2, $aC1, $aC2)

    [/autoit] [autoit][/autoit] [autoit]

    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Random()
    $aL1[0] = Random(0, $iWidth)
    $aL1[1] = Random(0, $iHeight)
    $aL1[2] = Random(0, $iWidth)
    $aL1[3] = Random(0, $iHeight)
    $aL2[0] = Random(0, $iWidth)
    $aL2[1] = Random(0, $iHeight)

    [/autoit] [autoit][/autoit] [autoit]

    $aC1[0] = $iWidth / 4 + Random(0, $iWidth / 2)
    $aC1[1] = $iHeight / 4 + Random(0, $iHeight / 2)
    $aC1[2] = Random(100, $iWidth / 4)
    $aC2[0] = $iWidth / 4 + Random(0, $iWidth / 2)
    $aC2[1] = $iHeight / 4 + Random(0, $iHeight / 2)
    $aC2[2] = Random(100, $iWidth / 4)

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Random

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Intersect($aL1, $aL2, $aC1, $aC2)
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFFFFFFFF)
    DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $hGfxBuffer, "handle", $hPen2, "float", $aL1[0], "float", $aL1[1], "float", $aL1[2], "float", $aL1[3])
    DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $hGfxBuffer, "handle", $hPen3, "float", $aL2[0], "float", $aL2[1], "float", $aL2[2], "float", $aL2[3])

    [/autoit] [autoit][/autoit] [autoit]

    Local $fX, $fY

    [/autoit] [autoit][/autoit] [autoit]

    Local $bIntersect = _Intersect_Lines($aL1[0], $aL1[1], $aL1[2], $aL1[3], $aL2[0], $aL2[1], $aL2[2], $aL2[3], $fX, $fY)
    Switch $bIntersect
    Case True
    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen, "float", $fX - 10, "float", $fY - 10, "float", 20, "float", 20)
    Case Else
    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen2, "float", $fX - 10, "float", $fY - 10, "float", 20, "float", 20)
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen, "float", $aC1[0] - $aC1[2], "float", $aC1[1] - $aC1[2], "float", $aC1[2] * 2, "float", $aC1[2] * 2)
    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen, "float", $aC2[0] - $aC2[2], "float", $aC2[1] - $aC2[2], "float", $aC2[2] * 2, "float", $aC2[2] * 2)

    [/autoit] [autoit][/autoit] [autoit]

    Local $fX1, $fY1, $fX2, $fY2
    $bIntersect = _Intersect_Circles($aC1[0], $aC1[1], $aC1[2], $aC2[0], $aC2[1], $aC2[2], $fX1, $fY1, $fX2, $fY2)
    Switch $bIntersect
    Case True
    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen, "float", $fX1 - 10, "float", $fY1 - 10, "float", 20, "float", 20)
    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen, "float", $fX2 - 10, "float", $fY2 - 10, "float", 20, "float", 20)
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    EndFunc ;==>_Intersect

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_PAINT

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_PenDispose($hPen2)
    _GDIPlus_PenDispose($hPen3)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Intersect_Circles($fCX1, $fCY1, $fR1, $fCX2, $fCY2, $fR2, ByRef $fX1, ByRef $fY1, ByRef $fX2, ByRef $fY2)
    Local $fDX = $fCX2 - $fCX1
    Local $fDY = $fCY2 - $fCY1
    Local $fD = Sqrt(($fDY * $fDY) + ($fDX * $fDX))

    [/autoit] [autoit][/autoit] [autoit]

    If ($fD > ($fR1 + $fR2)) Then Return False
    If ($fD < Abs($fR1 - $fR2)) Then Return False

    [/autoit] [autoit][/autoit] [autoit]

    Local $fA = (($fR1 * $fR1) - ($fR2 * $fR2) + ($fD * $fD)) / (2 * $fD)

    [/autoit] [autoit][/autoit] [autoit]

    Local $fX = $fCX1 + ($fDX * $fA / $fD)
    Local $fY = $fCY1 + ($fDY * $fA / $fD)

    [/autoit] [autoit][/autoit] [autoit]

    Local $fH = Sqrt(($fR1 * $fR1) - ($fA * $fA))

    [/autoit] [autoit][/autoit] [autoit]

    Local $fRX = (0 - $fDY) * ($fH / $fD)
    Local $fRY = $fDX * ($fH / $fD)

    [/autoit] [autoit][/autoit] [autoit]

    $fX1 = $fX + $fRX
    $fY1 = $fY + $fRY
    $fX2 = $fX - $fRX
    $fY2 = $fY - $fRY

    [/autoit] [autoit][/autoit] [autoit]

    Return True
    EndFunc ;==>_Intersect_Circles

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Intersect_Lines($fL1X1, $fL1Y1, $fL1X2, $fL1Y2, $fL2X1, $fL2Y1, $fL2X2, $fL2Y2, ByRef $fX, ByRef $fY)
    Local $iOnX1, $iOnY1, $iOnX2, $iOnY2
    Local $fDet, $fA1, $fB1, $fC1, $fA2, $fB2, $fC2

    [/autoit] [autoit][/autoit] [autoit]

    $fA1 = $fL1Y2 - $fL1Y1
    $fB1 = $fL1X1 - $fL1X2
    $fC1 = $fA1 * $fL1X1 + $fB1 * $fL1Y1

    [/autoit] [autoit][/autoit] [autoit]

    $fA2 = $fL2Y2 - $fL2Y1
    $fB2 = $fL2X1 - $fL2X2
    $fC2 = $fA2 * $fL2X1 + $fB2 * $fL2Y1

    [/autoit] [autoit][/autoit] [autoit]

    $fDet = $fA1 * $fB2 - $fA2 * $fB1
    If $fDet = 0 Then Return 0

    [/autoit] [autoit][/autoit] [autoit]

    $fX = ($fB2 * $fC1 - $fB1 * $fC2) / $fDet
    $fY = ($fA1 * $fC2 - $fA2 * $fC1) / $fDet

    [/autoit] [autoit][/autoit] [autoit]

    If $fL1X1 < $fL1X2 Then
    $iOnX1 = ($fX >= $fL1X1) And ($fX <= $fL1X2)
    Else
    $iOnX1 = ($fX <= $fL1X1) And ($fX >= $fL1X2)
    EndIf
    If $fL1Y1 < $fL1Y2 Then
    $iOnY1 = ($fY >= $fL1Y1) And ($fY <= $fL1Y2)
    Else
    $iOnY1 = ($fY <= $fL1Y1) And ($fY >= $fL1Y2)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $fL2X1 < $fL2X2 Then
    $iOnX2 = ($fX >= $fL2X1) And ($fX <= $fL2X2)
    Else
    $iOnX2 = ($fX <= $fL2X1) And ($fX >= $fL2X2)
    EndIf
    If $fL2Y1 < $fL2Y2 Then
    $iOnY2 = ($fY >= $fL2Y1) And ($fY <= $fL2Y2)
    Else
    $iOnY2 = ($fY <= $fL2Y1) And ($fY >= $fL2Y2)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return $iOnX1 And $iOnY1 And $iOnX2 And $iOnY2
    EndFunc ;==>_Intersect_Lines

    [/autoit]

    Die Formeln stammen glaub ich aus diesem Forum, aber ich weiß nicht mehr, von wem...
    Linke Maustaste drücken -> neue zufällige Positionen.

    wichtig für dich ist die Funktion _Intersect_Circles, da kannst du den Mittelpunkt der 2 Kreise und den Radius angeben.
    Der Returnwert ist True, wenn sich die Kreise schneiden, anderenfalls False.
    Die Schnittpunkte werden byref übergeben.


    Falls der Punkt N genau in der Mitte liegt oder du das Teilungsverhältnis kennst, dann geht das aber viel einfacher:

    [autoit]

    $fXN = $fXA + ($fXB - $fXA) / 2
    $fYN = $fYA + ($fYB - $fYA) / 2

    [/autoit]
    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <Math.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)
    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    Global $iWidth = 800
    Global $iHeight = 600

    [/autoit] [autoit][/autoit] [autoit]

    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)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hPen = _GDIPlus_PenCreate(0xFF00AA00, 2)
    Global $hPen2 = _GDIPlus_PenCreate(0xFFFF0000, 2)
    Global $hPen3 = _GDIPlus_PenCreate(0xFF0000FF, 2)

    [/autoit] [autoit][/autoit] [autoit]

    _Test(Random(0, $iWidth), Random(0, $iHeight), Random(0, $iWidth), Random(0, $iHeight))

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUIRegisterMsg($WM_ERASEBKGND, "WM_PAINT")
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $aInfo, $bClick
    While 1
    Sleep(10)
    $aInfo = GUIGetCursorInfo()

    [/autoit] [autoit][/autoit] [autoit]

    Switch $aInfo[2]
    Case True
    If Not $bClick Then _Test(Random(0, $iWidth), Random(0, $iHeight), Random(0, $iWidth), Random(0, $iHeight))
    $bClick = True
    Case Else
    $bClick = False
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Test($fXA, $fYA, $fXB, $fYB)
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFFFFFFFF)
    DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $hGfxBuffer, "handle", $hPen2, "float", $fXA, "float", $fYA, "float", $fXB, "float", $fYB)
    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen2, "float", $fXA - 10, "float", $fYA - 10, "float", 20, "float", 20)
    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen2, "float", $fXB - 10, "float", $fYB - 10, "float", 20, "float", 20)

    [/autoit] [autoit][/autoit] [autoit]

    Local $fXN, $fYN

    [/autoit] [autoit][/autoit] [autoit]

    ;Version 1:
    $fXN = $fXA + ($fXB - $fXA) / 2
    $fYN = $fYA + ($fYB - $fYA) / 2
    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen, "float", $fXN - 10, "float", $fYN - 10, "float", 20, "float", 20)

    [/autoit] [autoit][/autoit] [autoit]

    ;Version 2:
    Local $fAngle, $fDist
    $fAngle = _Atan2($fYB - $fYA, $fXB - $fXA)
    $fDist = Sqrt(($fXB - $fXA) ^ 2 + ($fYB - $fYA) ^ 2) / 2
    $fXN = $fXA + Cos($fAngle) * $fDist
    $fYN = $fYA + Sin($fAngle) * $fDist
    DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfxBuffer, "handle", $hPen3, "float", $fXN - 15, "float", $fYN - 15, "float", 30, "float", 30)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    EndFunc ;==>_Test

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_PAINT

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_PenDispose($hPen2)
    _GDIPlus_PenDispose($hPen3)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]


    E

  • Hi,
    ich verstehe ehrlich gesagt das Problem nicht....
    ALLE Variablen sind gegeben, nur noch einzusetzen in beliebige Formeln...Sin(),Cos(), Strahlensatz...alles verwendbar

    Bsp:

    [autoit]


    ;gegeben
    $ax=2;koordinaten A und B
    $ay=3
    $bx=8
    $by=10

    [/autoit][autoit][/autoit][autoit]

    $AB=sqrt(($bx-$ax)^2+($by-$ay)^2);länge AB

    [/autoit][autoit][/autoit][autoit]

    $AN=4 ;Länge AN

    [/autoit][autoit][/autoit][autoit]

    ;gesucht, Koordinaten nx und ny
    $nx=($bx-$ax)/$AB*$AN+$ax
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $nx = ' & $nx & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $ny=($by-$ay)/$AB*$AN+$ay
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ny = ' & $ny & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit]