Dieses Forum nutzt Cookies
Dieses Forum verwendet Cookies, um deine Login-Informationen zu speichern, wenn du registriert bist, und deinen letzten Besuch, wenn du es nicht bist. Cookies sind kleine Textdokumente, die auf deinem Computer gespeichert werden. Die von diesem Forum gesetzten Cookies werden nur auf dieser Website verwendet und stellen kein Sicherheitsrisiko dar. Cookies aus diesem Forum speichern auch die spezifischen Themen, die du gelesen hast und wann du zum letzten Mal gelesen hast. Bitte bestätige, ob du diese Cookies akzeptierst oder ablehnst.

Ein Cookie wird in deinem Browser unabhängig von der Wahl gespeichert, um zu verhindern, dass dir diese Frage erneut gestellt wird. Du kannst deine Cookie-Einstellungen jederzeit über den Link in der Fußzeile ändern.

Nautiker sind gefragt
#11
Hi,

deine Forderung ist eine nicht triviale Rechnung. Google mal nach Haversine-Formel.

Bei deinen 100 Metern ist die Abweichung zu normaler ebener Betrachtung zwar nicht sehr groß, Aber allein die Tatsache, dass der Abstand zwischen zwei Längengraden immer kleiner wird, je weiter man nach Norden kommt, macht eine Berechnung nicht trivial. Am Äquator beträgt dieser ca. 111km, am Wendekreis 102km, am Polarkreis 44km und bei 89° Breite nur noch knapp 2km.
Der Abstand zwischen zwei Breitengraden beträgt immer ca. 111km
Gruß,
Helmut

Win10 - Office365 / MacOS - Office365
Antworten Top
#12
Hallo,

ich habe von Nautik keine Ahnung. Aber ich fand's interessant. Ich habe bemerkt, dass ich mich noch nie wirklich mit Ellipsen befasst habe Dodgy .

Zunächst ist ja bisher völlig unklar, wie das mit der Länge der Ankerkette und der Wassertiefe (die Kette hängt ja schließlich auch durch etc.) sein soll. Exakt berechnen kann man auch den Durchhang, doch dazu wirst du nicht die nötigen Angaben liefern können (also man kann es nur in der Theorie exakt berechnen ... in der Praxis weißt du halt überhaupt nicht, mit welcher Kraft an der Kette gezogen wird, sie gespannt wird, was sich ja auch ständig ändert ...). Auf die Genauigkeit wird es ja wahrscheinlich auch nicht ankommen?!
Ich habe diese Problematik jetzt mal außen vor gelassen und mich gefragt, wie man Punkte in einem bestimmten Abstand zu einem Punkt auf der Erdoberfläche findet.

Grundsätzlich:
Wenn du eine Angabe in Grad, Minuten und Sekunden hast, dann kannst du sie in Dezimalgrad (eine Dezimalzahl) umrechnen:

Dezimalgrad = Grad + Minuten/60 + Sekunden/3600


Alle Punkte in einem bestimmten Abstand auf der Wasseroberfläche zu finden, ist nicht einfach (so man von einem Rotationsellipsoid ausgeht, Kugel wäre da deutlich einfacher). Die vier Punkte nach Norden, Osten, Süden und Westen sind bei einem Rotationsellipsoid relativ leicht, da hatte ich gerade mal Lust, das zu programmieren:

Code:
Option Explicit

Sub Punkte_im_Norden_Osten_Sueden_Westen()
Dim L As Double, B As Double    'Länge, Breite [Dezimalgrad]
Dim Distanz As Double          'in [m]
'            (nl,nb)
'    (wl,wb)  (L,B)  (ol,ob)
'            (sl,sb)
Dim nl As Double, nb As Double, wl As Double, wb As Double
Dim ol As Double, ob As Double, sl As Double, sb As Double
Dim PI As Double, t As Double, t1 As Double
PI = 4 * Atn(1)

'Position
B = 53.90972222 'Breite [Dezimalgrad]
L = 20.9075    'Länge  [Dezimalgrad]

'Distanz auf der Erdoberfläche in [m]
Distanz = 100


'Konstanten des Referenzellipsoids. Ich tippe mal auf WGS84 (siehe: https://de.wikipedia.org/wiki/Referenzellipsoid)
Const r1 As Double = 6378137      'groß e Halbachse [m]
Const r2 As Double = 6356752.3142  'kleine Halbachse [m]
t = Parameter_T_aus_Breite(B, r1, r2)  't der Parameterdarstellung der Ellipse eines Längengrades x=r1*cos(t), y=r2*sin(t)

'Punkt im Osten:
ob = B
ol = L + (Distanz / (r1 * Cos(t))) * 180 / PI

'Punkt im Westen:
wb = B
wl = L - (Distanz / (r1 * Cos(t))) * 180 / PI

'Punkt im Norden (Näherung mit Sekante)
t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, True)
nb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180
nl = L

'Punkt im Süden (Näherung mit Sekante)
t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, False)
sb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180
sl = L

Debug.Print "Ankerpunkt: ", B, L, Grad2String(B, L)
Debug.Print "Norden      ", nb, nl, Grad2String(nb, nl)
Debug.Print "Osten      ", ob, ol, Grad2String(ob, ol)
Debug.Print "Süden      ", sb, sl, Grad2String(sb, sl)
Debug.Print "Westen      ", wb, wl, Grad2String(wb, wl)
End Sub


