C++ 找出一个点是否在voronoi单元内

C++ 找出一个点是否在voronoi单元内,c++,boost,voronoi,boost-polygon,C++,Boost,Voronoi,Boost Polygon,有没有一种简单的方法来确定一个点是否在voronoi单元内 例如,以下代码生成类似下图的内容: using namespace boost::polygon; point_data<int> p1(0, 0); point_data<int> p2(-10, 10); point_data<int> p3(-10, -10); point_data<int> p4(10, -10); point_data<int> p5(10, 10

有没有一种简单的方法来确定一个点是否在voronoi单元内

例如,以下代码生成类似下图的内容:

using namespace boost::polygon;

point_data<int> p1(0, 0);
point_data<int> p2(-10, 10);
point_data<int> p3(-10, -10);
point_data<int> p4(10, -10);
point_data<int> p5(10, 10);

std::vector<point_data<int>> pts = { p1, p2, p3, p4, p5 };
construct_voronoi(pts.begin(), pts.end(), vd);
使用名称空间boost::polygon;
点_数据p1(0,0);
点_数据p2(-10,10);
点_数据p3(-10,-10);
点_数据p4(10,-10);
点_数据p5(10,10);
向量pts={p1,p2,p3,p4,p5};
构造voronoi(pts.begin(),pts.end(),vd);

在这种情况下,如何确定点(5,5)是否在中心单元格内


我可以从每个单元格中创建一个多边形,并使用a来查找,但我感兴趣的是,该库提供了“免费”的内容。

就像@Magnus Hoff评论的那样,由离查询点最近的中心定义的单元格必须包含它(直到距离)。事实上,这来自Voronoii单元的定义,即其成员更靠近单元中心而不是任何其他中心的点集。 因此,此查询实际上不需要
boost::polygon
或半线算法:

//using namespace boost::polygon;
using namespace std;
#include <iostream>
#include <vector>
#include <limits>

template <typename T> 
using point_data = std::pair<T,T>;
point_data<int> p1(0, 0);
point_data<int> p2(-10, 10);
point_data<int> p3(-10, -10);
point_data<int> p4(10, -10);
point_data<int> p5(10, 10);

std::vector<point_data<int>> pts = { p1, p2, p3, p4, p5 };
//construct_voronoi(pts.begin(), pts.end(), vd);


double dist2(point_data<int> pt1,point_data<int> pt2) {
  return (pt1.first-pt2.first)*(pt1.first-pt2.first) + (pt1.first-pt2.second)* (pt1.first-pt2.second);
}

bool isInCell(point_data<int> point) {
  double d = numeric_limits<double>::max();

  point_data<int> ptClose;
  for (auto& pt:pts) {
    if (dist2(pt,point) < d)
      ptClose = pt;
  }
  return ptClose == point;
}

int main() {
  cout << isInCell(make_pair(5,5)) << endl;
}
//使用名称空间boost::polygon;
使用名称空间std;
#包括
#包括
#包括
模板
使用point_data=std::pair;
点_数据p1(0,0);
点_数据p2(-10,10);
点_数据p3(-10,-10);
点_数据p4(10,-10);
点_数据p5(10,10);
向量pts={p1,p2,p3,p4,p5};
//构造voronoi(pts.begin(),pts.end(),vd);
双区2(点数据pt1、点数据pt2){
返回(pt1.first-pt2.first)*(pt1.first-pt2.first)+(pt1.first-pt2.second)*(pt1.first-pt2.second);
}
布尔伊森塞尔(点\数据点){
双d=数值_限制::max();
点_数据关闭;
用于(自动和pt:pts){
if(距离2(点,点)您可能需要点位置测试,特别是用于点位置测试的kirkpatrick数据结构,但它有点复杂。相反,您可以为每个voronoi单元指定一种颜色,并检查该点的颜色。

一个好方法是让点站点由一些空间分区数据结构(如KD树)支持它提供了简单的(N-)最近邻搜索(事实上,任何像样的voronoi图实现都应该已经在插入点站点期间为最近邻搜索进行了此操作)


因此,在图表旁边使用您自己的数据结构(树):当点站点插入到voronoi图表中时,将相同的点插入到树中。查询树以查找(N)个最近的voronoi站点。然后由您决定如何将该场地坐标映射到voronoi单元对象。

最简单的方法可能是迭代所有多边形,验证中间点0,0是否在其中,并检查该点是否在其中。我不确定该点的结果是什么
(5,5)
,它正好位于示例数据中两个单元格之间的边界上。无论如何,另一种方法(不使用多边形中的点算法)是检查从测试点到定义每个voronoi单元格的点的距离。最靠近测试点的点告诉您测试点所在的单元格。您可以比较
square_dist
(避免
sqrt
(和
double
)。谢谢你的回答。不过有一个问题:如果有,比如说,>100000个单元格,这种方法会不会太慢?如果你真的想处理100000个单元格,有一种更有效的方法可以找到计算几何中一个点的最近点。或者,如果这个查询是重复的,你可以使用一些空间索引。它们有点复杂更复杂的是。@Jarod42,谢谢你的更正。拼写错误更正,使用了距离平方。@TingL,非常感谢你的回答。这正是我想要的。我的错是我没有意识到“多边形中的点”不是最好的路线。事实证明,我甚至不需要提升。OP是问如何测试点是否在给定的单元格中,而不是找到哪个单元格包含该点。@Sneftel它最终是相同的:return getContainingCell(point)=givenCell