相交矩形 [英] Intersecting rectangles

查看:140
本文介绍了相交矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个解析几何一种question.I的我不知道我能here.However张贴它,我必须拿出一个Java函数来做到这一点functionality.I有一个页面多个矩形/摆动container.I知道该rectangles.Now的界限,我需要找哪个矩形相互交叉other.One好东西在这里相交的矩形总是具有相同的Y成分,所有的矩形都是平等的height.I都根据它们的X坐标配对矩形和宽度

This is an analytical geometry kind of question.I am not sure I can post it here.However I have to come up with a Java function to do this functionality.I have multiple rectangles in a page/swing container.I know the bounds of the rectangles.Now I need to find which rectangles are intersecting each other.One good thing here intersecting rectangles will always have the same y component and all rectangles are of equal height.I have to pair the rectangles based on their x coordinates and width

例如

Rect1 has bounds:20,10,50,20
Rect2 has bounds:60,10,30,20
Rect3 has bounds:40,10,40,20
Rect4 has bounds 20,30,40,20
Rect5 has bounds 20,50,30,20

现在我的方法应该返回

Rect1 and Rect2
Rect2 and Rect3
Rect3 and Rect1

有没有什么算法或以前有没有人尝试过​​吗?给你的建议

Is there any algorithm or has anyone tried it before?Give your suggestions

编辑:为了更具体的我矩形实际上是一个JLabel。我放置一个表的行内的标签。

To be more specific my rectangle is actually a JLabel. I am placing the labels inside the rows of a table.

推荐答案

1)首先,我同意其他人指出,这实际上是一个一维的问题:给定一组找到所有相交的对。

1) First, I agree with others that pointed out that this is actually a one dimensional problem: given a set of segments, find all the pairs that intersect.

2)请注意,你不能保证在最坏情况下,任何为O更好的(N ^ 2),因为该段都可能相互重叠。

2) Note that you can't guarantee anything better than O(N^2) in the worst case, since the segments may all overlap each other.

3)假设矩形的数目大,并且交叉点的数目不总是cuadratic在N,我会使用扫描技术:

3) Assuming that the number of rectangles is big, and that the number of intersections is not always cuadratic in N, I would use the sweep technique:

A)排序的所有片段开始点和结束点。

A) Sort all segment start points and end points in increasing order.

B)遍历列表,并收集方式交叉点。每次迭代重新presents一块轴被扫描,其中涵盖了它的部分很容易确定的。

B) Traverse the list, and collect intersections on the way. Each iteration represents a piece of the axis being scanned, where the segments covering it are easily determined.

4)请注意,如果你只需要在路口,那么你就可以在O做到这一点(N日志N)的时间。

4) Note that if you only need the number of intersections, then you can do it in O(N log N) time.

下面是有效地做这项工作的通用工具。在底部,你可以找到一个使用例子。请记住,这个解决方案是唯一相关的,如果你不希望很多交叉点。此外,它是一种矫枉过正少数段(我想,这是你的情况 - 因为你正在用N< 100 UI项)。不过,我写了一个练习,并享受吧:)

Here is a generic utility that does the job efficiently. At the bottom you can find a usage example. Remember that this solution is only relevant if you don't expect many intersections. Also, it is an overkill for a small number of segment (I suppose that this is your case - since you are working with N < 100 UI items). However, I wrote it as an exercise and enjoyed it :)

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.AbstractMap.SimpleEntry;


public class SegmentSet <T> {   
    private List<Segment> segments = new ArrayList<Segment>();  

    //note that x2 is inclusive
    public void add(int x1, int x2, T identity) {
        segments.add(new Segment(x1,x2, identity));
    }

    public List<SimpleEntry<T, T>> getAllIntersectingPairs() {
        // Build a list of all segment edges
        ArrayList<Edge> edges = new ArrayList<Edge>(2 * segments.size());
        int i=0;
        for(Segment seg : segments) {
            edges.add(new Edge(EdgeType.START, seg.x1, seg));
            edges.add(new Edge(EdgeType.END, seg.x2, seg));
        }

        // Sort the edges in ascending order
        Collections.sort(edges);

        // Sweep
        ArrayList<SimpleEntry<T, T>> res = new ArrayList<SimpleEntry<T, T>>();
        HashMap<Segment, Object> currSegments = new HashMap<Segment, Object>();
        for (Edge edge : edges) {
            if (edge.type == EdgeType.START) {
                for (Segment seg : currSegments.keySet())
                    res.add(new SimpleEntry<T, T>(edge.seg.identity, seg.identity));
                currSegments.put(edge.seg, null);
            } else {
                currSegments.remove(edge.seg);
            }
        }

        return res;
    }

    public class Segment {
        public final int x1;
        public final int x2;
        public final T identity;

        public Segment(int x1, int x2, T identity) {
            this.x1 = x1;
            this.x2 = x2;
            this.identity = identity;
        }
    }

    private enum EdgeType {START, END};

    private class Edge implements Comparable<Edge>{
        public final EdgeType type;
        public final int x;
        public Segment seg;

        public Edge(EdgeType type, int x, Segment seg) {
            this.type = type;
            this.x = x;
            this.seg = seg;
        }

        @Override
        public int compareTo(Edge o) {
            if (x > o.x)
                return 1;
            if (x < o.x)
                return -1;
            // A start Edge will come before an end edge in case of equal X value
            return type.ordinal() - o.type.ordinal();
        }
    }

    public static void main(String[] args) {
        SegmentSet<String> set = new SegmentSet<String>();
        set.add(10,100,"A");
        set.add(110,200,"B");
        set.add(0,400,"C");
        System.out.println(set.getAllIntersectingPairs());
    }
}

这篇关于相交矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