Private Function Parameter_T_aus_Breite(phi As Double, r1 As Double, r2 As Double) As Double
'phi - geogr. Breite  [Grad]  bzw.  [Dezimalgrad]
'die Parametergleichung einer Elipse lautet  x = r1*cos(t),  y = r2*sin(t)    mit  -pi <= t <= pi
'die Funktion gibt den Parameter t zurück, der den Winkel phi = arctan(y/x) repräsentiert.
'Der Rückgabewert der Funktion liegt immer zwischen -pi/2 und pi/2
Dim PI As Double, t As Double, dt As Double, x As Double, y As Double, B As Double, phi_ As Double
Dim LoopCounter As Long
PI = 4 * Atn(1)

B = Abs(phi) / 180 * PI  'abs(Breite im Bogenmaß)
t = 0
dt = PI / 10
Do
  t = t + dt
  x = r1 * Cos(t)
  y = r2 * Sin(t)
  phi_ = Atn(y / x)
  If phi_ > B Then
    t = t - dt
    dt = dt / 2
  End If
  LoopCounter = LoopCounter + 1
  If LoopCounter > 100000 Then
    MsgBox "Probleme mit der Iteration"
    Stop
  End If
Loop While Abs(phi_ - B) > 0.000000001
Debug.Print "Iterationsschritte zur Ermittlung von t: ", LoopCounter
Parameter_T_aus_Breite = IIf(phi < 0, -t, t)
End Function


Private Function Punkt_auf_Ellipse_In_Entfernung(t As Double, r1 As Double, r2 As Double, _
                                                Distanz As Double, Optional nachNorden As Boolean = True) As Double
't, r1, r2  repräsentieren einen Punkt x=r1*cos(t), y=r2*sin(t)  auf einer Ellipse
'die Funktion gibt den Parameter t2 zurück, der einen Punkt auf der Ellipse repräsentiert, der
'  in der Entfernung Distanz entfernt liegt.
Dim t1 As Double, dt As Double, x As Double, y As Double, x1 As Double, y1 As Double, s As Double, PI As Double
Dim LoopCounter As Long
PI = 4 * Atn(1)
t1 = t
dt = PI * Distanz / ((r1 + r2) / 2) * IIf(nachNorden, 1, -1)
x = r1 * Cos(t):    y = r2 * Sin(t)
Do
  t1 = t1 + dt
  x1 = r1 * Cos(t1): y1 = r2 * Sin(t1)
  s = Sqr((x - x1) ^ 2 + (y - y1) ^ 2)    'Länge des Sekantenabschnitts
  If s > Distanz Then
    t1 = t1 - dt
    dt = dt / 2
  End If
  LoopCounter = LoopCounter + 1
  If LoopCounter > 100000 Then
    MsgBox "Probleme mit der Iteration"
    Stop
  End If
Loop While Abs(s - Distanz) > Distanz / 500 '20cm
Debug.Print "LoopCounter " & IIf(nachNorden, "Norden: ", "Süden: "), LoopCounter
Punkt_auf_Ellipse_In_Entfernung = t1
End Function


Private Function Grad2String(Breite As Double, Lange As Double)
Dim grad As Integer, min As Integer, sek As Double, resString As String
grad = Int(Breite)
min = Int((Breite - grad) * 60)
sek = (Breite - grad - min / 60) * 3600
resString = grad & "° " & min & "' " & Round(sek, 6) & "''  "
grad = Int(Lange)
min = Int((Lange - grad) * 60)
sek = (Lange - grad - min / 60) * 3600
resString = resString & grad & "° " & min & "' " & Round(sek, 6) & "''"
Grad2String = resString
End Function

Der Code ist jetzt nicht ausgiebig getestet und über numerische Besonderheiten (z.B. Vorzeichen, Vorzeichenwechsel am Äquator / den Polen) habe ich mir keine Gedanken gemacht. Das testen kannst du ja übernehmen. Vielleicht klinkt sich ja auch noch jemand ein, der Ahnung hat?!

Wie sieht das denn aus, du sagst, du möchtest den Kreis um deinen Ankerpunkt herum im N 00° 00' 00''   E 00° 00' 00'' Format haben. Eine Kreisline hat ja nun unendlich viele Punkte ????  -  würden dir die vier denn ausreichen?

Schau mal hier https://de.wikipedia.org/wiki/Referenzel...ellipsoide werden Koordinatensysteme/Referenzsysteme aufgezählt. Mit welchem arbeitest du denn (wie gesagt, ich habe von Nautik keine Ahnung!)?

Grüße, Ulrich

PS: hier gibt es einen Entfernungsrechner: https://rechneronline.de/geo-koordinaten/ wenn du dich kontrollieren möchtest. Ich habe allerdings keine Ahnung, was für Koordinatenangaben in welchem Koordinatensystem der erwartet.
Antworten Top
#13
Huh Sagt doch einfach: geht nicht  Angry

Nein Quatsch, ich bedanke mich für die wirklich guten und spannenden Antworten und werde es halt weiterhin händisch auf der Papierseekarte ermitteln und in den Bogen für die Ankerwache eintragen.

