C++ 查找相交矩形组
我有一个矩形列表(它们不能旋转): 组顺序和组内元素顺序并不重要 如何计算这些组?如有必要,我可以更改数据结构 例如,我可以将C++ 查找相交矩形组,c++,algorithm,intersection,C++,Algorithm,Intersection,我有一个矩形列表(它们不能旋转): 组顺序和组内元素顺序并不重要 如何计算这些组?如有必要,我可以更改数据结构 例如,我可以将std::vector更改为std::set,并按左顶点X坐标对矩形进行排序。这样我就可以使用扫描线算法。但我找不到任何可以应用于我的问题的样本 如何获得交叉组 我认为集合向量可以完成这项工作 像这样: std::vector< std::set< int > > groups; // loop over rectangles for( int
std::vector
更改为std::set
,并按左顶点X坐标对矩形进行排序。这样我就可以使用扫描线算法。但我找不到任何可以应用于我的问题的样本
如何获得交叉组
我认为集合向量可以完成这项工作 像这样:
std::vector< std::set< int > > groups;
// loop over rectangles
for( int r1 = 0; r1 < rectangles.size(); r1++ )
{
// check if rectngle already in group
auto g_it = groups.end();
for( auto group = groups.begin();
group != groups.end(); group++ )
{
auto group_r1_it = group->find( r1 );
if( group_r1_it != group->end() )
{
g_it = group;
break;
}
}
if( g_it == groups.end() )
{
// not already in group, so create new group
set<int> s;
s.insert( r1 );
groups.push_back( s );
g_it = groups.end()-1;
}
// loop over remaining rectangles
for( int r2 = r1+1; r2 < rectangles.size(); r2++ )
{
// check for intersection
if( rectangles[r1].Intersect( rectangles[r2] ))
{
//report intersection
cout << r1+1 <<" " <<r2+1 << endl;
// add to group
g_it->insert( r2 );
}
}
}
// Display results
for ( auto group : groups )
{
cout << "{ ";
for( auto r : group )
{
cout << r+1 << " ";
}
cout << "} ";
}
cout << endl;
std::vector>组;
//在矩形上循环
对于(int r1=0;r1find(r1);
如果(组\u r1\u it!=组->结束()
{
g_it=组;
打破
}
}
如果(g_it==groups.end())
{
//不在组中,因此创建新组
设置s;
s、 插入(r1);
分组。推回;
g_it=groups.end()-1;
}
//在剩余矩形上循环
对于(int r2=r1+1;r2 cout我一直在研究一个问题,OP的问题是一个中间解决方案。给定的一组矩形(或任何一组矩形)的过程如下:
列出与每个矩形相交的矩形。因此,对于示例中的6个矩形,我们将有6个列表。步骤1的结果如下所示:
[[1,2],[2,1,4],[4,2],[3],[5,6],[6,5]]
接下来,我们迭代这个列表,如果下一个列表中存在任何一个矩形,则合并列表。例如,列表1的矩形1存在于列表2中。因此,由列表1和列表2组成的合并列表将是[1,2,4].清空列表1,以便我们不能在下一次迭代中再次使用它。每次迭代的结果如下所示:
[[],[2,1,4],[4,2],[3],[5,6],[6,5]]
[[], [], [4,2,1], [3], [5,6], [6,5]]
[[], [], [4,2,1], [3], [5,6], [6,5]]
[[], [], [4,2,1], [3], [5,6], [6,5]]
[]、[]、[4,2,1]、[3]、[6,5]。
从列表中删除空列表。结果是一组相交的矩形
[[4,2,1],[3],[6,5]]
希望这有帮助。我不太流利地说C++。但是,如果它有帮助,我可以和大家分享我写的导演Lango代码。我没有张贴LINGO代码的原因是因为很少有人在导演中工作。< / P>你可以很容易地把扫描与UNINOFING结合起来。有没有任何目录或样本可以适合我的?具体问题?@Danstahr感谢关键字,很好知道:)。我不知道,但应该不需要。Union Find在Kruskal的最小规划树算法中使用。如果您已经有了查找相交的算法(假设我们有对相交矩形ID),您只需调用Union()对这些对进行操作。结构会处理其余部分并提供结果。好的,我会通过网络检查。谢谢你的时间。Thanls我会检查它。它不使用扫描线,但现在我认为这不会是一个问题,因为我一次必须处理大约20个矩形…你说的扫描线是什么?@ravenspoint这是一种避免在矩形上嵌套for循环的方法,但仅对20个循环,实现它是浪费时间的。好的。我已将交点计算与分组计算分离,因此您可以使用您最喜欢的方法在一组矩形中检测交点。
{{3}, {4, 1, 2}, {5, 6}}
std::vector< std::set< int > > groups;
// loop over rectangles
for( int r1 = 0; r1 < rectangles.size(); r1++ )
{
// check if rectngle already in group
auto g_it = groups.end();
for( auto group = groups.begin();
group != groups.end(); group++ )
{
auto group_r1_it = group->find( r1 );
if( group_r1_it != group->end() )
{
g_it = group;
break;
}
}
if( g_it == groups.end() )
{
// not already in group, so create new group
set<int> s;
s.insert( r1 );
groups.push_back( s );
g_it = groups.end()-1;
}
// loop over remaining rectangles
for( int r2 = r1+1; r2 < rectangles.size(); r2++ )
{
// check for intersection
if( rectangles[r1].Intersect( rectangles[r2] ))
{
//report intersection
cout << r1+1 <<" " <<r2+1 << endl;
// add to group
g_it->insert( r2 );
}
}
}
// Display results
for ( auto group : groups )
{
cout << "{ ";
for( auto r : group )
{
cout << r+1 << " ";
}
cout << "} ";
}
cout << endl;
class Rectangle
{
public:
double centerX;
double centerY;
double width;
double height;
int myID;
static int lastID;
Rectangle(double x, double y, double w, double h)
:centerX(x),centerY(y),width(w),height(h),
myID( ++lastID )
{ }
bool Intersect( const Rectangle& other ) const
{
...
}
bool operator ==(const Rectangle& other ) const
{
return myID == other.myID;
}
bool operator <(const Rectangle& other ) const
{
return myID < other.myID;
}
};
int Rectangle::lastID = 0;
class RectangleGroups
{
public:
typedef std::set< Rectangle > group_t;
typedef std::vector< group_t >::iterator iter;
iter begin()
{
return groups.begin();
}
iter end()
{
return groups.end();
}
/** Build the groups of intersecting trinagles
@param[in] rectangles vector of rectangles
@param[in] intersections vector of pairs of intersecting rectangles
*/
void Make(
std::vector< Rectangle > rectangles,
std::vector< std::pair< Rectangle&, Rectangle& > >& intesections )
{
// loop over intersecting triangles
for( auto rp : intesections )
{
iter g_it = Find( rp.first );
if( g_it != groups.end() )
{
g_it->insert( rp.second );
continue;
}
g_it = Find( rp.second );
if( g_it != groups.end() )
{
g_it->insert( rp.first );
continue;
}
// neither rectangle is already in group, so add new group
g_it = Add( rp.first );
g_it->insert( rp.second );
}
// Add orphans
for( auto& r : rectangles )
{
if ( Find( r ) == groups.end() )
{
Add( r );
}
}
}
/// Display rectangle IDs in groups marked off with curly braces
void Display()
{
for ( auto group : groups )
{
cout << "{ ";
for( auto r : group )
{
cout << r.myID << " ";
}
cout << "} ";
}
cout << endl;
}
private:
std::vector< group_t > groups;
/// Add new group containing a copy of a rectangle, return iterator pointing to new group
iter Add( const Rectangle& r )
{
group_t s;
s.insert( r );
groups.push_back( s );
return groups.end()-1;
}
/// Find group containing rectangle, return iterator pointing to found group or to end
iter Find( const Rectangle& r )
{
for( iter it = groups.begin(); it != groups.end(); it++ )
{
auto group_it = it->find( r );
if( group_it != it->end() )
{
return it;
}
}
return groups.end();
}
};
// vector of intesections
// you can build this using various algorithms, even a sweepline
// here I will use a simple pair of nested for loops
std::vector< std::pair< Rectangle&, Rectangle& > > intersections;
// loop over rectangles
for( auto& r1 : rectangles )
{
// loop over remaining rectangles
for( auto& r2 : rectangles )
{
if( r2 < r1 || r1 == r2 )
continue;
// check for intersection
if( r1.Intersect( r2 ))
{
intersections.push_back( std::pair<Rectangle&, Rectangle& >( r1, r2 ) );
}
}
}
// Construct a vector of rectangle groups
// The groups will contain interesecting rectangles.
RectangleGroups groups;
groups.Make(
rectangles,
intersections );
// Display results
groups.Display();