使用增强几何从点到线的垂直地理距离

2023-12-13

我想得到距一点的垂直距离(t)到一条线段(p, q)。垂线不能与直线相交[p, q]。在这种情况下我想延长线路(p, q)假设,然后绘制垂线以获得距离。 p、q、t 都是 GPS 坐标。我正在使用增强几何。

typedef boost::geometry::model::point<
    double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>
> geo_point;
typedef boost::geometry::model::segment<geo_point> geo_segment;

geo_point p(88.41253929999999, 22.560206299999997);
geo_point q(88.36928063300775, 22.620867969497795);
geo_point t(88.29580956367181, 22.71558662052875);

I have plotted these three locations on map enter image description here

我测量了两个距离qt和距离t to pq

double dist_qt = boost::geometry::distance(q, t);
std::cout << dist_qt*earth_radius << std::endl;

geo_segment line(p, q);
double perp_dist = boost::geometry::distance(t, line);
std::cout << perp_dist*earth_radius << std::endl;

这两个距离是相同的。这意味着它不计算垂直距离。而是计算了shortest点到线内的距离bounds.

如何计算垂直距离,使其无论边界如何都必须垂直?

工作示例在cpp.sh


这个答案完成所有计算,无升压.


考虑半径 R = 1 的球体。

enter image description here

A、B点在a上大圆。这个大圈子gcAB也穿过中心点O球体的直径(大圆所需)。积分A, B, O定义一个平面PL1.

Point P也位于一个大圆圈内。

的最小距离(沿着大圆弧测量,而不是沿着 3D 直线测量)P到大圆gcAB是弧的长度PC.
Plane PL2大圆的gcPC垂直于平面PL1.

我们想要点C,位于该行OC,它是两个提到的平面的交集。

.
Plane PL1由其垂直向量定义pp1。该向量通过以下方式获得叉积向量数OA and OB.

因为飞机PL2垂直于平面PL1,它必须包含向量pp1。所以垂直向量pp2顶级车道PL2可以通过叉积得到OP and pp1.

一个向量ppi在行中OC两个平面的交线由以下叉积获得pp1 and pp2.

If we 正常化 vector ppi并将其分量乘以半径R地球的坐标,我们得到点的坐标C.
叉积不可交换。这意味着如果我们交换点 A、B,我们会得到相反的点C'在球体中。我们可以测试距离PC and PC'并得到他们的最小值。


计算大圆距离 维基百科链接为两点A, B,它依赖于角度a字里行间OA and OB.
为了在所有角度上获得最佳精度,我们使用a = atan2(y, x)其中,使用半径 1,y= sin(a) and x= cos(a). sin(a) and cos(a)可以通过叉积 (OA, OB) 计算点积分别为(OA、OB)。

将所有内容放在一起,我们得到了以下 C++ 代码:

#include <iostream>
#include <cmath>

const double degToRad = std::acos(-1) / 180;

struct vec3
{
    double x, y, z;
    vec3(double xd, double yd, double zd) : x(xd), y(yd), z(zd) {}
    double length()
    {
        return std::sqrt(x*x + y*y + z*z);
    }
    void normalize()
    {
        double len = length();
        x = x / len;
        y = y / len;
        z = z / len;
    } 
};

vec3 cross(const vec3& v1, const vec3& v2)
{
    return vec3( v1.y * v2.z - v2.y * v1.z,
                 v1.z * v2.x - v2.z * v1.x,
                 v1.x * v2.y - v2.x * v1.y );
}

double dot(const vec3& v1, const vec3& v2)
{
    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}

double GCDistance(const vec3& v1, const vec3& v2, double R)
{
    //normalize, so we can pass any vectors
    vec3 v1n = v1;
    v1n.normalize();
    vec3 v2n = v2;
    v2n.normalize();
    vec3 tmp = cross(v1n, v2n);
    //minimum distance may be in one direction or the other
    double d1 = std::abs(R * std::atan2(tmp.length() , dot(v1n, v2n)));
    double d2 = std::abs(R * std::atan2(tmp.length() , -dot(v1n, v2n)));

    return std::min(std::abs(d1), std::abs(d2));
}                  

