| int x[]; | int x[]; | ||||
| int y[]; | int y[]; | ||||
| int n; | int n; | ||||
| int MAX_Y; | |||||
| int MAX_X; | int MAX_X; | ||||
| int MAX_Y; | |||||
| int minX; | |||||
| int maxX; | |||||
| int minY; | |||||
| int maxY; | |||||
| IntList coHull; | IntList coHull; | ||||
| NPunkter17 points; | NPunkter17 points; | ||||
| String name = "Oblig4"; | String name = "Oblig4"; | ||||
| points.fyllArrayer(x, y); | points.fyllArrayer(x, y); | ||||
| } | } | ||||
| // This method should be overwritten by each implementation. | |||||
| // It's responsible for filling in MAX_X, MAX_Y, and coHull | |||||
| abstract void solve(); | abstract void solve(); | ||||
| /* | |||||
| * The rest is utility methods which any implementation will use. | |||||
| */ | |||||
| // Draw points using TegnUt. | |||||
| // Requires x, y, n, MAX_X, MAX_Y, and coHull | |||||
| // to be filled out. | |||||
| void draw() { | void draw() { | ||||
| TegnUt t = new TegnUt(this, coHull, name); | TegnUt t = new TegnUt(this, coHull, name); | ||||
| t.setVisible(true); | t.setVisible(true); | ||||
| } | } | ||||
| // a, b, and c will be used in the line equation. | |||||
| // It doesn't make sense to recalculate them all the time, | |||||
| // as they only depend on p1 and p2. | |||||
| int lineA(int p1, int p2) { | int lineA(int p1, int p2) { | ||||
| return y[p1] - y[p2]; | return y[p1] - y[p2]; | ||||
| } | } | ||||
| double dist(double l, int a, int b) { | double dist(double l, int a, int b) { | ||||
| return l / Math.sqrt((a * a) + (b * b)); | return l / Math.sqrt((a * a) + (b * b)); | ||||
| } | } | ||||
| // Create a list of points, in sorted order, on the line | |||||
| // given by (a, b, c, p1) | |||||
| IntList addPointsOnLine(IntList indexes, int a, int b, int c, int p1) { | |||||
| IntList l = new IntList(); | |||||
| // Add points on the line between p1 and p2 | |||||
| for (int i = 0; i < indexes.size(); ++i) { | |||||
| int idx = indexes.get(i); | |||||
| double line = lineEquation(a, b, c, idx); | |||||
| if (line == 0) | |||||
| l.add(idx); | |||||
| } | |||||
| // Calculate distances for sorting | |||||
| double[] dists = new double[l.size()]; | |||||
| for (int i = 0; i < l.size(); ++i) { | |||||
| dists[i] = pointDist(p1, l.get(i)); | |||||
| } | |||||
| // Sort points based on distance from p1 | |||||
| // (Bubble sort, but it's usually really few elements) | |||||
| boolean sorted; | |||||
| do { | |||||
| sorted = true; | |||||
| // Loop through points, swap non-sorted ones | |||||
| for (int i = 1; i < l.size(); ++i) { | |||||
| double dist = dists[i]; | |||||
| double prevDist = dists[i - 1]; | |||||
| // Skip if already sorted | |||||
| if (prevDist <= dist) | |||||
| continue; | |||||
| sorted = false; | |||||
| // Swap indexes | |||||
| int tmpi = l.data[i]; | |||||
| l.data[i] = l.data[i - 1]; | |||||
| l.data[i - 1] = tmpi; | |||||
| // Swap distances | |||||
| double tmpd = dists[i]; | |||||
| dists[i] = dists[i - 1]; | |||||
| dists[i - 1] = tmpd; | |||||
| } | |||||
| } while (!sorted); | |||||
| return l; | |||||
| } | |||||
| } | } |
| class Sequential extends Oblig4 { | class Sequential extends Oblig4 { | ||||
| Sequential(NPunkter17 points) { | Sequential(NPunkter17 points) { | ||||
| super(points); | super(points); | ||||
| name = "Sequential"; | name = "Sequential"; | ||||
| @Override | @Override | ||||
| void solve() { | void solve() { | ||||
| findMinMaxXY(); | |||||
| MAX_X = x[maxX]; | |||||
| MAX_Y = y[maxY]; | |||||
| MinMaxXY minmax = findMinMax(); | |||||
| MAX_X = x[minmax.maxX]; | |||||
| MAX_Y = y[minmax.maxY]; | |||||
| IntList indexes = new IntList(n); | IntList indexes = new IntList(n); | ||||
| for (int i = 0; i < n; ++i) | for (int i = 0; i < n; ++i) | ||||
| indexes.add(i); | indexes.add(i); | ||||
| coHull = pointsRightOf(maxX, minX, indexes); | |||||
| coHull.append(pointsRightOf(minX, maxX, indexes)); | |||||
| coHull = pointsRightOf(minmax.maxX, minmax.minX, indexes); | |||||
| coHull.append(pointsRightOf(minmax.minX, minmax.maxX, indexes)); | |||||
| for (int i = 0; i < coHull.size(); ++i) { | for (int i = 0; i < coHull.size(); ++i) { | ||||
| System.out.print(coHull.get(i)+" "); | System.out.print(coHull.get(i)+" "); | ||||
| System.out.println(""); | System.out.println(""); | ||||
| } | } | ||||
| void findMinMaxXY() { | |||||
| minX = 0; | |||||
| maxX = 0; | |||||
| minY = 0; | |||||
| maxY = 0; | |||||
| class MinMaxXY { | |||||
| int minX, maxX, maxY; | |||||
| } | |||||
| MinMaxXY findMinMax() { | |||||
| int minX = 0; | |||||
| int maxX = 0; | |||||
| int maxY = 0; | |||||
| for (int i = 1; i < n; ++i) { | for (int i = 1; i < n; ++i) { | ||||
| int px = x[i]; | int px = x[i]; | ||||
| maxX = i; | maxX = i; | ||||
| int py = y[i]; | int py = y[i]; | ||||
| if (py < y[minY]) | |||||
| minY = i; | |||||
| if (py > y[maxY]) | if (py > y[maxY]) | ||||
| maxY = i; | maxY = i; | ||||
| } | } | ||||
| } | |||||
| IntList addPointsOnLine(IntList indexes, int a, int b, int c, int p1) { | |||||
| IntList l = new IntList(); | |||||
| // Add points on the line between p1 and p2 | |||||
| for (int i = 0; i < indexes.size(); ++i) { | |||||
| int idx = indexes.get(i); | |||||
| double line = lineEquation(a, b, c, idx); | |||||
| if (line == 0) | |||||
| l.add(idx); | |||||
| } | |||||
| // Calculate distances for sorting | |||||
| double[] dists = new double[l.size()]; | |||||
| for (int i = 0; i < l.size(); ++i) { | |||||
| dists[i] = pointDist(p1, l.get(i)); | |||||
| } | |||||
| // Sort points based on distance from p1 | |||||
| // (Bubble sort, but it's usually really few elements) | |||||
| boolean sorted; | |||||
| do { | |||||
| sorted = true; | |||||
| // Loop through points, swap non-sorted ones | |||||
| for (int i = 1; i < l.size(); ++i) { | |||||
| double dist = dists[i]; | |||||
| double prevDist = dists[i - 1]; | |||||
| // Skip if already sorted | |||||
| if (prevDist <= dist) | |||||
| continue; | |||||
| sorted = false; | |||||
| // Swap indexes | |||||
| int tmpi = l.data[i]; | |||||
| l.data[i] = l.data[i - 1]; | |||||
| l.data[i - 1] = tmpi; | |||||
| // Swap distances | |||||
| double tmpd = dists[i]; | |||||
| dists[i] = dists[i - 1]; | |||||
| dists[i - 1] = tmpd; | |||||
| } | |||||
| } while (!sorted); | |||||
| return l; | |||||
| MinMaxXY minmax = new MinMaxXY(); | |||||
| minmax.minX = minX; | |||||
| minmax.maxX = maxX; | |||||
| minmax.maxY = maxY; | |||||
| return minmax; | |||||
| } | } | ||||
| IntList pointsRightOf(int p1, int p2, IntList indexes) { | IntList pointsRightOf(int p1, int p2, IntList indexes) { |