Language agnostic 确定经纬度矩形和球体上的圆是否重叠
假设我有以下几点:Language agnostic 确定经纬度矩形和球体上的圆是否重叠,language-agnostic,math,geometry,gis,trigonometry,Language Agnostic,Math,Geometry,Gis,Trigonometry,假设我有以下几点: 由最小和最大纬度和经度定义的区域(通常为“lat-long-rect”,但除了某些投影外,它实际上不是矩形) 一个圆,由一个中心纬度/长度和一个半径定义 我如何确定: 两个形状是否重叠 圆是否完全包含在矩形中 我在寻找一个完整的公式/算法,而不是数学课程本身。警告:如果圆/矩形跨越球体的大部分,这可能会很棘手,例如: “矩形”:最小长度=-90度,最大长度=+90度,最小横向=+70度,最大横向=+80度 圆:圆心=纬度=+85度,长=+160度,半径=20度(例如,如果
- 由最小和最大纬度和经度定义的区域(通常为“lat-long-rect”,但除了某些投影外,它实际上不是矩形)
- 一个圆,由一个中心纬度/长度和一个半径定义
我在寻找一个完整的公式/算法,而不是数学课程本身。警告:如果圆/矩形跨越球体的大部分,这可能会很棘手,例如: “矩形”:最小长度=-90度,最大长度=+90度,最小横向=+70度,最大横向=+80度 圆:圆心=纬度=+85度,长=+160度,半径=20度(例如,如果点A在圆上,点C是圆的圆心,点O是球体的圆心,则角度AOC=40度) 这些交叉点,但数学可能有几种情况来检查交叉点/包容。以下点位于上述圆上:P1=(+65度纬度,+160度长),P2=(+75度纬度,-20度长)。P1在“矩形”外,P2在“矩形”内,因此圆/矩形至少相交2点 好的,下面是我对解决方案的概述:
设C=半径为R的圆心(如上所述,用球面角表示)。C有纬度LATC和经度LONGC。因为“矩形”这个词在这里有点误导(恒定纬度的线不是大圆的线段),所以我将使用术语“边界框”
- 函数
返回+1,0或-1:如果点p在圆内,返回+1;如果点p在圆上,返回0;如果点p在圆外,返回-1:计算大圆距离D(表示为球面角)在C和任何点P之间,都会告诉你P是否在圆圈内:内圆(p)
(正如user@Die in Sente提到的,在这个论坛的其他地方已经询问了很大的圆圈距离)InsideCircle(P)=符号(R-D)
- 定义
=x=MOD(x+180度,360度)-180度的主角度<代码>倾斜(x)始终在-180度和+180度之间,包括(+180度应映射到-180度)PANG(x)
- 要定义边界框,您需要知道4个数字,但经度有一个小问题。LAT1和LAT2表示边界纬度(假设LAT1
- LAT1这个怎么样
查找将矩形中心点
连接到圆中心的向量Cr
。查找与矩形相交的点v
。如果i
则它们相交 换句话说,矩形内线段的长度加上圆内线段的长度应大于总长度(v|i-Cr |+r>| v | |
,中心连接线段) 查找点v
应该是个棘手的部分,特别是当它落在经度边缘时,但是你应该能够比我更快地找到一些东西 编辑:此方法无法判断圆是否完全在矩形内。您需要找到从其中心到矩形所有四条边的距离i
编辑:上述内容不正确。正如Federico Ramponi所建议的,在某些情况下,它甚至在欧几里德几何中也不起作用。我将发布另一个答案。请不要接受这一点,请随意投反对票。我很快就会删除它。再试试这个 我认为解决方案是测试一组点,正如Jason S所建议的,但我不同意他选择的点,我认为这在数学上是错误的 您需要在lat/long框的侧面找到点,其中到圆中心的距离为局部最小值或最大值。将这些点添加到角点集,则上述算法应该是正确的 也就是说,让经度为x维,纬度为y维
框的侧面是o的参数曲线P(t)=P0+t(P1-P0)。对于欧几里德几何答案,请参见:这适用于地球上的任何点。如果要将其更改为不同大小的球体,只需将kEarchRadiusKms更改为球体所需的任意半径
此方法用于计算到lat和lon点之间的距离 我从这里得到了这个距离公式: 如果矩形的任何顶点之间的距离小于圆半径的距离,则圆和矩形重叠。如果圆心与所有顶点之间的距离大于圆的半径,且所有这些距离都小于矩形的宽度和高度,则圆应位于矩形的内部 如果你能发现我的代码有问题的话,请随意修改我的代码public static double Calc(double Lat1, double Long1, double Lat2, double Long2) { double dDistance = Double.MinValue; double dLat1InRad = Lat1 * (Math.PI / 180.0); double dLong1InRad = Long1 * (Math.PI / 180.0); double dLat2InRad = Lat2 * (Math.PI / 180.0); double dLong2InRad = Long2 * (Math.PI / 180.0); double dLongitude = dLong2InRad - dLong1InRad; double dLatitude = dLat2InRad - dLat1InRad; // Intermediate result a. double a = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) + Math.Cos(dLat1InRad) * Math.Cos(dLat2InRad) * Math.Pow(Math.Sin(dLongitude / 2.0), 2.0); // Intermediate result c (great circle distance in Radians). double c = 2.0 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1.0 - a)); // Distance. // const Double kEarthRadiusMiles = 3956.0; const Double kEarthRadiusKms = 6376.5; dDistance = kEarthRadiusKms * c; return dDistance; }
public string Test(double cLat, double cLon, double cRadius, double rlat1, double rlon1, double rlat2, double rlon2, double rlat3, double rlon3, double rlat4, double rlon4) { double d1 = Calc(cLat, cLon, rlat1, rlon1); double d2 = Calc(cLat, cLon, rlat2, rlon2); double d3 = Calc(cLat, cLon, rlat3, rlon3); double d4 = Calc(cLat, cLon, rlat4, rlon4); if (d1 <= cRadius || d2 <= cRadius || d3 <= cRadius || d4 <= cRadius) { return "Circle and Rectangle intersect..."; } double width = Calc(rlat1, rlon1, rlat2, rlon2); double height = Calc(rlat1, rlon1, rlat4, rlon4); if (d1 >= cRadius && d2 >= cRadius && d3 >= cRadius && d4 >= cRadius && width >= d1 && width >= d2 && width >= d3 && width >= d4 && height >= d1 && height >= d2 && height >= d3 && height >= d4) { return "Circle is Inside of Rectangle!"; } return "NO!"; }
- LAT1这个怎么样
查找将矩形中心点