Zu den Antworten bzgl. der Wassertiefe und der durchhängenden Katte: ja das ist alles richtig!
Ich weiß aber ja, wieviel Kette ausgesteckt wurde und kann mir dann über die Wassertiefe (aus der Karte zu entnehmen) bei maximal gestreckter Kette über den Pythagoras den Kreis errechnen - weiter "darf" sich das Schiffe halt nicht vom Ankerplatz - von dem ich die Koordinaten ja geplottet habe - entfernen. Dazu muss ich dann eben die N S E W Koordinaten eintragen und die Wache muss sie mit dem GPS System vergleichen.
Und auch die Antworten bzgl der Abstände zwischen den Längengraden sind richtig und zu berücksichtigen! 
Nochmals vielen Dank  15
Antworten Top
#14
Du bist Nautiker, du weißt also, wie man das ganze berechnet. Allerdings weißt du nicht, wie man es in Excel umsetzt. 

Dann ist der richtige Weg: Zeige DU UNS den Rechenweg, wir zeigen dir dann, wie es in Excel umgesetzt wird. 

Dass "traditionelle" Segler GPS und Excelmappen verwenden, verwundert mich Landratte dann allerdings schon. "Seglertradition" scheint maximal in Dekaden zu denken, nicht in Hektoden.
Antworten Top
#15
Hallo,

ich glaube, du hast mich falsch verstanden: das war ein in weiten Teilen funktionierender (noch anzupassender) Lösungsvorschlag!

Du scheinst eine fertige Datei haben zu wollen. Das ist normalerweise nicht so meine Freude beim Helfen, aber ich hatte gerade nochmal Zeit und irgendwie finde ich die Fragestellung (in Teilen) auch interessant.

Ich habe dir eine Mappe gemacht. 

Wenn man die Erde als eine Kugel annimmt (weißt du, welchen Radius ich da annehmen sollte?), dann sind die Berechnungen (abgesehen von den Polen/Equator 0° Länge und 180° Länge) wirklich für 99% aller Fälle äußerst simpel:
Länge = Länge_Ankerpunkt + (Distanz / Erdradius) * 180 / Pi
Breite = Breite_Ankerpunkt + (Distanz / Erdradius) * 180 / Pi
mit Distanz meine ich deine 100 m bzw. Ankerkettenlänge bzw. Projektion dieser auf die Wasseroberfläche ...
Länge_Ankerpunkt und Breite_Ankerpunkt muss dabei als Dezimalgrad vorliegen
Das könnte man auch gut und einfach mit Formeln in Excel umsetzen. Vielleicht hilft dir jemand dabei - ich habe da keinen Spaß dran.

Ich habe gerade einige Fehler meines Lösungsvorschlags ausgemerzt und das ganze in Funktionen verpackt, sodass du es vom Tabellenblatt mit einer Formel aufrufen kannst. Dabei habe ich sowohl einen Vorschlag für die Näherung der Erde als Kugel, als auch einen für die Erde als Parallelellipsoid.

Die Formel geben ein ganzes Array zurück, sind also Matrix-Formeln. Du rufst sie mit folgenden Parametern auf:
udf_ankerkreis_kugel(Distanz, Breite, Länge)
udf_ankerkreis_ellipsoid(Distanz, Breite, Länge)
Dabei wird muss die Distanz in Meter angegeben sein.
Die Breite und Länge müssen als Dezimalzahl (Dezimalgrad) angegeben werden.

Hier der Code für alle, die es interessiert:
Code:
Option Explicit

Function udf_ankerkreis_kugel(ByVal Distanz As Double, B As Double, L As Double, Optional Dezimalgrad As Boolean = False)
    'Distanz - [m]
    'B      - geogr. Breite [Dezimalgrad] mit Vorzeichen!  -90° <= B <=  90°
    'L      - geogr. Länge  [Dezimalgrad] mit Vorzeichen!  -180° <= L <= 180°
    '
    'Dezimalgrad - False: N 53° 54' 34,999992''  E 20° 54' 27''
    '              True:  N 53,90972222  E 20,9075
    Dim R As Double, PI As Double
    Dim nb As Double, nl As Double, sb As Double, sl As Double, ol As Double, wl As Double
    Dim result(1 To 4, 1 To 1) As Variant
    PI = 4 * Atn(1)
    Distanz = Abs(Distanz)                      ' es wird ausschließlich Distanz > 0 akzeptiert!
   
    R = (6378137 + 6356752.3142) / 2            ' angenommenr Radius der Erde (Radien aus WSG84)
    nb = B + (Distanz / R) / PI * 180          ' nördl. Breite
    nl = L                                      ' nördl. Länge
    sb = B - (Distanz / R) / PI * 180          ' südl. Breite
    sl = L                                      ' südl. Länge
    ol = L + (Distanz / R) / PI * 180          ' östl. Länge
    wl = L - (Distanz / R) / PI * 180          ' westl. Länge
   
    If ol > 180 Then ol = ol - 360              ' 0 <= Länge <= 180
    If wl < -180 Then wl = wl + 360            '-180 <= Länge <= 0
    If nb > 90 Then                            ' nb !> 90
        nb = 180 - nb
        nl = (180 - Abs(nl)) * Sgn(nl) * (-1)  ' wenn nb>90 => Länge ändert sich!
    End If
    If sb < -90 Then
        sb = -180 - sb
        sl = (180 - Abs(sl)) * Sgn(sl) * (-1)
    End If
   
    result(1, 1) = geographischeNotation(nb, nl, Dezimalgrad)
    result(2, 1) = geographischeNotation(B, ol, Dezimalgrad)
    result(3, 1) = geographischeNotation(sb, sl, Dezimalgrad)
    result(4, 1) = geographischeNotation(B, wl, Dezimalgrad)
    udf_ankerkreis_kugel = result
