This problem of this week is to find the multi-point collinearity mode in a series of points.
Two important parts of Computer Vision: feature dectection and pattern recognition ). Feature Detection extracts important features from images, and pattern recognition discovers patterns in these features. The problem of collocated points also has many applications in real life, such as statistical data analysis.
Problem.Draw a line segment of four or more vertices connected to each (at most) from n different points on a two-dimensional plane.
Point data type.API of the specified point type
public class Point implements Comparable<Point> { public final Comparator<Point> SLOPE_ORDER; // compare points by slope to this point public Point(int x, int y) // construct the point (x, y) public void draw() // draw this point public void drawTo(Point that) // draw the line segment from this point to that point public String toString() // string representation public int compareTo(Point that) // is this point lexicographically smaller than that point? public double slopeTo(Point that) // the slope between this point and that point}
The draw (), drawto (), and tostring () methods have been implemented. compareto (), slopeto (), and slope_order comparator must be implemented.
Compareto (): sort by Y axis. If the vertex (x0, y0) <(x1, Y1), then y0 <Y1, or Y0 = Y1, x0 <x1.
Slopeto: returns the slope of two points. (Y1-y0)/(x1-x0), the slope of the horizontal line segment is positive zero, the slope of the vertical line segment is positive infinity, the slope of the Line Segment degrades into a point is negative infinity
Slope_order comparator: used for slope comparison and sorting. Use a call point (x0, y0) if (x1, Y1) is less than (X2, Y2) When and only when (y1-y0)/(x1-x0) is less than (y2-y0) /(x2-x0 ). The slopeto () is called directly here, and the horizontal, vertical, and degradation situations are also taken into consideration.
Brute force.The brute force method is used to find four points, namely P, Q, R, and s, that are collocated in a straight line. Sort all vertices first, enumerate P, Q, R, S, and determine if p-Q, P-r, and p-s have the same slope. If yes, then we connect a straight line from P to S. The worst time complexity is n ^ 4, and the proportion of space used is N.
int N = points.length;Arrays.sort(points);//BruteForce Implementationfor (int ip = 0; ip < N; ip++) { Point p = points[ip]; for (int iq = ip + 1; iq < N; iq++) { Point q = points[iq]; for (int ir = iq + 1; ir < N; ir++) { Point r = points[ir]; for (int is = ir + 1; is < N; is++) { Point s = points[is]; if (p.slopeTo(q) == p.slopeTo(r) && p.slopeTo(q) == p.slopeTo(s)) { p.drawTo(s); StdOut.println(p.toString() + " -> " + q.toString() + " -> " + r.toString() + " -> " + s.toString()); } } } }}
A faster, sorting-based solution.For a vertex P, all the other vertices are sorted by the slope of the vertex P. If there are three adjacent vertices or more with the same slope, they are collocated.
In this way, the algorithm only needs to enumerate all origin points (Ppoints), then sort the remaining points by the slope of the origin point, and then find out whether there is a collinearity in the sorted points, the complexity is n (enumeration) + nlogn (sorting) + N (traversing search). The required space ratio is N.
Note: Do not output the same-line subline segment and the same-line segment multiple times during statistics. Here, use the location relationship of compareto () to avoid this.
Sample Data FilesThere are many input examples for testing.