首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在我的函数中,计算一个新的纬度/经度坐标的错误在哪里?

在我的函数中,计算一个新的纬度/经度坐标的错误在哪里?
EN

Stack Overflow用户
提问于 2019-04-14 00:57:20
回答 2查看 124关注 0票数 0

我编写了一个函数,从方位和距离计算新的纬度/经度坐标。然而,它正在返回错误的结果,我不明白为什么。我在https://www.movable-type.co.uk/scripts/latlong.html上使用了公式,但是当我用页面上的计算器测试它时,它给出了错误的结果。例如,NewLatLong(0, 0, 500, "K", 45)的纬度为5.54656612024095E-02,经度为0。在将纬度转换为与页面上的计算器进行比较之后,纬度是正确的,但是为什么经度返回为零?NewLatLong的参数是原始纬度和经度,距离,距离单位(K =公里),顺时针方向,以度为单位。

MS Access不具备所需的所有三角函数。我提供了新的。这些已分别测试,并似乎功能正确。

我看不出我的代码有什么问题。有人能帮上忙吗。

代码语言:javascript
运行
AI代码解释
复制
Public Function NewLatLong(latD As Double, longD As Double, distance As Double, unit As String, bearingD As Double) As Double()
    Dim latlong(2) As Double
    Dim latR As Double, bearingR As Double
    latR = Radians(latD)
    bearingR = Radians(bearingD)
    Dim cosAngDistance As Double, sinAngDistance As Double
    cosAngDistance = Cos(distance / EarthRadius(unit))
    sinAngDistance = Sin(distance / EarthRadius(unit))
    latlong(0) = ArcSine(Sin(latR) * cosAngDistance + Cos(latR) * sinAngDistance * Cos(bearingR))
    latlong(1) = (Radians(longD) + ArcTan2(Sin(bearingR) * sinAngDistance * Cos(latR), cosAngDistance - Sin(latR) * Sin(latlong(0))) + 540) Mod 360 - 180
    NewLatLong = latlong
    Debug.Print latlong(0) & " " & latlong(1)
End Function

Public Function EarthRadius(unit As String) As Double
    If (unit = "M") Then
        EarthRadius = 3963
    ElseIf (unit = "K") Then
        EarthRadius = 6371
    Else
        EarthRadius = 3443.753
    End If
End Function


Public Function Pi() As Double
    Pi = 4 * Atn(1)
End Function

Public Function ArcCosine(value As Double) As Double
    ArcCosine = Atn(-value / Sqr(-value * value + 1)) + 2 * Atn(1)
End Function

Public Function ArcSine(value As Double) As Double
    ArcSine = Atn(value / Sqr(-value * value + 1))
End Function

Public Function ArcTan2(y As Double, x As Double) As Double
    If x > 0 Then
        ArcTan2 = Atn(y / x)
    ElseIf x < 0 Then
        ArcTan2 = Sgn(y) * (Pi() - Atn(Abs(y / x)))
    ElseIf y = 0 Then
        ArcTan2 = 0
    Else
        ArcTan2 = Sgn(y) * Pi() / 2
    End If
End Function

Public Function Radians(degrees As Double) As Double
    Radians = degrees * Pi() / 180
End Function
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-14 06:47:51

好消息和坏消息。好消息是您的代码工作得几乎完美,坏消息是Mod操作符总是返回一个整数,而不管它的参数类型如何(为什么是Microsoft!?)为什么!?)。

不要使用latlong(1) = (Radians(longD) + ArcTan2(Sin(bearingR) * sinAngDistance * Cos(latR), cosAngDistance - Sin(latR) * Sin(latlong(0))) + 540) Mod 360 - 180,而是使用下面的代码来查找经度

代码语言:javascript
运行
AI代码解释
复制
Dim tempLong As Double
tempLong = Radians(longD) + ArcTan2(Sin(bearingR) * sinAngDistance * Cos(latR), cosAngDistance - Sin(latR) * Sin(latlong(0)))
' set longitude if calculated value less than 1
If tempLong < 1 Then
    latlong(1) = tempLong
' if greater than 1, add decimal part back to modulus result
Else
    Dim decLong As Double
    decLong = tempLong
    While decLong > 1
        decLong = decLong - 1
    Wend
    latlong(1) = ((tempLong + 540) Mod 360 - 180) + decLong
End If
票数 2
EN

Stack Overflow用户

发布于 2019-04-14 12:58:29

我添加了我自己的mod函数,它可以正确地工作在双倍的情况下。

代码语言:javascript
运行
AI代码解释
复制
Public Function ModDouble(dividend As Double, divisor As Double) As Double
    Dim x As Double
    x = Int(dividend / divisor)
    ModDouble = dividend - (x * divisor)
End Function

这使得原始代码运行良好,使用

代码语言:javascript
运行
AI代码解释
复制
latlong(1) = ModDouble(radians(longD) + ArcTan2(Sin(bearingR) * sinAngDistance * Cos(latR), cosAngDistance - Sin(latR) * Sin(latlong(0))) + 540, 360) - 180

但是我要标记BankBuilder的答案是正确的,因为他基本上发现了错误,这是我永远也找不到的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55673582

复制
相关文章

相似问题

领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文