End Function


Function udf_ankerkreis_ellipsoid(Distanz As Double, B As Double, L As Double, Optional Dezimalgrad As Boolean = False)
    'Distanz - [m]
    'B      - geogr. Breite [Dezimalgrad] mit Vorzeichen!  -90° <= B <=  90°
    'L      - geogr. Länge  [Dezimalgrad] mit Vorzeichen!  -180° <= L <= 180°
    Dim nb As Double, nl As Double, wl As Double, ol As Double, sb As Double, sl As Double
    Dim PI As Double, t As Double, t1 As Double, result(1 To 4, 1 To 1) As Variant
    PI = 4 * Atn(1)
    'Konstanten des Referenzellipsoids WGS84 (siehe: https://de.wikipedia.org/wiki/Referenzellipsoid)
    Const r1 As Double = 6378137      'groß e Halbachse [m]
    Const r2 As Double = 6356752.3142  'kleine Halbachse [m]
    't der Parameterdarstellung der Ellipse eines Längengrades x=r1*cos(t), y=r2*sin(t)
    t = Parameter_T_aus_Breite(B, r1, r2)                              ' -PI <= t <= PI
    ol = L + (Distanz / (r1 * Cos(t))) * 180 / PI                      'östliche Länge
    wl = L - (Distanz / (r1 * Cos(t))) * 180 / PI                      'westliche Länge
    t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, True)
    nb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180                'nördliche Breite
    t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, False)
    sb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180                'südliche Breite
   
    If ol > 180 Then ol = ol - 360
    If wl < -180 Then wl = wl + 360
    If nb > 90 Then
        nb = 180 - nb
        nl = (180 - Abs(nl)) * Sgn(nl) * (-1)
    End If
    If sb < -90 Then
        sb = -180 - sb
        sl = (180 - Abs(sl)) * Sgn(sl) * (-1)
    End If
   
    result(1, 1) = geographischeNotation(nb, L, Dezimalgrad)
    result(2, 1) = geographischeNotation(B, ol, Dezimalgrad)
    result(3, 1) = geographischeNotation(sb, L, Dezimalgrad)
    result(4, 1) = geographischeNotation(B, wl, Dezimalgrad)
    udf_ankerkreis_ellipsoid = result
End Function


Sub Punkte_im_Norden_Osten_Sueden_Westen()
  Dim L As Double, B As Double    'Länge, Breite [Dezimalgrad]
  Dim Distanz As Double          'in [m]
  '            (nl,nb)
  '    (wl,wb)  (L,B)  (ol,ob)
  '            (sl,sb)
  Dim nl As Double, nb As Double, wl As Double, wb As Double
  Dim ol As Double, ob As Double, sl As Double, sb As Double
  Dim PI As Double, t As Double, t1 As Double
  PI = 4 * Atn(1)
 
  'Position
  B = Tabelle1.[B7] '70 '53.90972222 'Breite [Dezimalgrad]
  L = Tabelle1.[H7] '20.9075    'Länge  [Dezimalgrad]
 
  'Distanz auf der Erdoberfläche in [m]
  Distanz = Tabelle1.[B9]
 
 
  'Konstanten des Referenzellipsoids. Ich tippe mal auf WGS84 (siehe: https://de.wikipedia.org/wiki/Referenzellipsoid)
  Const r1 As Double = 6378137      'groß e Halbachse [m]
  Const r2 As Double = 6356752.3142  'kleine Halbachse [m]
  t = Parameter_T_aus_Breite(B, r1, r2)  't der Parameterdarstellung der Ellipse eines Längengrades x=r1*cos(t), y=r2*sin(t)
 
  'Punkt im Osten:
  ob = B
  ol = L + (Distanz / (r1 * Cos(t))) * 180 / PI
  If ol > 180 Then ol = ol - 360
 
  'Punkt im Westen:
  wb = B
  wl = L - (Distanz / (r1 * Cos(t))) * 180 / PI
  If wl < -180 Then wl = wl + 360
 
  'Punkt im Norden (Näherung mit Sekante)
  t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, True)
  nb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180 * IIf(t1 > PI / 2, -1, 1)
  nl = IIf(t1 > PI / 2, (180 - Abs(L)) * Sgn(L) * (-1), L)
 
  'Punkt im Süden (Näherung mit Sekante)
  t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, False)
  sb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180
  sl = L
 
  Dim Dezimalgrad As Boolean
  Dezimalgrad = False
  Debug.Print "Ankerpunkt: ", B, L, geographischeNotation(B, L, Dezimalgrad)
  Debug.Print "Norden      ", nb, nl, geographischeNotation(nb, nl, Dezimalgrad)
  Debug.Print "Osten      ", ob, ol, geographischeNotation(ob, ol, Dezimalgrad)
  Debug.Print "Süden      ", sb, sl, geographischeNotation(sb, sl, Dezimalgrad)
  Debug.Print "Westen      ", wb, wl, geographischeNotation(wb, wl, Dezimalgrad)
