文章目录

  • 1 预备知识
  • 2 原理描述
  • 3 代码实现

1 预备知识

在求解此问题之前首先要明确一下几点:

(1)两点间的球面距离: 球面上两点间的最短距离,即球心与球面上两点所确定的平面与球面相交,得到一截面圆,两点间的劣弧(圆心角<180°的圆弧)就是这两点间的球面距离。

(2)任意与球面相交的平面,球截面均为一个圆,不可能出现其他截面形状。

(3)余弦定理

(4) 弦长公式

角度制下:

已知圆弧的半径 RRR,圆心角 n°n°n°,则弧长计算公式为

l=n°πR180°l=\cfrac{n°\pi R}{180°}l=180°n°πR​

弧度制下:

已知圆弧的半径 RRR,圆心角(弧度) θ\thetaθ,则弧长计算公式为
l=R⋅θl=R·\thetal=R⋅θ

2 原理描述

已知球面上两点 S1(x1,y1,z1)S_1(x_1,y_1,z_1)S1​(x1​,y1​,z1​)、S2(x2,y2,z2)S_2(x_2,y_2,z_2)S2​(x2​,y2​,z2​)与球心 O(x0,y0,z0)O(x_0,y_0,z_0)O(x0​,y0​,z0​),可以唯一确定一个平面,且三点围成一个扇形 ⌔OS1S2⌔OS_1S_2⌔OS1​S2​,半径为球半径 RRR。

根据余弦定理,可求得扇形的圆心角 α\alphaα

cosα=2R2−∣S1S2∣22R2=1−∣S1S2∣22R2cos\alpha=\cfrac{2R^2-|S_1S_2|^2}{2R^2}=1-\cfrac{|S_1S_2|^2}{2R^2}cosα=2R22R2−∣S1​S2​∣2​=1−2R2∣S1​S2​∣2​
α=arccos(1−∣S1S2∣22R2)\alpha=arccos(1-\cfrac{|S_1S_2|^2}{2R^2})α=arccos(1−2R2∣S1​S2​∣2​)

其中,∣S1S2∣|S_1S_2|∣S1​S2​∣ 为两点构成的弦长,且
∣S1S2∣=(x2−x1)2+(y2−y1)2+(z2−z1)2|S_1S_2|=\sqrt{(x_2-x_1)^2+(y_2-y_1)^2+(z_2-z_1)^2}∣S1​S2​∣=(x2​−x1​)2+(y2​−y1​)2+(z2​−z1​)2​
根据上面给出的弧长公式,即可计算出球面上任意两点间的球面距离。

3 代码实现

以球心位于坐标原点 O(0,0,0)O(0,0,0)O(0,0,0),球半径 R=1.0R=1.0R=1.0 的球面为例,已知球面上两点 p1(1,0,0)p_1(1,0,0)p1​(1,0,0),p2(0,0,1)p_2(0,0,1)p2​(0,0,1),求这两点的球面距离。

代码:

