|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- abstract class Oblig4 {
- // Required for TegnUt
- int x[];
- int y[];
- int n;
- int MAX_X;
- int MAX_Y;
-
- IntList coHull;
- NPunkter17 points;
- String name = "Oblig4";
-
- Oblig4(int[] x, int[] y, int n) {
- this.x = x;
- this.y = y;
- this.n = n;
- coHull = new IntList();
- }
-
- // This method should be overwritten by each implementation.
- // It's responsible for filling in MAX_X, MAX_Y, and coHull
- abstract void solve();
-
- // We don't want to draw on the main thread.
- class DrawThread extends Thread {
- Oblig4 d;
-
- DrawThread(Oblig4 d) {
- this.d = d;
- }
-
- public void run() {
- try {
- TegnUt t = new TegnUt(d, coHull, name);
- t.setVisible(true);
- } catch (Exception ex) {
- System.out.println(name+": Couldn't draw window.");
- }
- }
- }
-
- // Draw points using TegnUt.
- // Requires x, y, n, MAX_X, MAX_Y, and coHull
- // to be filled out.
- Thread draw() {
- if (n > 20000) {
- System.out.println(name+": Too many dots to draw.");
- return null;
- }
-
- System.out.println(name+" coHull: ");
- for (int i = 0; i < coHull.size(); ++i) {
- if (i == 0)
- System.out.print(coHull.get(i));
- else
- System.out.print(", "+coHull.get(i));
- }
- System.out.println("");
-
- DrawThread t = new DrawThread(this);
- t.start();
- return t;
- }
-
- /*
- * The rest is utility methods which any implementation will use.
- */
-
- // 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];
- }
- int lineB(int p1, int p2) {
- return x[p2] - x[p1];
- }
- int lineC(int p1, int p2) {
- return (y[p2] * x[p1]) - (y[p1] * x[p2]);
- }
-
- // From p1 to p2.
- // == 0: p3 is on the line.
- // > 0: p3 is left of the line.
- // < 0: p3 is right of the line.
- double lineEquation(int a, int b, int c, int p3) {
- return (a * x[p3]) + (b * y[p3]) + c;
- }
-
- // Distance between two points
- double pointDist(int p1, int p2) {
- int x1 = x[p1], y1 = y[p1];
- int x2 = x[p2], y2 = y[p2];
-
- int dx = x2 - x1;
- int dy = y2 - y1;
- return Math.abs(Math.sqrt((dx * dx) + (dy * dy)));
- }
-
- // Distance between the line and p3
- 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;
- }
- }
|