End Sub


Private Function Parameter_T_aus_Breite(phi As Double, r1 As Double, r2 As Double) As Double
    'phi - geogr. Breite  [Grad]  bzw.  [Dezimalgrad]
    'die Parametergleichung einer Elipse lautet  x = r1*cos(t),  y = r2*sin(t)    mit  -pi <= t <= pi
    'die Funktion gibt den Parameter t zurück, der den Winkel phi = arctan(y/x) repräsentiert.
    'Der Rückgabewert der Funktion liegt immer zwischen -pi/2 und pi/2
    Dim PI As Double, t As Double, dt As Double, x As Double, y As Double, B As Double, phi_ As Double
    Dim LoopCounter As Long
    PI = 4 * Atn(1)
   
    B = Abs(phi) / 180 * PI  'abs(Breite im Bogenmaß)
    t = 0
    dt = PI / 10
    Do
        LoopCounter = LoopCounter + 1
        t = t + dt
        x = r1 * Cos(t)
        y = r2 * Sin(t)
        phi_ = Atn(y / x)
        If Abs(phi_ - B) < 0.000000001 Then Exit Do
        If phi_ > B Then
            t = t - dt
            dt = dt / 2
        End If
        If LoopCounter > 100000 Then
            MsgBox "Probleme mit der Iteration"
            Stop
        End If
    Loop
'    Debug.Print "Iterationsschritte zur Ermittlung von t: ", LoopCounter
    Parameter_T_aus_Breite = t * Sgn(phi)
    End Function
   
   
Private Function Punkt_auf_Ellipse_In_Entfernung(t As Double, r1 As Double, r2 As Double, _
                                                Distanz As Double, Optional nachNorden As Boolean = True) As Double
    't, r1, r2  repräsentieren einen Punkt x=r1*cos(t), y=r2*sin(t)  auf einer Ellipse
    'die Funktion gibt den Parameter t2 zurück, der einen Punkt auf der Ellipse repräsentiert, der
    '  in der Entfernung Distanz entfernt liegt.
    Dim t1 As Double, dt As Double, x As Double, y As Double, x1 As Double, y1 As Double, s As Double, PI As Double
    Dim LoopCounter As Long
    PI = 4 * Atn(1)
    t1 = t
    dt = PI * Distanz / ((r1 + r2) / 2) * IIf(nachNorden, 1, -1)
    x = r1 * Cos(t):    y = r2 * Sin(t)
    Do
        LoopCounter = LoopCounter + 1
        t1 = t1 + dt
        x1 = r1 * Cos(t1): y1 = r2 * Sin(t1)
        s = Sqr((x - x1) ^ 2 + (y - y1) ^ 2)    'Länge des Sekantenabschnitts
        If Abs(s - Distanz) < Distanz / 500 Then Exit Do
        If s > Distanz Then
            t1 = t1 - dt
            dt = dt / 2
        End If
        If LoopCounter > 100000 Then
            MsgBox "Probleme mit der Iteration"
            Stop
        End If
    Loop
'    Debug.Print "LoopCounter " & IIf(nachNorden, "Norden: ", "Süden: "), LoopCounter
    Punkt_auf_Ellipse_In_Entfernung = t1
End Function


Function geographischeNotation(Breite As Double, Lange As Double, Optional Dezimalgrad As Boolean = False)
'Dezimalgrad => N xx° xx' xx''  E xx° xx' xx''
    Dim grad As Integer, min As Integer, sek As Double, resString As String
    If Not Dezimalgrad Then
        grad = Int(Breite)
        min = Int((Breite - grad) * 60)
        sek = (Breite - grad - min / 60) * 3600
        resString = IIf(Breite > 0, "N ", "S ") & Abs(grad) & "° " & min & "' " & Round(sek, 6) & "''  "
        grad = Int(Abs(Lange))
        min = Int((Abs(Lange) - grad) * 60)
        sek = (Abs(Lange) - grad - min / 60) * 3600
        resString = resString & IIf(Lange > 0, "E ", "W ") & grad & "° " & min & "' " & Round(sek, 6) & "''"
        geographischeNotation = resString
    Else
        geographischeNotation = IIf(Breite > 0, "N ", "S ") & Abs(Breite) & "  " & IIf(Lange > 0, "E ", "W ") & Abs(Lange)
    End If
End Function

Kommst du damit klar?

Grüße, Ulrich

PS: mein im Post #12 geposteter Code enthält Denkfehler - ich kann ihn leider nicht mehr editieren.


Angehängte Dateien
.xlsm   Ankerpunkt.xlsm (Größe: 30,61 KB / Downloads: 3)
Antworten Top
#16
(19.04.2023, 10:15)EarlFred schrieb: Du bist Nautiker, du weißt also, wie man das ganze berechnet. Allerdings weißt du nicht, wie man es in Excel umsetzt. 

Dann ist der richtige Weg: Zeige DU UNS den Rechenweg, wir zeigen dir dann, wie es in Excel umgesetzt wird. 

Dass "traditionelle" Segler GPS und Excelmappen verwenden, verwundert mich Landratte dann allerdings schon. "Seglertradition" scheint maximal in Dekaden zu denken, nicht in Hektoden.