#include <iostream>
#include <vector>
#include <cmath>using namespace std;//XYZ点类型结构体
struct PointXYZ
{public:double x;double y;double z;
};//球面距离求解类
class SphereDistanceCalculator
{public:/*** @brief   :设置球半径* @param[I]:R(球半径)* @param[O]:none* @return  :none* @note    :**/void setSphereRadius(double R);/*** @brief   :设置球面两点* @param[I]:p1(球面第一点)* @param[I]:p2(球面第二点)* @param[O]:none* @return  :none* @note    :**/void setSpherePoints(PointXYZ p1, PointXYZ p2);/*** @brief   :计算球面距离* @param[I]:none* @param[O]:none* @return  :vector<double>,依次为弦长、圆心角、球面距离* @note    :**/vector<double> calculateSphereDistance();private:double m_R;          //球半径bool is_setSphereRadius = false;PointXYZ m_p1;        //球面第一点PointXYZ m_p2;       //球面第二点bool is_setSpherePoints = false;
};/**
* @brief   :设置球半径
* @param[I]:R(球半径)
* @param[O]:none
* @return  :none
* @note    :
**/
void SphereDistanceCalculator::setSphereRadius(double R)
{if (R > 0){m_R = R;is_setSphereRadius = true;}else{cerr << "\a->球体半径应为一个正数!\n";system("pause");abort();}
}/**
* @brief   :设置球面两点
* @param[I]:p1(球面第一点)
* @param[I]:p2(球面第二点)
* @param[O]:none
* @return  :none
* @note    :
**/
void SphereDistanceCalculator::setSpherePoints(PointXYZ p1, PointXYZ p2)
{m_p1 = p1;m_p2 = p2;is_setSpherePoints = true;
}/**
* @brief   :计算球面距离
* @param[I]:none
* @param[O]:none
* @return  :vector<double>,依次为弦长、圆心角、球面距离
* @note    :
**/
vector<double> SphereDistanceCalculator::calculateSphereDistance()
{if (!is_setSphereRadius){cerr << "\a->请输入球半径!\n";system("pause");abort();}if (!is_setSpherePoints){cerr << "\a->请输入球面上两点三维坐标!\n";system("pause");abort();}vector<double> res;        //存放返回值的向量double S1S2;          //弦长S1S2 = sqrt(pow((m_p2.x - m_p1.x), 2) + pow((m_p2.y - m_p1.y), 2) + pow((m_p2.z - m_p1.z), 2));res.push_back(S1S2);double alpha;         //圆心角alpha = acos(1 - pow(S1S2 / m_R, 2) / 2);res.push_back(alpha);double sphereDistance;  //球面距离sphereDistance = m_R * alpha;res.push_back(sphereDistance);return res;
}int main()
{const double PI = 3.14159265359;  //常量PIPointXYZ p1, p2;                  //球面两点坐标p1.x = 1.0;p1.y = 0.0;p1.z = 0.0;p2.x = 0.0;p2.y = 0.0;p2.z = 1.0;SphereDistanceCalculator sdc;       //创建球面距离求解对象sdc.setSphereRadius(1.0);           //设置球半径sdc.setSpherePoints(p1, p2);     //设置球面上两点vector<double> rec;                  //存放弦长、圆心角、球面距离的向量rec = sdc.calculateSphereDistance();//执行计算,并将结果存放到rec中cout << "->球面两点的直线距离(圆弧弦长):" << rec[0] << endl;cout << "->球面两点对应的圆心角(弧度):" << rec[1] << endl<< "  球面两点对应的圆心角(角度):" << rec[1] / PI * 180 << "°" << endl;cout << "->球面两点的球面距离:" << rec[2] << endl;return 0;
}

输出结果:

->球面两点的直线距离(圆弧弦长):1.41421
->球面两点对应的圆心角(弧度):1.5708球面两点对应的圆心角(角度):90°
->球面两点的球面距离:1.5708

