package com.interview.books.topcoder.geometry; import com.interview.leetcode.utils.Point; import java.util.*; /** * Created_By: stefanie * Date: 15-1-12 * Time: 下午2:39 */ public class TC_G15_LineSegmentIntersection_Aligned { static class Line{ Point[] points = new Point[2]; public Line(Point p1, Point p2){ if(p1.x != p2.x){ points[0] = p1.x <= p2.x? p1 : p2; points[1] = p1.x <= p2.x? p2 : p1; } else { points[0] = p1.y <= p2.y? p1 : p2; points[1] = p1.y <= p2.y? p2 : p1; } } public boolean isVertical(){ if(points[0].x == points[1].x) return true; else return false; } } static Comparator<Line> START_HORIZONTAL_COMPARATOR = new Comparator<Line>() { @Override public int compare(Line o1, Line o2) { if(o1.points[0].x == o2.points[0].x){ return o1.isVertical()? 1 : -1; } else { return o1.points[0].x - o2.points[0].x; } } }; static Comparator<Line> END_HORIZONTAL_COMPARATOR = new Comparator<Line>() { @Override public int compare(Line o1, Line o2) { return o1.points[1].x - o2.points[1].x; } }; public List<Point> intersection(Line[] lines){ List<Point> intersections = new ArrayList(); Arrays.sort(lines, START_HORIZONTAL_COMPARATOR); PriorityQueue<Line> horizonals = new PriorityQueue(lines.length, END_HORIZONTAL_COMPARATOR); SortedSet<Integer> verticals = new TreeSet(); for(int i = 0; i < lines.length; i++){ Line current = lines[i]; while(!horizonals.isEmpty() && horizonals.peek().points[1].x < current.points[0].x){ Line line = horizonals.poll(); verticals.remove(line.points[0].y); } if(current.isVertical()){ for(Integer point : verticals.subSet(current.points[0].y, current.points[1].y)){ intersections.add(new Point(current.points[0].x, point)); } } else { verticals.add(current.points[0].y); horizonals.add(current); } } return intersections; } public static void main(String[] args){ TC_G15_LineSegmentIntersection_Aligned finder = new TC_G15_LineSegmentIntersection_Aligned(); Line[] lines = new Line[7]; lines[0] = new Line(new Point(0,2), new Point(2,2)); lines[1] = new Line(new Point(1,1), new Point(1,3)); lines[2] = new Line(new Point(3,4), new Point(5,4)); lines[3] = new Line(new Point(4,3), new Point(7,3)); lines[4] = new Line(new Point(4,1), new Point(4,5)); lines[5] = new Line(new Point(4,7), new Point(5,7)); lines[6] = new Line(new Point(6,4), new Point(6,6)); List<Point> intersections = finder.intersection(lines); for(Point point : intersections){ System.out.println(point.x + ", " + point.y); //(1,2),(4,3),(4,4) } } }