| @@ -3,13 +3,9 @@ abstract class Oblig4 { | |||
| int x[]; | |||
| int y[]; | |||
| int n; | |||
| int MAX_Y; | |||
| int MAX_X; | |||
| int MAX_Y; | |||
| int minX; | |||
| int maxX; | |||
| int minY; | |||
| int maxY; | |||
| IntList coHull; | |||
| NPunkter17 points; | |||
| String name = "Oblig4"; | |||
| @@ -23,13 +19,25 @@ abstract class Oblig4 { | |||
| 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(); | |||
| /* | |||
| * 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() { | |||
| TegnUt t = new TegnUt(this, coHull, name); | |||
| 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) { | |||
| return y[p1] - y[p2]; | |||
| } | |||
| @@ -62,4 +70,56 @@ abstract class Oblig4 { | |||
| double dist(double l, int a, int 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; | |||
| } | |||
| } | |||
| @@ -1,4 +1,5 @@ | |||
| class Sequential extends Oblig4 { | |||
| Sequential(NPunkter17 points) { | |||
| super(points); | |||
| name = "Sequential"; | |||
| @@ -6,16 +7,16 @@ class Sequential extends Oblig4 { | |||
| @Override | |||
| 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); | |||
| for (int i = 0; i < n; ++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) { | |||
| System.out.print(coHull.get(i)+" "); | |||
| @@ -23,11 +24,15 @@ class Sequential extends Oblig4 { | |||
| 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) { | |||
| int px = x[i]; | |||
| @@ -37,61 +42,15 @@ class Sequential extends Oblig4 { | |||
| maxX = i; | |||
| int py = y[i]; | |||
| if (py < y[minY]) | |||
| minY = i; | |||
| if (py > y[maxY]) | |||
| 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) { | |||