计算球面上任意两点间的球面距离(C++实现)相关推荐

  1. 由经纬度计算地球上任意两点的距离

    由经纬度计算地球上任意两点的距离 在地球上,城市的地理位置.GPS定位.一些地标的地理位置等是由经纬度给出的,本文主要根据两个地理位置的经纬度,来计算两个地理位置之间的距离. %计算城市间距离 zb= ...

  2. JAVA 计算地球上任意两点(经纬度)距离

    /*** 计算地球上任意两点(经纬度)距离* * @param long1* 第一点经度* @param lat1* 第一点纬度* @param long2* 第二点经度* @param lat2* ...

  3. JOJ2737:狼与羊的故事(求图上任意两点间的桥边)

     2737: 狼与羊的故事 Result TIME Limit MEMORY Limit Run Times AC Times JUDGE 3s 65536K 53 10 Standard 村长要召开 ...

  4. 3维两点间的距离 js_高考必刷题4:球面上任意两点间距离的计算

    678地理工作室,每天,6:13 678地理工作室诚邀一起合作的小伙伴 文章首发于微信公众号"老丁侃地理",欢迎关注 本文为老丁原创,引用请注明来源 第一部分:经纬网部分,考纲和知 ...

  5. golang计算任意两点间的方位角

    计算任意两点间的方位角 方位角是从某点的指北经线起,依顺时针方向到目标方向线之间的水平夹角(如图所示θ,可以将其看成是指南针所指示的角度),也即是OPN平面与OPQ平面的所构成的二面角大小. 以北极点 ...

  6. matlab求椭圆的弧长,用MATLAB实现求椭球上任意两点的最短弧长

    基于法向矢量导向的求椭球上两点的最短弧长 问题分析 求椭球上任意两点间的最短弧长用数学来推算解析解的话十分复杂,因此考虑通过使用计算机来近似求解.问题的难点在于怎样让每一步都是处在最优的状态,以及怎样 ...

  7. 球面两点间的球面距离的计算

    球面两点间的球面距离的计算 实际上这是一个很简单的问题,今天之所以把他提出来并作出解决方案,是因为昨天在讨论项目的时候,项目lead提出计算地球球面上两点的球面距离是很难的,实际上是一个很简单的立体几 ...

  8. 球面两点间的球面距离的计算(2)

    球面两点间的球面距离的计算(2)   1.计算 上篇中提到了两点间球面距离的计算的理论基础,在这篇中,进行计算. 同样,假设点A的经度为东经a1度,纬度为北纬b1度:点B的经度为东经a2度,纬度为南纬 ...

  9. matlab利用经纬度计算距离_【Matlab】根据经纬度计算两点间的球面距离

    做建模或者研究空间数据,可能会遇到"根据经纬度计算两点间的球面距离"的问题,网上的资料很多,都是各种公式推导,但是一旦按公式编程计算,很可能得不到正确的距离.根本原因是在" ...

最新文章

  1. android查看报错日志,android运行错误日志帮看下 不懂啊
  2. poj 3461 Oulipo(kmp统计子串出现次数)
  3. kafka的groupid
  4. 【NLP】bert4vec:一个基于预训练的句向量生成工具
  5. Linux CentOS 6.x 关闭图形化界面的方法
  6. MySQL面试题 数据库设计三范式
  7. ubuntu14.04的键盘失灵解决方案
  8. spring+mybatis实现读写分离
  9. extjs中元数据_json – 如何配置ExtJS 4 Store(代理和阅读器)来读取元数据
  10. 寄存器地址和内存地址_通俗易懂和你聊聊寄存器那些事(精美图文)
  11. Moss 2007 入门(1) - 功能概述【转】
  12. 伪指令相当于c语言的什么,ARM汇编中关于“.word”伪指令的概念(转)
  13. 基于OMCS的远程桌面实现远程控制地面站
  14. Jumony(二)jQuery的设计艺术和选择器
  15. CMD使用教程-整理最全面的cmd用法
  16. win7系统获得管理员取得所有权的方法【系统天地】
  17. 线性调频信号MATLAB仿真
  18. python绘制直方图
  19. 用python画动态皮卡丘_如何利用python绘制可爱皮卡丘?
  20. 高配云计算机平台,云电脑真的来了!小破本也能秒变高配

热门文章

  1. python word操作添加超链接_使用pythondocx在MSWord中添加超链接
  2. java中使用unzip_java实现zip与unzip
  3. 不要怕伤害你最爱的人
  4. web服务器的网站选项,Web服务器配置方法(2)
  5. c 获取webform页面html,C#-WebForm-纯HTML提交方式
  6. 剑指offer笔记(五)字符串注意事项
  7. 在特斯拉工作,到底要会几门语言,排第一的竟然是它?
  8. 英文文献翻译策略:一种解决划词翻译包含换行符的最优策略
  9. android 通知id,java – Android:获取唯一的通知ID
  10. 推荐 :完备的 AI 学习路线,最详细的资源整理!