检查点是不是在圆圈内

Posted

技术标签:

【中文标题】检查点是不是在圆圈内【英文标题】:Check if point is inside circle检查点是否在圆圈内 【发布时间】:2020-01-07 18:09:21 【问题描述】:

我有一个名为 spotCoordinates 的地点的 GPS 坐标,中心是圆坐标 this.state.center,半径以公里为单位 this.state.radius

我正在尝试创建一种方法来检查 spotCoordinates 是否在一个圆圈内,但我不知道如何将半径添加到坐标以及如何检查它是否真的在圆圈内。如果是正方形会更容易。

 calculateParkingSpotsInTheArea = () => 
      this.state.parkingSpots.map(spot => 
          let spotCoordinates = spot.coordinates;
          console.log(spotCoordinates, this.state.center, this.state.radius);
          // Calculate if the parking spot is inside the circle
      );
  

例如在控制台中打印的值spotCoordinates = [41.5408446218337, -8.612296123028727] center = lat: 41.536558, lng: -8.627487 radius = 25

有什么帮助吗?

【问题讨论】:

这个帖子可能对你有用***.com/questions/14560999/… 使用勾股定理求圆中点的距离。如果它小于圆的直径,则该点在内部。 @user3783243 不同。我没有2个坐标。我需要从中心和半径计算圆“边缘” @MikeRobinson 你的意思是“如果它小于半径......” 41.5408446218337, -8.612296123028727 是一个点,41.536558, lng: -8.627487 是另一个点,不是吗? 【参考方案1】:

感谢this SO 链接和Great-circle distance

let spotCoordinates1 = [41.5408446218337, -8.612296123028727];
let spotCoordinates2 = [38.817459, -9.282218]

let center = lat: 41.536558, lng: -8.627487;
let radius = 25

checkIfInside(spotCoordinates1);
checkIfInside(spotCoordinates2);

function checkIfInside(spotCoordinates) 

    let newRadius = distanceInKmBetweenEarthCoordinates(spotCoordinates[0], spotCoordinates[1], center.lat, center.lng);
    console.log(newRadius)

    if( newRadius < radius ) 
        //point is inside the circle
        console.log('inside')
    
    else if(newRadius > radius) 
        //point is outside the circle
        console.log('outside')
    
    else 
        //point is on the circle
        console.log('on the circle')
    



function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) 
  var earthRadiusKm = 6371;

  var dLat = degreesToRadians(lat2-lat1);
  var dLon = degreesToRadians(lon2-lon1);

  lat1 = degreesToRadians(lat1);
  lat2 = degreesToRadians(lat2);

  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  return earthRadiusKm * c;


function degreesToRadians(degrees) 
  return degrees * Math.PI / 180;

【讨论】:

你能给我一个外面的坐标吗? 38.817459, -9.282218 千米sssss【参考方案2】:

你可以计算点到中心的距离,看看它是否小于半径,这里是一个例子:

const spotCoordinates = 
  lat: 41.5408446218337,
  lng: -8.612296123028727
;
const center = 
  lat: 41.536558,
  lng: -8.627487
;
const radius = 25;


function degreesToRadians(degrees) 
  return degrees * Math.PI / 180;


function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) 
  var earthRadiusKm = 6371;

  var dLat = degreesToRadians(lat2-lat1);
  var dLon = degreesToRadians(lon2-lon1);

  lat1 = degreesToRadians(lat1);
  lat2 = degreesToRadians(lat2);

  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  return earthRadiusKm * c;



function isInCircle(latLng) 
  const distance = distanceInKmBetweenEarthCoordinates(latLng.lat, latLng.lng, center.lat, center.lng);

  const calculationResult = distance <= radius;
  console.log("Is inside", calculationResult);


isInCircle(spotCoordinates);

以下是使用 Google 地图执行此公式的示例: https://jsfiddle.net/dpr9shz3/使用demo,只要点击地图上的任意位置,alert就会指定计算结果以及是否点击了圆形。

【讨论】:

我认为这是假设地球是平的。附近的景点将无法使用。 @user12361681 如果计算平面的半径和距离就足够准确了并且计算必须考虑坐标与两极的距离。 @user12361681 我看不出这对附近的地点不起作用的任何原因。 它将在 3 英里半径范围内工作,然后错误开始呈指数增长。 @user12361681 我已经编辑了我的答案并添加了一个带有演示的小提琴。这里的代码假设半径是公里,演示中的半径是米。【参考方案3】:

对此的表达是:

(center.x - pt.x)^2 + (center.y - pt.y)^2 < radius^2

您可以调整比较运算符以检查 pt 是在圆上 (==) 还是在圆边界之外 (>)。

这是一个 javascript 函数,如果 pt 在圆圈内,则返回 -1,如果在圆圈上,则返回 0,如果在圆圈外,则返回 1。

/**
 * @description Check if a pt is in, on or outside of a circle.
 * @param [float] pt The point to test. An array of two floats - x and y coordinates.
 * @param [float] center The circle center. An array of two floats - x and y coordinates.
 * @param float r The circle radius.
 * @returns -1 | 0 | 1 -1 if the point is inside, 0 if it is on and 1 if it is outside the circle.
 */
function ptInCircle(pt, center, r) 

    const lhs = Math.pow(center[0] - pt[0], 2) + Math.pow(center[1] - pt[1], 2);
    const rhs = Math.pow(r, 2);

    return lhs < rhs ? -1 : (lhs === rhs ? 0 : 1);

如果您不喜欢速记的嵌套三元运算符,可以将返回行换成这个:

if (lhs < rhs) 
    return -1
 else if (lhs === rhs) 
    return 0
 else 
    return 1

用法:

ptInCircle([0, 1], [1, 0], 1)
// Returns 1

【讨论】:

以上是关于检查点是不是在圆圈内的主要内容,如果未能解决你的问题,请参考以下文章

检查纬度和经度是不是在一个圆圈内

地理位置 - 如何检查 2 个圆圈是不是重叠

如何检查圆圈中的哪些点?

检查图像点是不是与圆相交

如何在圆圈范围内反弹物体?

检查点是不是在多边形内