Okay, dass ist ein guter Ansatz. Schaffe ich aber heute nicht mehr umfangreich:
wenn ich die GPS Koordinaten habe - sei es automatisch oder aus der Seekarte ermittelt - will ich die maximalen Koordinaten ermittel, in denen sich das Schiff bewegen darf. Habe ich das also aus Kettenlängen, Wassertiefe und Schiffslänge errechnet, um wieviel Meter sich das Schiff  zum Beispiel 100 Metern um den Ankerpunkt bewegen darf, soll Excel mir diese 4 Koordinaten N O S W in Grad, Minuten und Sekunden geben. Die Daten werden sich im Sekundenbereich befinden, maximal im kleinen Minutenbereich.

Ich gebe Excel also die Ankerplatzkoordinaten und den Umkreis in Metern vor und Excel sagt mir den Rest. 1 Seemeile sind 1,825m entsprechend x 60 dann die Minuten bzw x 3600 die Sekunden.

Es ist verpflichtend auf Schiffen, auf denen gegen Entgeld anderen Menschen das Segeln näher gebracht werden soll (oder will), diese modernen Geräte wie GPS, Radar, AIS (automatisches Schiff Identifizierungssystem) und ähnliches benutzt werden müssen - Sicherheitsvorschriften. Dazu gehören auch die Traditionssegler ab einer gewissen Größe und wir reden hier jetzt gerade von 36 Meter.

Die Excel Geschichte ist einfach nur für mich interessant und dient der zusätzlichen Kontrolle.

(19.04.2023, 14:37)losgehts schrieb: Hallo,

ich glaube, du hast mich falsch verstanden: das war ein in weiten Teilen funktionierender (noch anzupassender) Lösungsvorschlag!

Du scheinst eine fertige Datei haben zu wollen. Das ist normalerweise nicht so meine Freude beim Helfen, aber ich hatte gerade nochmal Zeit und irgendwie finde ich die Fragestellung (in Teilen) auch interessant.

Ich habe dir eine Mappe gemacht. 

Wenn man die Erde als eine Kugel annimmt (weißt du, welchen Radius ich da annehmen sollte?), dann sind die Berechnungen (abgesehen von den Polen/Equator 0° Länge und 180° Länge) wirklich für 99% aller Fälle äußerst simpel:
Länge = Länge_Ankerpunkt + (Distanz / Erdradius) * 180 / Pi
Breite = Breite_Ankerpunkt + (Distanz / Erdradius) * 180 / Pi
mit Distanz meine ich deine 100 m bzw. Ankerkettenlänge bzw. Projektion dieser auf die Wasseroberfläche ...
Länge_Ankerpunkt und Breite_Ankerpunkt muss dabei als Dezimalgrad vorliegen
Das könnte man auch gut und einfach mit Formeln in Excel umsetzen. Vielleicht hilft dir jemand dabei - ich habe da keinen Spaß dran.

Ich habe gerade einige Fehler meines Lösungsvorschlags ausgemerzt und das ganze in Funktionen verpackt, sodass du es vom Tabellenblatt mit einer Formel aufrufen kannst. Dabei habe ich sowohl einen Vorschlag für die Näherung der Erde als Kugel, als auch einen für die Erde als Parallelellipsoid.

Die Formel geben ein ganzes Array zurück, sind also Matrix-Formeln. Du rufst sie mit folgenden Parametern auf:
udf_ankerkreis_kugel(Distanz, Breite, Länge)
udf_ankerkreis_ellipsoid(Distanz, Breite, Länge)
Dabei wird muss die Distanz in Meter angegeben sein.
Die Breite und Länge müssen als Dezimalzahl (Dezimalgrad) angegeben werden.

Hier der Code für alle, die es interessiert:
Code:
Option Explicit

Function udf_ankerkreis_kugel(ByVal Distanz As Double, B As Double, L As Double, Optional Dezimalgrad As Boolean = False)
    'Distanz - [m]
    'B      - geogr. Breite [Dezimalgrad] mit Vorzeichen!  -90° <= B <=  90°
    'L      - geogr. Länge  [Dezimalgrad] mit Vorzeichen!  -180° <= L <= 180°
    '
    'Dezimalgrad - False: N 53° 54' 34,999992''  E 20° 54' 27''
    '              True:  N 53,90972222  E 20,9075
    Dim R As Double, PI As Double
    Dim nb As Double, nl As Double, sb As Double, sl As Double, ol As Double, wl As Double
    Dim result(1 To 4, 1 To 1) As Variant
    PI = 4 * Atn(1)
    Distanz = Abs(Distanz)                      ' es wird ausschließlich Distanz > 0 akzeptiert!
   
    R = (6378137 + 6356752.3142) / 2            ' angenommenr Radius der Erde (Radien aus WSG84)
    nb = B + (Distanz / R) / PI * 180          ' nördl. Breite
    nl = L                                      ' nördl. Länge
    sb = B - (Distanz / R) / PI * 180          ' südl. Breite
    sl = L                                      ' südl. Länge
    ol = L + (Distanz / R) / PI * 180          ' östl. Länge
    wl = L - (Distanz / R) / PI * 180          ' westl. Länge
   
    If ol > 180 Then ol = ol - 360              ' 0 <= Länge <= 180
    If wl < -180 Then wl = wl + 360            '-180 <= Länge <= 0
    If nb > 90 Then                            ' nb !> 90
        nb = 180 - nb
        nl = (180 - Abs(nl)) * Sgn(nl) * (-1)  ' wenn nb>90 => Länge ändert sich!
    End If
    If sb < -90 Then
        sb = -180 - sb
        sl = (180 - Abs(sl)) * Sgn(sl) * (-1)
    End If
   
    result(1, 1) = geographischeNotation(nb, nl, Dezimalgrad)
    result(2, 1) = geographischeNotation(B, ol, Dezimalgrad)
    result(3, 1) = geographischeNotation(sb, sl, Dezimalgrad)
    result(4, 1) = geographischeNotation(B, wl, Dezimalgrad)
    udf_ankerkreis_kugel = result
