如何在Sweep-line算法中检测右端点

时间:2012-10-28 02:52:44

标签: java algorithm geometry computational-geometry

我想知道Sweep line algorithm我们如何检测形状的右端点(圆形或矩形),因为我们使用从左到右的扫描垂直线扫描?因此算法基本上是每当我们点击左端点然后插入该形状的y间隔的区间树时,当我们点击任何形状的右端点时,我们将其从间隔树中移除。例如

    ArrayList<Circle> circles = new ArrayList<Circle>();
    BinarySearchTree<Interval> intervalTree = new BinarySearchTree<Interval>();

    //sort by x coordinate
    Collections.sort(circles, new Comparator<Circle>(){
          @Override
          public int compareTo(Circle c1, Circle c2){
                return c1.x - c2.x;
          }
    });        

    //here's where the sweep line begins
    for(int i = 0; i < circle.size(); i++)
    {
          //we hit the ith circle's left endpoint 
          Circle current = circle.get(i);

          //insert into the interval tree
          intervalTree.addInterval(new Interval(current.y, current.y+current.height));

    }

但是我们什么时候才能知道我们是否到达了Circle的正确端点?我们需要另一个哈希映射吗?

1 个答案:

答案 0 :(得分:1)

public enum EventType {
    START,
    END;
}

public class EventPoint implements Comparable<EventPoint> {
    public EventType type;
    public double x;
    public Circle circle;
    public Interval interval;

    public EventPoint(EventType type, double x,
            Circle circle, Interval interval) {
        this.type = type;
        this.x = x;
        this.circle = circle;
        this.interval = interval;
    }

    /**
     * Compare this EventPoint with another. This is used by the priority
     * queue to determine the "minimum" event.
     */
    public int compareTo(EventPoint other) {
        return Double.compare(x, other.x);
    }

    /** Creates a start event, with a circle. */
    public static EventPoint start(double x, Circle circle) {
        return new EventPoint(START, x, circle, null);
    }

    /** Creates an end event, with an interval. */
    public static EventPoint end(double x, Interval interval) {
        return new EventPoint(END, x, null, interval);
    }
}
PriorityQueue<EventPoint> events = new PriorityQueue<EventPoint>();
BinarySearchTree<Interval> intervalTree = new BinarySearchTree<Interval>();

// Initialize all the start events, and include the corresponding circle.    
for (Circle c : circles) {
    events.add(EventPoint.start(c.x, c));
}

while (!events.isEmpty()) {

    // Remove the minimum (leftmost) event from the queue
    EventPoint ep = events.poll();

    switch (ep.type) {

        case START:
            Circle current = ep.circle;
            // (Look for intersections in the interval tree...)

            // Create an interval and add it to the interval tree
            Interval interval = new Interval(current.y, current.y +
                    current.height);
            intervalTree.add(interval);

            // Add an end-event to the queue, and include the interval for
            // later removal.
            events.add(EventPoint.end(current.x + current.width, interval));

            break;

        case END:
            // Remove the interval from the interval tree.
            intervalTree.remove(ep.interval);
            break;
    }
}