/* * 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 de.fhg.igd.geom.shape.Line2D; /** * Contains a set of sweep-line segments. * * @author Michel Kraemer */ public class SweepLine { /** * A SweepPoint2DXYComparator which can compare Point2Ds */ private static SweepPoint2DXYComparator _p2dxyc = new SweepPoint2DXYComparator(); /** * The sorted list that contains all sweep-line segments */ private final SortedCollection<SweepLineSegment> _list; /** * A comparator which compares sweep line segments */ private final SweepLineComparator _slc; /** * The current sweep line position */ private double _position = 0.0; /** * Default constructor */ public SweepLine() { _slc = new SweepLineComparator(0.0); _list = new SortedCollection<SweepLineSegment>(_slc); } /** * Converts a Point2DEvent to a SweepLineSegment * * @param event the event to convert * @return the sweep line segment */ private SweepLineSegment makeSegment(Point2DEvent event) { Line2D line = event.getLineSegment(); SweepLineSegment s = new SweepLineSegment(line, event.getPolygon()); if (_p2dxyc.compare(line.getPoints()[0], line.getPoints()[1]) < 0) { s.setLeftPoint(line.getPoints()[0]); s.setRightPoint(line.getPoints()[1]); } else { s.setLeftPoint(line.getPoints()[1]); s.setRightPoint(line.getPoints()[0]); } return s; } /** * Adds a Point2DEvent to the sweep-line * * @param event the Point2DEvent * @return a sweep-line segment created to hold the Point2DEvent */ public SweepLineSegment add(Point2DEvent event) { SweepLineSegment s = makeSegment(event); _list.add(s); // set new sweep line position and resort the list double x = s.getLeftPoint().getX(); if (x != _position) { _position = x; _slc.setPosition(x); _list.resort(); } return s; } /** * Gets the SweepLineSegment that represents the given Point2DEvent * * @param event the Point2DEvent * @return the SweepLineSegment */ public SweepLineSegment get(Point2DEvent event) { SweepLineSegment s = makeSegment(event); int i = _list.indexOf(s); if (i == -1) { return null; } return _list.get(i); } /** * Removes a SweepLineSegment from the SweepLine * * @param s the segment to remove * @return true if the segment was removed, false otherwise */ public boolean remove(SweepLineSegment s) { return _list.remove(s); } /** * Gets the segment which is below the given one. * * @param s the given segment * @return the segment below s or null if there is no such segment */ public SweepLineSegment getBelowSegment(SweepLineSegment s) { int i = _list.indexOf(s); if (i == -1 || i >= _list.size() - 1) { return null; } return _list.get(i + 1); } /** * Gets the segment which is above the given one. * * @param s the given segment * @return the segment above s or null if there is no such segment */ public SweepLineSegment getAboveSegment(SweepLineSegment s) { int i = _list.indexOf(s); if (i < 1) { return null; } return _list.get(i - 1); } }