int main()
{
    //Points A, B, and P
    double lon1 = 88.41253929999999  * degToRad;
    double lat1 = 22.560206299999997 * degToRad;
    double lon2 = 88.36928063300775  * degToRad;
    double lat2 = 22.620867969497795 * degToRad;
    double lon3 = 88.29580956367181  * degToRad;
    double lat3 = 22.71558662052875  * degToRad;

    //Let's work with a sphere of R = 1
    vec3 OA(std::cos(lat1) * std::cos(lon1), std::cos(lat1) * std::sin(lon1), std::sin(lat1));
    vec3 OB(std::cos(lat2) * std::cos(lon2), std::cos(lat2) * std::sin(lon2), std::sin(lat2));
    vec3 OP(std::cos(lat3) * std::cos(lon3), std::cos(lat3) * std::sin(lon3), std::sin(lat3));
    //plane OAB, defined by its perpendicular vector pp1
    vec3 pp1 = cross(OA, OB);
    //plane OPC
    vec3 pp2 = cross(pp1, OP);
    //planes intersection, defined by a line whose vector is ppi
    vec3 ppi = cross(pp1, pp2);
    ppi.normalize(); //unitary vector

    //Radious or Earth
    double R = 6371000; //mean value. For more precision, data from a reference ellipsoid is required

    std::cout << "Distance AP = " << GCDistance(OA, OP, R) << std::endl;
    std::cout << "Distance BP = " << GCDistance(OB, OP, R) << std::endl;
    std::cout << "Perpendicular distance (on arc) = " << GCDistance(OP, ppi, R) << std::endl;
}

哪一个给出了距离 对于给定的三个点,AP = 21024.4 BP = 12952.1 且 PC= 499.493。

运行代码here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用增强几何从点到线的垂直地理距离 的相关文章

