Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 查找相交矩形组_C++_Algorithm_Intersection - Fatal编程技术网

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;r2cout我一直在研究一个问题,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();