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) { |