Site Search:

IntersectionCounter.java

Back>



import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.*;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class IntersectionCounter {
    private static PriorityQueue<Event> pq = new PriorityQueue<>();
    private static Line[] lines
    
    private static final int N = 10;
    public static void main(String... args) {
        lines = new Line[N];
        for(int i = 0; i < N; i++) {
            lines[i] = new Line(BORDERSIZE);
        }
        myDraw(new LinesDraw(lines));
        
        for(int i = 0; i < N; i++) {
            Line l = lines[i];
            if(l.y0 == l.y1) {
                pq.add(new Event(Math.min(l.x0, l.x1), l.y0, null));
                pq.add(new Event(Math.max(l.x0, l.x1), null, l.y1));
            } else {
                pq.add(new Event(l.x0, Math.min(l.y0, l.y1), Math.max(l.y0, l.y1)));
            }
        }
        int count = 0;
        SortedSet<Double> bst = new TreeSet<>();
        while(!pq.isEmpty()) {
            count += pq.remove().interSection(bst);
        }
        
        System.out.println(count);
    }
    
    private static final int BORDERSIZE = 512;
    static void myDraw(JPanel jpanel) {
        JFrame frame = new JFrame("Lines");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(jpanel);
        frame.setSize((int)(BORDERSIZE * 2), (int)(BORDERSIZE * 1.5));
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

class LinesDraw extends JPanel {
    private static final long serialVersionUID = 1L;
    private Line[] lines;
    public LinesDraw(Line[] lines) {
        this.lines = lines;
    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.red);
        for (int i = 0; i < lines.length; i++) {
          g2d.draw(new Line2D.Double(lines[i].x0, lines[i].y0, lines[i].x1, lines[i].y1));
        }
      }
}

class Event implements Comparable<Event>{
    private final Double x
    private final Double y0
    private final Double y1
    public Event(Double x, Double y0, Double y1) {
        this.x = x;
        this.y0 = y0;
        this.y1 = y1;
    }

    @Override
    public int compareTo(Event that) {
        return Double.compare(this.x, that.x);
    }
    
    public int interSection(SortedSet<Double> set) {
        if(y1 == null) { //start of horizontal line
            set.add(y0);
            return 0;
        } else if(y0 == null) { //end of horizontal line
            set.remove(y1);
            return 0;
        } else//met a vertical line
            return set.subSet(y0, y1).size();
        }
    }
}

class Line {
    private static final Random r = new Random();
    Double x0, y0, x1, y1;
    public Line(int BORDERSIZE) {
        if(r.nextDouble() > 0.5) {   //vertical line
            x0 = x1 = r.nextDouble() * BORDERSIZE;
            y0 = r.nextDouble() * BORDERSIZE;
            y1 = r.nextDouble() * BORDERSIZE;
        } else {     //horizontal line
            y0 = y1 = r.nextDouble() * BORDERSIZE;
            x0 = r.nextDouble() * BORDERSIZE;
            x1 = r.nextDouble() * BORDERSIZE;
        }
    }

}