End Function


Function udf_ankerkreis_ellipsoid(Distanz As Double, B As Double, L As Double, Optional Dezimalgrad As Boolean = False)
    'Distanz - [m]
    'B      - geogr. Breite [Dezimalgrad] mit Vorzeichen!  -90° <= B <=  90°
    'L      - geogr. Länge  [Dezimalgrad] mit Vorzeichen!  -180° <= L <= 180°
    Dim nb As Double, nl As Double, wl As Double, ol As Double, sb As Double, sl As Double
    Dim PI As Double, t As Double, t1 As Double, result(1 To 4, 1 To 1) As Variant
    PI = 4 * Atn(1)
    'Konstanten des Referenzellipsoids WGS84 (siehe: https://de.wikipedia.org/wiki/Referenzellipsoid)
    Const r1 As Double = 6378137      'groß e Halbachse [m]
    Const r2 As Double = 6356752.3142  'kleine Halbachse [m]
    't der Parameterdarstellung der Ellipse eines Längengrades x=r1*cos(t), y=r2*sin(t)
    t = Parameter_T_aus_Breite(B, r1, r2)                              ' -PI <= t <= PI
    ol = L + (Distanz / (r1 * Cos(t))) * 180 / PI                      'östliche Länge
    wl = L - (Distanz / (r1 * Cos(t))) * 180 / PI                      'westliche Länge
    t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, True)
    nb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180                'nördliche Breite
    t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, False)
    sb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180                'südliche Breite
   
    If ol > 180 Then ol = ol - 360
    If wl < -180 Then wl = wl + 360
    If nb > 90 Then
        nb = 180 - nb
        nl = (180 - Abs(nl)) * Sgn(nl) * (-1)
    End If
    If sb < -90 Then
        sb = -180 - sb
        sl = (180 - Abs(sl)) * Sgn(sl) * (-1)
    End If
   
    result(1, 1) = geographischeNotation(nb, L, Dezimalgrad)
    result(2, 1) = geographischeNotation(B, ol, Dezimalgrad)
    result(3, 1) = geographischeNotation(sb, L, Dezimalgrad)
    result(4, 1) = geographischeNotation(B, wl, Dezimalgrad)
    udf_ankerkreis_ellipsoid = result
End Function


Sub Punkte_im_Norden_Osten_Sueden_Westen()
  Dim L As Double, B As Double    'Länge, Breite [Dezimalgrad]
  Dim Distanz As Double          'in [m]
  '            (nl,nb)
  '    (wl,wb)  (L,B)  (ol,ob)
  '            (sl,sb)
  Dim nl As Double, nb As Double, wl As Double, wb As Double
  Dim ol As Double, ob As Double, sl As Double, sb As Double
  Dim PI As Double, t As Double, t1 As Double
  PI = 4 * Atn(1)
 
  'Position
  B = Tabelle1.[B7] '70 '53.90972222 'Breite [Dezimalgrad]
  L = Tabelle1.[H7] '20.9075    'Länge  [Dezimalgrad]
 
  'Distanz auf der Erdoberfläche in [m]
  Distanz = Tabelle1.[B9]
 
 
  'Konstanten des Referenzellipsoids. Ich tippe mal auf WGS84 (siehe: https://de.wikipedia.org/wiki/Referenzellipsoid)
  Const r1 As Double = 6378137      'groß e Halbachse [m]
  Const r2 As Double = 6356752.3142  'kleine Halbachse [m]
  t = Parameter_T_aus_Breite(B, r1, r2)  't der Parameterdarstellung der Ellipse eines Längengrades x=r1*cos(t), y=r2*sin(t)
 
  'Punkt im Osten:
  ob = B
  ol = L + (Distanz / (r1 * Cos(t))) * 180 / PI
  If ol > 180 Then ol = ol - 360
 
  'Punkt im Westen:
  wb = B
  wl = L - (Distanz / (r1 * Cos(t))) * 180 / PI
  If wl < -180 Then wl = wl + 360
 
  'Punkt im Norden (Näherung mit Sekante)
  t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, True)
  nb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180 * IIf(t1 > PI / 2, -1, 1)
  nl = IIf(t1 > PI / 2, (180 - Abs(L)) * Sgn(L) * (-1), L)
 
  'Punkt im Süden (Näherung mit Sekante)
  t1 = Punkt_auf_Ellipse_In_Entfernung(t, r1, r2, Distanz, False)
  sb = Atn((r2 * Sin(t1)) / (r1 * Cos(t1))) / PI * 180
  sl = L
 
  Dim Dezimalgrad As Boolean
  Dezimalgrad = False
  Debug.Print "Ankerpunkt: ", B, L, geographischeNotation(B, L, Dezimalgrad)
  Debug.Print "Norden      ", nb, nl, geographischeNotation(nb, nl, Dezimalgrad)
  Debug.Print "Osten      ", ob, ol, geographischeNotation(ob, ol, Dezimalgrad)
  Debug.Print "Süden      ", sb, sl, geographischeNotation(sb, sl, Dezimalgrad)
  Debug.Print "Westen      ", wb, wl, geographischeNotation(wb, wl, Dezimalgrad)
