/* * Copyright (c) 2016 Fraunhofer IGD * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Fraunhofer IGD <http://www.igd.fraunhofer.de/> */ package de.fhg.igd.geom.algorithm.sweepline; import java.util.Collections; import java.util.Comparator; import de.fhg.igd.geom.shape.Line2D; import de.fhg.igd.geom.shape.Polygon; /** * Represents a queue of events during a sweep-line search * * @author Michel Kraemer */ public class Point2DEventQueue { /** * A sorted list that contains all events (in reverse order, so they can be * removed faster) */ private final SortedCollection<Point2DEvent> _list; /** * A Point2D comparator used to sort points in the list */ private final Comparator<Point2DEvent> _p2deventc; /** * A Point2D comparator used to compare points */ private final SweepPoint2DXYComparator _p2dxyc; /** * Constructs a new EventQueue */ public Point2DEventQueue() { _p2deventc = Collections.reverseOrder(new SweepPoint2DEventComparator()); _p2dxyc = new SweepPoint2DXYComparator(); _list = new SortedCollection<Point2DEvent>(_p2deventc); } /** * Removes an event from the head of this queue * * @return the event or null if the queue is empty */ public Point2DEvent remove() { if (_list.isEmpty()) { return null; } return _list.remove(_list.size() - 1); } /** * @return the number of elements in the queue */ public int size() { return _list.size(); } /** * @return true if the queue is empty */ public boolean isEmpty() { return _list.isEmpty(); } /** * Adds a 2D line with exactly two Points to the queue. * * @param p the line to add * @param poly the Polygon the given line belongs to * @return true if the line has been added, false otherwise */ public boolean add(Line2D p, Polygon poly) { if (p.getPoints().length != 2) { throw new IllegalArgumentException( "The Line2D must be a simple " + "line with two Points"); } if (p.getPoints()[0].equals(p.getPoints()[1])) { throw new IllegalArgumentException("Degenerated line"); } if (p.getPoints()[0].getX() == p.getPoints()[1].getX()) { throw new IllegalArgumentException("Line must not be vertical"); } // sort points and create events boolean l = _p2dxyc.compare(p.getPoints()[0], p.getPoints()[1]) < 0; Point2DEvent p1 = new Point2DEvent(p.getPoints()[0], p, l, poly); Point2DEvent p2 = new Point2DEvent(p.getPoints()[1], p, !l, poly); // add events to set if (!_list.add(p1)) { return false; } if (!_list.add(p2)) { // remove p1 to leave the list in // a consistent state _list.remove(p1); return false; } return true; } /** * Clears the queue */ public void clear() { _list.clear(); } }