随机推荐

  • 在 VBA 中跨工作表指定 Excel 范围

    在VBA中 为什么以下会失败 Dim rng as Range rng Range Sheet1 Sheet3 A1 它抛出一个 HRESULT 异常 还有另一种方法可以在 VBA 中构造这个范围吗 请注意 您可以输入 SUM Sheet1
  • 高阶函数和 ST

    我正在玩http hackage haskell org packages archive vault 0 2 0 0 doc html Data Vault ST html并想编写如下函数 onVault f runST f lt gt
  • 接受用于填充“url_for”方法的 URL 参数是否安全?

    我正在使用 Ruby on Rails 4 1 1 并且我正在考虑接受直接传递到的参数 通过 URL 查询字符串 url for方法 这样 URL in the browser http www myapp com redirect to
  • 浮点型和双精度型有什么区别?

    我读过有关双精度和单精度之间的区别的内容 然而 在大多数情况下 float and double似乎可以互换 即使用其中之一似乎不会影响结果 事实真的如此吗 浮点数和双精度数什么时候可以互换 它们之间有什么区别 差异巨大 As the na
  • Javascript读取文件夹中的文件

    我有以下问题 我正在尝试用 javascript 解决 我有一个 div 其背景图像在 css 文件中指定 我希望我的 javascript 定期更改该图像 假设每 5 秒一次 我知道该怎么做 问题是我有一个图像文件夹可供选择作为背面图像
  • 如何查看 mongoDB 中的任何更改(新行)?

    有没有办法观察每一个collection 甚至一个 中mongoDB 现在我考虑计时器来检查文档编号或最后一个 ID 但也许有可能实现类似的机制newDocumentAddedEvent MongoDB 中还没有触发器 还没有 但是如果您正
  • 将 R 中的多个绘图导出到 ppt 中

    我在这里找到了一个函数 可以为在 R 中创建的绘图创建带有幻灯片的 ppt 这是该函数的链接 R 将当前活动的 R 图导出到 Powerpoint Word LibreOffice 的功能 我希望我的程序添加几张幻灯片 每张幻灯片包含一张图
  • ' aria-label='如何判断浏览器是否支持 '> 如何判断浏览器是否支持

    可能的重复 HTML5 类型检测和插件初始化
  • PythonInfo 没有 virtualenv 实现

    我遇到 virtualenv 实现错误 我知道 python2 7 很旧 但仍然需要 有人有解决办法吗 PythonInfo base exec prefix None system stdlib u usr lib python2 7 h
  • 为什么我们必须在内部类中将静态变量声明为final? [复制]

    这个问题在这里已经有答案了 我的代码是这样的 public class BookStore class Enumerator1 static int b 0 requires final public String searchBook f
  • 跨域请求和JQuery

    我尝试使用 getJSON 通过 jquery 向 Web 服务发出跨域请求 它工作正常 但是 当我尝试在 Internet Explorer 7 或 8 中发出相同的请求时 该请求永远不会发送 有人有主意吗 JSONP 就是为了这个目的而
  • 在 Perl 中如何找到所有重定向后的最终 URL?

    可以说我有 http www ritzcarlton com 这将我重定向到 http www ritzcarlton com en Default htm Perl 有没有办法在所有重定向后找到最终网址 使用 LWP 将为您遵循重定向 然
  • 在 JavaScript 中反转字符串

    我正在尝试反转输入字符串 var oneway document getElementById input field value var backway oneway reverse 但萤火虫告诉我oneway reverse 不是一个函
  • VS2015 中的 CoreCLR 控制台应用程序项目中没有本机代码调试?

    我真的很想跳过 CoreCLR 新的项目结构 nuget 合并到构建系统 文件系统报告更改时自动刷新解决方案以及针对多个平台只是我想从旧的 csproj net 继续前进的部分原因4 x 的东西 我的主要用例之一是使用 C 探索多平台游戏引
  • 如何将“字符串列表”变成真正的列表?

    我正在开一个 txt文件 并且必须使用其中的列表来执行我正在编写的函数 这是文本文件中给出的列表之一 24 72 95 100 59 80 87 n Using strip 它摆脱了 n 所以就变成 24 72 95 100 59 80 8
  • 递归 JSON 架构

    我正在尝试为带有子菜单的菜单创建正确的 JSON 架构 所以我应该从 item 定义一个数组 其中应包含三个项目 1 显示名称 2 URL 和子项 应该是具有相同结构的对象数组 此时我得到了这个 type array additionalP
  • main() 总是返回 int? [复制]

    这个问题在这里已经有答案了 可能的重复 C C 中 main 应该返回什么 为什么我们在c 中给出int main而不是void main 我开始学习 C 时 我想到了以下问题 main 总是返回 int 我不能声明无效主 代替int ma
  • 更改列表框中所选项目的背景颜色

    首先 我在这里和网络上搜索 发现很多解决方案如何更改 WPF 中列表框中所选项目的背景颜色 但没有找到如何在 Windows 应用商店应用程序中更改它 这个框架有点不同 我无法使用任何解决方案 我用这个 http social msdn m
  • Android:使用两个 ValueEventListener 从 firebase 数据库获取数据(在 Arraylist 过期之前设置适配器)

    我正在开发一个应用程序 数据库中有医生和患者等用户 患者数据和患者中可能有医生userIduserId在医生数据中 因为在应用程序中医生会看到有关他 她的患者的一些信息 我开发了这段代码 但在设置适配器之前我无法将患者信息添加到Arrayl
  • 使用增强几何从点到线的垂直地理距离

    我想得到距一点的垂直距离 t 到一条线段 p q 垂线不能与直线相交 p q 在这种情况下我想延长线路 p q 假设 然后绘制垂线以获得距离 p q t 都是 GPS 坐标 我正在使用增强几何 typedef boost geometry