End Sub


Private Function Parameter_T_aus_Breite(phi As Double, r1 As Double, r2 As Double) As Double
    'phi - geogr. Breite  [Grad]  bzw.  [Dezimalgrad]
    'die Parametergleichung einer Elipse lautet  x = r1*cos(t),  y = r2*sin(t)    mit  -pi <= t <= pi
    'die Funktion gibt den Parameter t zurück, der den Winkel phi = arctan(y/x) repräsentiert.
    'Der Rückgabewert der Funktion liegt immer zwischen -pi/2 und pi/2
    Dim PI As Double, t As Double, dt As Double, x As Double, y As Double, B As Double, phi_ As Double
    Dim LoopCounter As Long
    PI = 4 * Atn(1)
   
    B = Abs(phi) / 180 * PI  'abs(Breite im Bogenmaß)
    t = 0
    dt = PI / 10
    Do
        LoopCounter = LoopCounter + 1
        t = t + dt
        x = r1 * Cos(t)
        y = r2 * Sin(t)
        phi_ = Atn(y / x)
        If Abs(phi_ - B) < 0.000000001 Then Exit Do
        If phi_ > B Then
            t = t - dt
            dt = dt / 2
        End If
        If LoopCounter > 100000 Then
            MsgBox "Probleme mit der Iteration"
            Stop
        End If
    Loop
'    Debug.Print "Iterationsschritte zur Ermittlung von t: ", LoopCounter
    Parameter_T_aus_Breite = t * Sgn(phi)
    End Function
   
   
Private Function Punkt_auf_Ellipse_In_Entfernung(t As Double, r1 As Double, r2 As Double, _
                                                Distanz As Double, Optional nachNorden As Boolean = True) As Double
    't, r1, r2  repräsentieren einen Punkt x=r1*cos(t), y=r2*sin(t)  auf einer Ellipse
    'die Funktion gibt den Parameter t2 zurück, der einen Punkt auf der Ellipse repräsentiert, der
    '  in der Entfernung Distanz entfernt liegt.
    Dim t1 As Double, dt As Double, x As Double, y As Double, x1 As Double, y1 As Double, s As Double, PI As Double
    Dim LoopCounter As Long
    PI = 4 * Atn(1)
    t1 = t
    dt = PI * Distanz / ((r1 + r2) / 2) * IIf(nachNorden, 1, -1)
    x = r1 * Cos(t):    y = r2 * Sin(t)
    Do
        LoopCounter = LoopCounter + 1
        t1 = t1 + dt
        x1 = r1 * Cos(t1): y1 = r2 * Sin(t1)
        s = Sqr((x - x1) ^ 2 + (y - y1) ^ 2)    'Länge des Sekantenabschnitts
        If Abs(s - Distanz) < Distanz / 500 Then Exit Do
        If s > Distanz Then
            t1 = t1 - dt
            dt = dt / 2
        End If
        If LoopCounter > 100000 Then
            MsgBox "Probleme mit der Iteration"
            Stop
        End If
    Loop
'    Debug.Print "LoopCounter " & IIf(nachNorden, "Norden: ", "Süden: "), LoopCounter
    Punkt_auf_Ellipse_In_Entfernung = t1
End Function


Function geographischeNotation(Breite As Double, Lange As Double, Optional Dezimalgrad As Boolean = False)
'Dezimalgrad => N xx° xx' xx''  E xx° xx' xx''
    Dim grad As Integer, min As Integer, sek As Double, resString As String
    If Not Dezimalgrad Then
        grad = Int(Breite)
        min = Int((Breite - grad) * 60)
        sek = (Breite - grad - min / 60) * 3600
        resString = IIf(Breite > 0, "N ", "S ") & Abs(grad) & "° " & min & "' " & Round(sek, 6) & "''  "
        grad = Int(Abs(Lange))
        min = Int((Abs(Lange) - grad) * 60)
        sek = (Abs(Lange) - grad - min / 60) * 3600
        resString = resString & IIf(Lange > 0, "E ", "W ") & grad & "° " & min & "' " & Round(sek, 6) & "''"
        geographischeNotation = resString
    Else
        geographischeNotation = IIf(Breite > 0, "N ", "S ") & Abs(Breite) & "  " & IIf(Lange > 0, "E ", "W ") & Abs(Lange)
    End If
End Function

Kommst du damit klar?

Grüße, Ulrich

PS: mein im Post #12 geposteter Code enthält Denkfehler - ich kann ihn leider nicht mehr editieren.

Probiere ich morgen aus. VIELEN DANK
Antworten Top


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste