Advertisement
qwerty787788

Segment Intersection

Jan 8th, 2013
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.47 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. public class Geometry {
  5.     FastScanner in;
  6.     PrintWriter out;
  7.  
  8.     final static double eps = 1e-9;
  9.  
  10.     class Point {
  11.         double x, y;
  12.  
  13.         public Point(double x, double y) {
  14.             super();
  15.             this.x = x;
  16.             this.y = y;
  17.         }
  18.  
  19.         double dist(Point an) {
  20.             double dx = an.x - x;
  21.             double dy = an.y - y;
  22.             return Math.sqrt(dx * dx + dy * dy);
  23.         }
  24.     }
  25.  
  26.     class Line {
  27.         double A, B, C;
  28.         boolean normed;
  29.  
  30.         Line(Point p1, Point p2) {
  31.             A = p2.y - p1.y;
  32.             B = p1.x - p2.x;
  33.             C = -A * p1.x - B * p1.y;
  34.         }
  35.  
  36.         void norm() {
  37.             double z = Math.sqrt(A * A + B * B);
  38.             A /= z;
  39.             B /= z;
  40.             C /= z;
  41.             normed = true;
  42.         }
  43.  
  44.         double dist(Point p) {
  45.             if (!normed)
  46.                 norm();
  47.             return Math.abs(A * p.x + B * p.y + C);
  48.         }
  49.  
  50.         Point intersec(Line another) {
  51.             double zn = A * another.B - another.A * B;
  52.             if (Math.abs(zn) <= eps)
  53.                 return null;
  54.             double x = another.C * B - another.B * C;
  55.             double y = another.A * C - another.C * A;
  56.             return new Point(x / zn, y / zn);
  57.         }
  58.     }
  59.  
  60.     boolean insideSorted(double x, double xLeft, double xRight) {
  61.         return x >= xLeft - eps && x <= xRight + eps;
  62.     }
  63.  
  64.     boolean inside(double x, double xLeft, double xRight) {
  65.         return insideSorted(x, Math.min(xLeft, xRight), Math.max(xLeft, xRight));
  66.     }
  67.  
  68.     class Segment {
  69.         Point p1, p2;
  70.         Line l;
  71.  
  72.         public Segment(Point p1, Point p2) {
  73.             this.p1 = p1;
  74.             this.p2 = p2;
  75.             l = new Line(p1, p2);
  76.         }
  77.  
  78.         boolean onSegment(Point p) {
  79.             if (l.dist(p) > eps)
  80.                 return false;
  81.             return inside(p.x, p1.x, p2.x) && inside(p.y, p1.y, p2.y);
  82.         }
  83.  
  84.         boolean isPoint() {
  85.             return p1.dist(p2) <= eps;
  86.         }
  87.     }
  88.  
  89.     class IntersectionObject {
  90.         boolean isPoint;
  91.         Point point;
  92.         Segment segment;
  93.  
  94.         IntersectionObject(Point point) {
  95.             isPoint = true;
  96.             this.point = point;
  97.         }
  98.  
  99.         IntersectionObject(Segment segment) {
  100.             isPoint = false;
  101.             this.segment = segment;
  102.         }
  103.     }
  104.  
  105.     boolean intersectSorted(double xLeft, double xRight, double yLeft,
  106.             double yRight) {
  107.         return Math.max(xLeft, yLeft) - eps <= Math.min(xRight, yRight);
  108.     }
  109.  
  110.     boolean intersect(double xLeft, double xRight, double yLeft, double yRight) {
  111.         return intersectSorted(Math.min(xLeft, xRight),
  112.                 Math.max(xLeft, xRight), Math.min(yLeft, yRight),
  113.                 Math.max(yLeft, yRight));
  114.     }
  115.  
  116.     IntersectionObject intersect(Segment s1, Segment s2) {
  117.         if (!intersect(s1.p1.x, s1.p2.x, s2.p1.x, s2.p2.x)
  118.                 || !intersect(s1.p1.y, s1.p2.y, s2.p1.y, s2.p2.y))
  119.             return null;
  120.         boolean isPoint1 = s1.isPoint();
  121.         boolean isPoint2 = s2.isPoint();
  122.         if (isPoint1 && isPoint2)
  123.             return new IntersectionObject(s1.p1);
  124.         if (isPoint1) {
  125.             if (s2.onSegment(s1.p1))
  126.                 return new IntersectionObject(s1.p1);
  127.             return null;
  128.         }
  129.         if (isPoint2) {
  130.             if (s1.onSegment(s2.p1))
  131.                 return new IntersectionObject(s2.p1);
  132.             return null;
  133.         }
  134.         Point intersecton = s1.l.intersec(s2.l);
  135.         if (intersecton == null) {
  136.             if (Math.abs(s1.l.dist(s2.p1)) > eps
  137.                     || Math.abs(s2.l.dist(s1.p1)) > eps)
  138.                 return null;
  139.             double xLeft1 = Math.min(s1.p1.x, s1.p2.x);
  140.             double xLeft2 = Math.min(s2.p1.x, s2.p2.x);
  141.             double xRight1 = Math.max(s1.p1.x, s1.p2.x);
  142.             double xRight2 = Math.max(s2.p1.x, s2.p2.x);
  143.             double yLeft1 = Math.min(s1.p1.y, s1.p2.y);
  144.             double yLeft2 = Math.min(s2.p1.y, s2.p2.y);
  145.             double yRight1 = Math.max(s1.p1.y, s1.p2.y);
  146.             double yRight2 = Math.max(s2.p1.y, s2.p2.y);
  147.             Point p1 = new Point(Math.max(xLeft1, xLeft2), Math.max(yLeft1,
  148.                     yLeft2));
  149.             Point p2 = new Point(Math.min(xRight1, xRight2), Math.min(yRight1,
  150.                     yRight2));
  151.             if (s1.l.dist(p1) > eps || s1.l.dist(p2) > eps) {
  152.                 p1 = new Point(Math.max(xLeft1, xLeft2), Math.min(yRight1,
  153.                         yRight2));
  154.                 p2 = new Point(Math.min(xRight1, xRight2), Math.max(yLeft1,
  155.                         yLeft2));
  156.             }
  157.             if (p1.dist(p2) <= eps)
  158.                 return new IntersectionObject(p1);
  159.             Segment newSeg = new Segment(p1, p2);
  160.             return new IntersectionObject(newSeg);
  161.         } else {
  162.             if (!s1.onSegment(intersecton) || !s2.onSegment(intersecton))
  163.                 return null;
  164.             return new IntersectionObject(intersecton);
  165.         }
  166.     }
  167.  
  168.     void solve() {
  169.         Point p1 = new Point(in.nextDouble(), in.nextDouble());
  170.         Point p2 = new Point(in.nextDouble(), in.nextDouble());
  171.         Point p3 = new Point(in.nextDouble(), in.nextDouble());
  172.         Point p4 = new Point(in.nextDouble(), in.nextDouble());
  173.         Segment s1 = new Segment(p1, p2);
  174.         Segment s2 = new Segment(p3, p4);
  175.         IntersectionObject inter = intersect(s1, s2);
  176.         if (inter == null) {
  177.             out.println("Empty");
  178.             return;
  179.         }
  180.         if (inter.isPoint) {
  181.             out.println(inter.point.x + " " + inter.point.y);
  182.             return;
  183.         }
  184.         Point pAns1 = inter.segment.p1;
  185.         Point pAns2 = inter.segment.p2;
  186.         if (pAns2.x < pAns1.x
  187.                 || (Math.abs(pAns1.x - pAns2.x) <= eps && pAns2.y < pAns1.y)) {
  188.             Point tmp = pAns1;
  189.             pAns1 = pAns2;
  190.             pAns2 = tmp;
  191.         }
  192.         out.println(pAns1.x + " " + pAns1.y);
  193.         out.println(pAns2.x + " " + pAns2.y);
  194.     }
  195.  
  196.     void run() {
  197.         try {
  198.             in = new FastScanner(new File("intersection.in"));
  199.             out = new PrintWriter(new File("intersection.out"));
  200.  
  201.             solve();
  202.  
  203.             out.close();
  204.         } catch (FileNotFoundException e) {
  205.             e.printStackTrace();
  206.         }
  207.     }
  208.  
  209.     void runIO() {
  210.  
  211.         in = new FastScanner(System.in);
  212.         out = new PrintWriter(System.out);
  213.  
  214.         solve();
  215.  
  216.         out.close();
  217.     }
  218.  
  219.     class FastScanner {
  220.         BufferedReader br;
  221.         StringTokenizer st;
  222.  
  223.         public FastScanner(File f) {
  224.             try {
  225.                 br = new BufferedReader(new FileReader(f));
  226.             } catch (FileNotFoundException e) {
  227.                 e.printStackTrace();
  228.             }
  229.         }
  230.  
  231.         public FastScanner(InputStream f) {
  232.             br = new BufferedReader(new InputStreamReader(f));
  233.         }
  234.  
  235.         String next() {
  236.             while (st == null || !st.hasMoreTokens()) {
  237.                 String s = null;
  238.                 try {
  239.                     s = br.readLine();
  240.                 } catch (IOException e) {
  241.                     e.printStackTrace();
  242.                 }
  243.                 if (s == null)
  244.                     return null;
  245.                 st = new StringTokenizer(s);
  246.             }
  247.             return st.nextToken();
  248.         }
  249.  
  250.         boolean hasMoreTokens() {
  251.             while (st == null || !st.hasMoreTokens()) {
  252.                 String s = null;
  253.                 try {
  254.                     s = br.readLine();
  255.                 } catch (IOException e) {
  256.                     e.printStackTrace();
  257.                 }
  258.                 if (s == null)
  259.                     return false;
  260.                 st = new StringTokenizer(s);
  261.             }
  262.             return true;
  263.         }
  264.  
  265.         int nextInt() {
  266.             return Integer.parseInt(next());
  267.         }
  268.  
  269.         long nextLong() {
  270.             return Long.parseLong(next());
  271.         }
  272.  
  273.         double nextDouble() {
  274.             return Double.parseDouble(next());
  275.         }
  276.     }
  277.  
  278.     public static void main(String[] args) {
  279.         new Geometry().runIO();
  280.     }
  281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement