package pl.wat.ms4ds.terenfunkcje; /** * Klasa algorytmiczna do wyznaczania kwadratów odcinka (dyskretyzacja odcinka kwadratami/pikselami). */ public class Bresenham { static int sign(int a) { if (a > 0) return 1; if (a < 0) return -1; return 0; } /** * Metoda generuje tablicę współrzędnych gridowych kolejnych punktów/kwadratów podanego odcinka. *

* Wykorzystuje algorytm Bresenhama. * * @param x1 współrzędna x początku * @param y1 współrzędna y początku * @param x2 współrzędna x końca * @param y2 współrzędna y końca * @return tablicę kolejnych kwadratów tworzących odcinek o zadanych końcach */ public static GridCoord[] generateSegment(int x1, int y1, int x2, int y2) { int x = x1; int y = y1; int dx = x2 - x1; int dy = y2 - y1; final int sx = sign(dx); final int sy = sign(dy); if (dx < 0) { dx = -dx; } if (dy < 0) { dy = -dy; } final int ddx = 2 * dx; final int ddy = 2 * dy; int p; if (dx >= dy) { // poruszamy się po x p = ddy - dx; GridCoord[] res = new GridCoord[dx + 1]; for (int i = 0; i <= dx; i++) { res[i] = new GridCoord(x, y); if (p > 0) { y += sy; p -= ddx; } x += sx; p += ddy; } return res; } else { // poruszamy sie po y p = ddx - dy; GridCoord[] res = new GridCoord[dy + 1]; for (int i = 0; i <= dy; i++) { res[i] = new GridCoord(x, y); if (p > 0) { x += sx; p -= ddy; } y += sy; p += ddx; } return res; } } static void print(GridCoord[] segment) { StringBuilder sb = new StringBuilder(300); sb.append('['); int last = segment.length - 1; for (int i = 0; i < segment.length; i++) { sb.append('('); sb.append(segment[i].x); sb.append(','); sb.append(segment[i].y); sb.append(')'); if (i < last) { sb.append('|'); } } sb.append(']'); System.out.println(sb); } // public static void main(String[] args) { // // var segment = generateSegmentSquares(10, 3, 1, 6); // var segment2 = generateSegmentSquares(1, 6, 10, 3); // var line = generateSegmentSquares(2, 1, 5, 8); // var line1 = generateSegmentSquares(5, 8, 2, 1); // var line2 = generateSegmentSquares(1, 6, 6, 11); // var line3 = generateSegmentSquares(11, 6, 6, 1); // // final int low = 300; // final int xHigh = 2000; // final int yHigh = 1000; // final int TRIAL_LENGTH = 100; // System.out.println("Start trial 1"); // long t0 = System.nanoTime(); // long sumLen = 0; // for (int i = 0; i < TRIAL_LENGTH; i++) { // int x1 = low + RandomStream.uniformInt(-20, 20); // int y1 = low + RandomStream.uniformInt(-20, 20); // int x2 = low + RandomStream.uniformInt(-20, 20); // int y2 = low + RandomStream.uniformInt(-20, 20); // int dx = Math.abs(x2 - x1); // int dy = Math.abs(y2 - y1); // if (dx == dy) { // continue; // } // var seg1 = generateSegmentSquares(x1, y1, x2, y2); // print(seg1); // } // long dt = System.nanoTime() - t0; // dt /= 1_000_000; // System.out.println("Czas = " + dt + " [ms]"); // sumLen = 0; // System.out.println("Start trial 2"); // t0 = System.nanoTime(); // for (int i = 0; i < TRIAL_LENGTH * 10000; i++) { // int x1 = low + RandomStream.uniformInt(50); // int y1 = low + RandomStream.uniformInt(50); // int x2 = 2 * xHigh + RandomStream.uniformInt(1000); // int y2 = 2 * yHigh + RandomStream.uniformInt(2000); // int dx = Math.abs(x2 - x1); // int dy = Math.abs(y2 - y1); // if (dx == dy) { // continue; // } // // var seg1 = generateSegmentSquares(x1, y1, x2, y2); // // sumLen += seg1.length; // } // dt = System.nanoTime() - t0; // dt /= 1_000_000; // System.out.println("Czas = " + dt + " [ms] - len=" + sumLen); // //// var seg1 = generateSegment(1, 1, 3, 5); //// var seg2 = generateSegment(14, 4, 3, 8); //// System.out.println(seg1); // } }