1579 lines
60 KiB
Java
1579 lines
60 KiB
Java
package pl.wat.ms4ds.terrain;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import pl.wat.ms4ds.common.EGeoDirection;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
public class GeomUtils {
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(GeomUtils.class);
|
|
|
|
/**
|
|
* <p> Wyznacznik macierzy (kwadratowej stopnia 3)
|
|
* [[p.x, p.y, 1],
|
|
* [q.x, q.y, 1]
|
|
* [r.x, r.y, 1]]
|
|
* </p>
|
|
* Pozwala na określenie położenie punktu względem wektora.
|
|
*
|
|
* @param p Wsp poczatku wektora
|
|
* @param q Wsp konca wektora
|
|
* @param r Wsp testowanego punktu
|
|
* @return det3 == 0, gdy punkt jest wpolliniowy, det3 wieksze od 0, gdy punkt lezy po lewej stronie wektora,
|
|
* det3 mniejsze od 0, gdy punkt lezy po prawej stronie wektora,
|
|
*/
|
|
public static long det3(Coord.Grid p, Coord.Grid q, Coord.Grid r) {
|
|
return p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y);
|
|
}
|
|
|
|
/**
|
|
* <p> Wyznacznik macierzy (kwadratowej stopnia 3)
|
|
* [[p.x, p.y, 1],
|
|
* [q.x, q.y, 1]
|
|
* [r.x, r.y, 1]]
|
|
* </p>
|
|
* Pozwala na określenie położenie punktu względem wektora.
|
|
*
|
|
* @param px Wsp x poczatku wektora
|
|
* @param py Wsp y poczatku wektora
|
|
* @param qx Wsp x końca wektora
|
|
* @param qy Wsp y końca wektora
|
|
* @param rx Wsp x testowanego punktu
|
|
* @param ry Wsp y testowanego punktu
|
|
* @return det3 == 0, gdy punkt jest wspolliniowy, det3 wieksze od 0, gdy punkt lezy po lewej stronie wektora,
|
|
* det3 mniejsze od 0, gdy punkt lezy po prawej stronie wektora,
|
|
*/
|
|
public static long det3(int px, int py, int qx, int qy, int rx, int ry) {
|
|
return px * (qy - ry) + qx * (ry - py) + rx * (py - qy);
|
|
}
|
|
|
|
/**
|
|
* Sprawdza, czy punkt r należy do odcinka p-q
|
|
*
|
|
* @param p Poczatek odcinka
|
|
* @param q Koniec odcinka
|
|
* @param r Punkt testowany
|
|
* @return true, jesli punkt r lezy na odcinku
|
|
*/
|
|
public static boolean include(Coord.Grid p, Coord.Grid q, Coord.Grid r) {
|
|
return det3(p, q, r) == 0 &&
|
|
Math.min(p.x, q.x) <= r.x &&
|
|
r.x <= Math.max(p.x, q.x) &&
|
|
Math.min(p.y, q.y) <= r.y &&
|
|
r.y <= Math.max(p.y, q.y);
|
|
}
|
|
|
|
/**
|
|
* Sprawdza, czy punkt r należy do odcinka p-q
|
|
*
|
|
* @param px Wsp x poczatku wektora
|
|
* @param py Wsp y poczatku wektora
|
|
* @param qx Wsp x końca wektora
|
|
* @param qy Wsp y końca wektora
|
|
* @param rx Wsp x testowanego punktu
|
|
* @param ry Wsp y testowanego punktu
|
|
* @return true, jesli punkt r lezy na odcinku
|
|
*/
|
|
public static boolean include(int px, int py, int qx, int qy, int rx, int ry) {
|
|
return det3(px, py, qx, qy, rx, ry) == 0 &&
|
|
Math.min(px, qx) <= rx &&
|
|
rx <= Math.max(px, qx) &&
|
|
Math.min(py, qy) <= ry &&
|
|
ry <= Math.max(py, qy);
|
|
}
|
|
|
|
/**
|
|
* Sprawdza, czy punkt r należy do poziomego odcinka p-q
|
|
*
|
|
* @param p Poczatek odcinka
|
|
* @param q Koniec odcinka
|
|
* @param r Punkt testowany
|
|
* @return true, jeśli punkt r należy do odcinka p-q
|
|
*/
|
|
public static boolean includeHorizontaly(Coord.Grid p, Coord.Grid q, Coord.Grid r) {
|
|
return p.y == r.y &&
|
|
Math.min(p.x, q.x) <= r.x &&
|
|
r.x <= Math.max(p.x, q.x);
|
|
|
|
// return det3(p, q, r) == 0 &&
|
|
// Math.min(p.x, q.x) <= r.x &&
|
|
// r.x <= Math.max(p.x, q.x) &&
|
|
// Math.min(p.y, q.y) <= r.y &&
|
|
// r.y <= Math.max(p.y, q.y);
|
|
}
|
|
|
|
/**
|
|
* Sprawdza, czy punkt r należy do poziomego odcinka p-q
|
|
*
|
|
* @param px Wsp x poczatku wektora
|
|
* @param py Wsp y poczatku wektora
|
|
* @param qx Wsp x końca wektora
|
|
* @param qy Wsp y końca wektora
|
|
* @param rx Wsp x testowanego punktu
|
|
* @param ry Wsp y testowanego punktu
|
|
* @return true, jeśli punkt r należy do odcinka p-q
|
|
*/
|
|
public static boolean includeHorizontaly(int px, int py, int qx, int qy, int rx, int ry) {
|
|
return py == ry &&
|
|
Math.min(px, qx) <= rx &&
|
|
rx <= Math.max(px, qx);
|
|
}
|
|
|
|
/**
|
|
* Określenie znaku liczby
|
|
*
|
|
* @param x Testowana liczba
|
|
* @return 0, gdy x == 0, 1 gdy x wieksze od 0, -1 gdy x mniejsze od 0
|
|
*/
|
|
public static int sgn(long x) {
|
|
if (x == 0) {
|
|
return 0;
|
|
}
|
|
if (x > 0) {
|
|
return 1;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Sprawdza, czy odcinki p-q i r-s przecinają się wewnetrznie tzn.
|
|
* mają dokładnie jeden punkt wspólny różny od każdego z konców odcinków.
|
|
*
|
|
* @param p punkt początkowy pierwszego odcinka
|
|
* @param q punkt końcowy pierwszego odcinka
|
|
* @param r punkt początkowy drugiego odcinka
|
|
* @param s punkt końcowy drugiego odcinka
|
|
* @return true, jeśli odcinki przecinają się wewnętrznie
|
|
*/
|
|
public static boolean cross(Coord.Grid p, Coord.Grid q, Coord.Grid r, Coord.Grid s) {
|
|
long det3_pqr = det3(p, q, r);
|
|
long det3_pqs = det3(p, q, s);
|
|
long det3_rsp = det3(r, s, p);
|
|
long det3_rsq = det3(r, s, q);
|
|
|
|
return sgn(det3_pqr) != sgn(det3_pqs) &&
|
|
sgn(det3_rsp) != sgn(det3_rsq) &&
|
|
det3_pqr != 0 &&
|
|
det3_pqs != 0 &&
|
|
det3_rsp != 0 &&
|
|
det3_rsq != 0;
|
|
// return sgn(det3(p, q, r)) != sgn(det3(p, q, s)) &&
|
|
// sgn(det3(r, s, p)) != sgn(det3(r, s, q)) &&
|
|
// !include(p, q, r) &&
|
|
// !include(p, q, s) &&
|
|
// !include(r, s, p) &&
|
|
// !include(r, s, q);
|
|
}
|
|
|
|
/**
|
|
* Sprawdza, czy odcinki p-q i r-s przecinają się wewnetrznie tzn.
|
|
* mają dokładnie jeden punkt wspólny różny od każdego z konców odcinków.
|
|
*
|
|
* @param px wsp x punktu początkowego pierwszego odcinka
|
|
* @param py wsp y punktu początkowego pierwszego odcinka
|
|
* @param qx wsp x punktu końcowego pierwszego odcinka
|
|
* @param qy wsp y punktu końcowego pierwszego odcinka
|
|
* @param rx wsp x punktu początkowego drugiego odcinka
|
|
* @param ry wsp y punktu początkowego drugiego odcinka
|
|
* @param sx wsp x punktu końcowego drugiego odcinka
|
|
* @param sy wsp y punktu końcowego drugiego odcinka
|
|
* @return true, jeśli odcinki przecinają się wewnętrznie
|
|
*/
|
|
public static boolean cross(int px, int py, int qx, int qy, int rx, int ry, int sx, int sy) {
|
|
long det3_pqr = det3(px, py, qx, qy, rx, ry);
|
|
long det3_pqs = det3(px, py, qx, qy, sx, sy);
|
|
long det3_rsp = det3(rx, ry, sx, sy, px, py);
|
|
long det3_rsq = det3(rx, ry, sx, sy, qx, qy);
|
|
|
|
return sgn(det3_pqr) != sgn(det3_pqs) &&
|
|
sgn(det3_rsp) != sgn(det3_rsq) &&
|
|
det3_pqr != 0 &&
|
|
det3_pqs != 0 &&
|
|
det3_rsp != 0 &&
|
|
det3_rsq != 0;
|
|
// return sgn(det3(p, q, r)) != sgn(det3(p, q, s)) &&
|
|
// sgn(det3(r, s, p)) != sgn(det3(r, s, q)) &&
|
|
// !include(p, q, r) &&
|
|
// !include(p, q, s) &&
|
|
// !include(r, s, p) &&
|
|
// !include(r, s, q);
|
|
}
|
|
|
|
/**
|
|
* Sprawdza, czy odcinki p-q i r-s mają dowolną część wspólną.
|
|
*
|
|
* @param p punkt początkowy pierwszego odcinka
|
|
* @param q punkt końcowy pierwszego odcinka
|
|
* @param r punkt początkowy drugiego odcinka
|
|
* @param s punkt końcowy drugiego odcinka
|
|
* @return true, jeśli odcinki mają część wspólną
|
|
*/
|
|
public static boolean intersection(Coord.Grid p, Coord.Grid q, Coord.Grid r, Coord.Grid s) {
|
|
long det3_pqr = det3(p, q, r);
|
|
long det3_pqs = det3(p, q, s);
|
|
long det3_rsp = det3(r, s, p);
|
|
long det3_rsq = det3(r, s, q);
|
|
return (sgn(det3_pqr) != sgn(det3_pqs) && sgn(det3_rsp) != sgn(det3_rsq)) ||
|
|
(det3_pqr == 0 && det3_pqs == 0 &&
|
|
((Math.min(p.x, q.x) <= r.x &&
|
|
r.x <= Math.max(p.x, q.x) &&
|
|
Math.min(p.y, q.y) <= r.y &&
|
|
r.y <= Math.max(p.y, q.y)) ||
|
|
(Math.min(p.x, q.x) <= s.x &&
|
|
s.x <= Math.max(p.x, q.x) &&
|
|
Math.min(p.y, q.y) <= s.y &&
|
|
s.y <= Math.max(p.y, q.y))));
|
|
}
|
|
|
|
/**
|
|
* Sprawdza, czy punkt należy do wielokata w ogólnym przypadku (boki wielokata bez samoprzecięć).
|
|
*
|
|
* @param polygon Kolejne wierzchołki wielokata.
|
|
* @param p Testowany punkt.
|
|
* @return true, jeśli testowany punkt leży wewnątrz wielokąta
|
|
*/
|
|
public static boolean insidePolygon(Coord.Grid[] polygon, Coord.Grid p) {
|
|
// sprawdzenie czy punkt p należy do jednego z boków wielokąta
|
|
for (int i = 0; i < polygon.length; i++) {
|
|
int i_plus_1 = (i + 1) % polygon.length;
|
|
if (include(polygon[i], polygon[i_plus_1], p)) {
|
|
return true;
|
|
}
|
|
}
|
|
// punkty p i p1 wyznaczają półprostą równoległą do osi OX
|
|
// współrzędna X punktu p1 musi być większa od największej
|
|
// współrzędnej X wśród wszystkich wierzchołków wielokąta
|
|
Coord.Grid p1 = new Coord.Grid(p.x + 1, p.y);
|
|
for (int i = 0; i < polygon.length; i++) {
|
|
p1.x = Math.max(polygon[i].x, p1.x);
|
|
}
|
|
p1.x++;
|
|
// licznik przecięć
|
|
int cross_count = 0;
|
|
// przechodzenie po wszystkich bokach
|
|
int i = 0;
|
|
while (i < polygon.length) {
|
|
int i_plus_1 = (i + 1) % polygon.length;
|
|
int i_plus_2 = (i + 2) % polygon.length;
|
|
int i_minus_1 = (i + polygon.length - 1) % polygon.length;
|
|
int sgn_det3_i_minus_1 = sgn(det3(p, p1, polygon[i_minus_1]));
|
|
int sgn_det3_i_plus_1 = sgn(det3(p, p1, polygon[i_plus_1]));
|
|
int sgn_det3_i_plus_2 = sgn(det3(p, p1, polygon[i_plus_2]));
|
|
if (includeHorizontaly(p, p1, polygon[i])) {
|
|
// polprosta p-p1 zawiera wierzchołek w(i)
|
|
if (includeHorizontaly(p, p1, polygon[i_plus_1])) {
|
|
// polprosta p-p1 zawiera bok w(i)w(i+1)
|
|
if (sgn_det3_i_minus_1 != sgn_det3_i_plus_2) {
|
|
// punkt wczesniejszy w(i-1) i dalszy w(i+2) testowanego boku wielokata
|
|
// leza po przeciwnych stronach polprostej p-p1, zatem ilosc przeciec +1
|
|
cross_count++;
|
|
}
|
|
// pomijamy nastepny wierzcholek
|
|
i++;
|
|
} else {
|
|
// polprosta p-p1 zawiera TYLKO wierzchołek w(i)
|
|
if (sgn_det3_i_minus_1 != 0 && sgn_det3_i_minus_1 != sgn_det3_i_plus_1) {
|
|
// wierzcholki sasiadujace z wierzchołkiem w(i) tj. w(i-1) i w(i+1)
|
|
// leza po przeciwnych stronach polprostej p-p1, zatem ilosc przeciec +1
|
|
cross_count++;
|
|
}
|
|
}
|
|
} else {
|
|
// sprawdzenie czy polprosta p-p1
|
|
// przecina bok w(i)w(i+1) wielokąta wewnatrz odcinka
|
|
if (cross(p, p1, polygon[i], polygon[i_plus_1])) {
|
|
cross_count++;
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
// obliczenie wyniku (nieparzysty oznacza należenie punktu do wielokata)
|
|
return (cross_count % 2) == 1;
|
|
}
|
|
|
|
/**
|
|
* Sprawdza, czy punkt należy do wielokata w ogólnym przypadku (boki wielokata bez samoprzecięć).
|
|
*
|
|
* @param polygon Kolejne wierzchołki wielokata.
|
|
* @param px Wsp. x testowanego punktu.
|
|
* @param py Wsp. y testowanego punktu.
|
|
* @return true, jeśli testowany punkt leży wewnątrz wielokąta
|
|
*/
|
|
public static boolean insidePolygon(Coord.Grid[] polygon, int px, int py) {
|
|
// sprawdzenie czy punkt p nie należy do jednego z boków wielokąta
|
|
for (int i = 0; i < polygon.length; i++) {
|
|
int i_plus_1 = (i + 1) % polygon.length;
|
|
if (include(polygon[i].x, polygon[i].y, polygon[i_plus_1].x, polygon[i_plus_1].y, px, py)) {
|
|
return true;
|
|
}
|
|
}
|
|
// punkty p i p1 wyznaczają półprostą równoległą do osi OX
|
|
// współrzędna X punktu p1 musi być większa od największej
|
|
// współrzędnej X wśród wszystkich wierzchołków wielokąta
|
|
Coord.Grid p1 = new Coord.Grid(px + 1, py);
|
|
for (int i = 0; i < polygon.length; i++) {
|
|
p1.x = Math.max(polygon[i].x, p1.x);
|
|
}
|
|
p1.x++;
|
|
// licznik przecięć
|
|
int cross_count = 0;
|
|
// przechodzenie po wszystkich bokach
|
|
int i = 0;
|
|
while (i < polygon.length) {
|
|
int i_plus_1 = (i + 1) % polygon.length;
|
|
int i_plus_2 = (i + 2) % polygon.length;
|
|
int i_minus_1 = (i + polygon.length - 1) % polygon.length;
|
|
int sgn_det3_i_minus_1 = sgn(det3(px, py, p1.x, p1.y, polygon[i_minus_1].x, polygon[i_minus_1].y));
|
|
if (includeHorizontaly(px, py, p1.x, p1.y, polygon[i].x, polygon[i].y)) {
|
|
// polprosta p-p1 zawiera wierzchołek w(i)
|
|
if (includeHorizontaly(px, py, p1.x, p1.y, polygon[i_plus_1].x, polygon[i_plus_1].y)) {
|
|
int sgn_det3_i_plus_2 = sgn(det3(px, py, p1.x, p1.y, polygon[i_plus_2].x, polygon[i_plus_2].y));
|
|
// polprosta p-p1 zawiera bok w(i)w(i+1)
|
|
if (sgn_det3_i_minus_1 != sgn_det3_i_plus_2) {
|
|
// punkt wczesniejszy w(i-1) i dalszy w(i+2) testowanego boku wielokata
|
|
// leza po przeciwnych stronach polprostej p-p1, zatem ilosc przeciec +1
|
|
cross_count++;
|
|
}
|
|
// pomijamy nastepny wierzcholek
|
|
i++;
|
|
} else {
|
|
int sgn_det3_i_plus_1 = sgn(det3(px, py, p1.x, p1.y, polygon[i_plus_1].x, polygon[i_plus_1].y));
|
|
// polprosta p-p1 zawiera TYLKO wierzchołek w(i)
|
|
if (sgn_det3_i_minus_1 != 0 && sgn_det3_i_minus_1 != sgn_det3_i_plus_1) {
|
|
// wierzcholki sasiadujace z wierzchołkiem w(i) tj. w(i-1) i w(i+1)
|
|
// leza po przeciwnych stronach polprostej p-p1, zatem ilosc przeciec +1
|
|
cross_count++;
|
|
}
|
|
}
|
|
} else {
|
|
// sprawdzenie czy polprosta p-p1
|
|
// przecina bok w(i)w(i+1) wielokąta wewnatrz odcinka
|
|
if (cross(px, py, p1.x, p1.y, polygon[i].x, polygon[i].y, polygon[i_plus_1].x, polygon[i_plus_1].y)) {
|
|
cross_count++;
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
// obliczenie wyniku (nieparzysty oznacza należenie punktu do wielokata)
|
|
return (cross_count % 2) == 1;
|
|
}
|
|
|
|
/**
|
|
* Wyznacza kierunek przeciwny dla zadanego, przy założeniu, że kierunki geograficzne numerowane są od 0 do 7
|
|
*
|
|
* @param kierunek zadany kierunek
|
|
* @return kierunek przeciwny dla zadanego
|
|
*/
|
|
public static int kierunekPrzeciwny(int kierunek) {
|
|
int kierPrzeciwny = (kierunek + 4) % 8;
|
|
return kierPrzeciwny;
|
|
}
|
|
|
|
// tangens kąta alfa = 22.5 stopnia
|
|
static final double TANG_22_5_DEG = Math.tan(Math.PI / 8);
|
|
// tangens kąta alfa = 22.5 stopnia
|
|
static final double TANG_67_5_DEG = Math.tan(3 * Math.PI / 8);
|
|
|
|
/**
|
|
* Wyznacza najbliższy kierunek geograficzny dla zadanego wektora.
|
|
*
|
|
* @param start kwadrat początkowy wektora
|
|
* @param stop kwadrat końcowy wektora
|
|
* @return kierunek geograficzny klasy EGeoDirection
|
|
*/
|
|
public static EGeoDirection kierunek(Coord.Grid start, Coord.Grid stop) {
|
|
if (start.x == stop.x && start.y == stop.y) {
|
|
return EGeoDirection.UNDEFINED;
|
|
}
|
|
// polnoc-poludnie
|
|
if (start.x == stop.x) {
|
|
if (start.y < stop.y) {
|
|
return EGeoDirection.NORTH; //na polnoc OK
|
|
} else {
|
|
// Start.Y >= Stop.Y
|
|
return EGeoDirection.SOUTH; //na poludnie OK
|
|
}
|
|
}
|
|
// wschod-zachod
|
|
if (start.y == stop.y) {
|
|
if (start.x < stop.x) {
|
|
return EGeoDirection.EAST; //na wschod OK
|
|
} else {
|
|
// Start.X >= Stop.X
|
|
return EGeoDirection.WEST; //na zachod OK
|
|
}
|
|
}
|
|
// pozostale kierunki
|
|
double dx = stop.x - start.x;
|
|
double dy = stop.y - start.y;
|
|
if (dx > 0) {
|
|
double tgAlfa = dy / dx;
|
|
if (tgAlfa >= TANG_67_5_DEG) {
|
|
return EGeoDirection.NORTH;
|
|
} else if (tgAlfa >= TANG_22_5_DEG) {
|
|
return EGeoDirection.NORTHEAST;
|
|
} else if (tgAlfa >= -TANG_22_5_DEG) {
|
|
return EGeoDirection.EAST;
|
|
} else if (tgAlfa >= -TANG_67_5_DEG) {
|
|
return EGeoDirection.SOUTHEAST;
|
|
} else {
|
|
return EGeoDirection.SOUTH;
|
|
}
|
|
} else {
|
|
double tgAlfa = dy / -dx;
|
|
if (tgAlfa >= TANG_67_5_DEG) {
|
|
return EGeoDirection.NORTH;
|
|
} else if (tgAlfa >= TANG_22_5_DEG) {
|
|
return EGeoDirection.NORTHWEST;
|
|
} else if (tgAlfa >= -TANG_22_5_DEG) {
|
|
return EGeoDirection.WEST;
|
|
} else if (tgAlfa >= -TANG_67_5_DEG) {
|
|
return EGeoDirection.SOUTHWEST;
|
|
} else {
|
|
return EGeoDirection.SOUTH;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Funkcja zwraca kierunek geograficzny dla wektora opisanego na sasiednich kwadratach.
|
|
*
|
|
* @param start współrzędne (X, Y) siatki kwadratu początkowego
|
|
* @param stop współrzędne (X, Y) siatki kwadratu końcowego
|
|
* @return kierunek geograficzny klasy EGeoDirection dla wektora zadanego przez kwadrat początkowy
|
|
* i końcowy lub UNDEFINED dla kwadratów niesąsiednich
|
|
*/
|
|
public static EGeoDirection kierunekDlaSasiada(Coord.Grid start, Coord.Grid stop) {
|
|
int d = Math.abs(start.x - stop.x) + Math.abs(start.y - stop.y);
|
|
if (d == 1 || d == 2) {
|
|
if (start.x == stop.x) {
|
|
if (start.y < stop.y) {
|
|
return EGeoDirection.NORTH;
|
|
}
|
|
return EGeoDirection.SOUTH;
|
|
}
|
|
if (start.y == stop.y) {
|
|
if (start.x < stop.x) {
|
|
return EGeoDirection.EAST;
|
|
}
|
|
return EGeoDirection.WEST;
|
|
}
|
|
if (start.x < stop.x) {
|
|
if (start.y < stop.y) {
|
|
return EGeoDirection.NORTHEAST;
|
|
}
|
|
return EGeoDirection.SOUTHEAST;
|
|
}
|
|
if (start.y < stop.y) {
|
|
return EGeoDirection.NORTHWEST;
|
|
}
|
|
return EGeoDirection.SOUTHWEST;
|
|
} else {
|
|
return EGeoDirection.UNDEFINED;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Funkcja zwraca kierunek geograficzny dla wektora opisanego na sasiednich kwadratach.
|
|
*
|
|
* @param xStart współrzędne X siatki kwadratu początkowego
|
|
* @param yStart współrzędne Y siatki kwadratu początkowego
|
|
* @param xStop współrzędne X siatki kwadratu końcowego
|
|
* @param yStop współrzędne Y siatki kwadratu końcowego
|
|
* @return kierunek geograficzny dla wektora zadanego przez kwadrat początkowy i końcowy lub UNDEFINED dla kwadratów niesąsiednich
|
|
*/
|
|
public static EGeoDirection kierunekDlaSasiada(int xStart, int yStart, int xStop, int yStop) {
|
|
int d = Math.abs(xStart - xStop) + Math.abs(yStart - yStop);
|
|
if (d == 1 || d == 2) {
|
|
if (xStart == xStop) {
|
|
if (yStart < yStop) {
|
|
return EGeoDirection.NORTH;
|
|
}
|
|
return EGeoDirection.SOUTH;
|
|
}
|
|
if (yStart == yStop) {
|
|
if (xStart < xStop) {
|
|
return EGeoDirection.EAST;
|
|
}
|
|
return EGeoDirection.WEST;
|
|
}
|
|
if (xStart < xStop) {
|
|
if (yStart < yStop) {
|
|
return EGeoDirection.NORTHEAST;
|
|
}
|
|
return EGeoDirection.SOUTHEAST;
|
|
}
|
|
if (yStart < yStop) {
|
|
return EGeoDirection.NORTHWEST;
|
|
}
|
|
return EGeoDirection.SOUTHWEST;
|
|
} else {
|
|
return EGeoDirection.UNDEFINED;
|
|
}
|
|
}
|
|
|
|
private static final float PRZEKATNA_MK = MapConsts.SS_SIZE * (float) Math.sqrt(2);
|
|
|
|
/**
|
|
* Funkcja wyznacza odległość między środkami kwadratów sąsiednich na zadanym kierunku
|
|
*
|
|
* @param kierunek zadany kierunek sąsiedztwa
|
|
* @return odległość między środkami kwadratów sąsiednich [m]
|
|
*/
|
|
public static float odlegloscKwadratowSasiednich(EGeoDirection kierunek) {
|
|
switch (kierunek) {
|
|
case NORTH:
|
|
case SOUTH:
|
|
case EAST:
|
|
case WEST:
|
|
return MapConsts.SS_SIZE;
|
|
case NORTHEAST:
|
|
case NORTHWEST:
|
|
case SOUTHEAST:
|
|
case SOUTHWEST:
|
|
return PRZEKATNA_MK;
|
|
default:
|
|
return 0.0f;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza sumaryczną długość drogi podanej jako ciąg sąsiednich kwadratów
|
|
*
|
|
* @param road droga jako ciąg sąsiednich kwadratów
|
|
* @return sumaryczna długość drogi [m]
|
|
*/
|
|
public static float dlugoscDrogiPoKwadratch(Coord.Grid[] road) {
|
|
float dl = 0;
|
|
for (int i = 1; i < road.length; i++) {
|
|
dl += Coord.Grid.distance(road[i - 1], road[i]);
|
|
}
|
|
return dl;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza tablicę kwadratów leżących na łamanej.
|
|
*
|
|
* @param punktyLamanej tablica wspolrzednych tworzących łamaną
|
|
* @return kwadratyWyj kolekcja kwadratów leżących na łamanej
|
|
*/
|
|
public static ArrayList<Coord.Grid> kwadratyLamanej(Coord.Grid[] punktyLamanej) {
|
|
ArrayList<Coord.Grid> kwadratyWyj = new ArrayList<Coord.Grid>();
|
|
if (punktyLamanej.length == 2) {
|
|
Coord.Grid[] kwadraty = kwadratyOdcinka(punktyLamanej[0], punktyLamanej[1]);
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadratyWyj.add(kwadraty[i]);
|
|
}
|
|
return kwadratyWyj;
|
|
}
|
|
for (int i = 0; i < punktyLamanej.length - 1; i++) {
|
|
Coord.Grid[] kwadraty = kwadratyOdcinka(punktyLamanej[i], punktyLamanej[i + 1]);
|
|
int lko;
|
|
if (i < punktyLamanej.length - 2) {
|
|
// odcinek lamanej nie jest ostatni, zatem bez ostatniego kwadratu odcinka,
|
|
// gdyz powtorzy sie jako pierwszy w nastepnym odcinku lamanej
|
|
lko = kwadraty.length - 1;
|
|
} else {
|
|
lko = kwadraty.length;
|
|
}
|
|
for (int j = 0; j < lko; j++) {
|
|
kwadratyWyj.add(kwadraty[j]);
|
|
}
|
|
}
|
|
return kwadratyWyj;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza tablicę kwadratów leżących na łamanej.
|
|
*
|
|
* @param punktyLamanej tablica wspolrzednych odcinków tworzących łamaną
|
|
* @return tablica (ciąg) sąsiednich kwadratów leżących na łamanej
|
|
*/
|
|
public static Coord.Grid[] kwadratyLamanej2(Coord.Grid[] punktyLamanej) {
|
|
Coord.Grid[] kwadratyWyj;
|
|
if (punktyLamanej.length == 2) {
|
|
kwadratyWyj = kwadratyOdcinka(punktyLamanej[0], punktyLamanej[1]);
|
|
return kwadratyWyj;
|
|
}
|
|
int maxLen = 0;
|
|
for (int i = 0; i < punktyLamanej.length - 1; i++) {
|
|
maxLen += Math.abs(punktyLamanej[i].x - punktyLamanej[i + 1].x) + Math.abs(punktyLamanej[i].y - punktyLamanej[i + 1].y) + 1;
|
|
}
|
|
Coord.Grid[] helpTab = new Coord.Grid[maxLen];
|
|
int lastLen = 0;
|
|
for (int i = 0; i < punktyLamanej.length - 1; i++) {
|
|
Coord.Grid[] kwadraty = kwadratyOdcinka(punktyLamanej[i], punktyLamanej[i + 1]);
|
|
// liczba kwadratów bieżącego odcinka do zapamietania
|
|
int lko;
|
|
if (i < punktyLamanej.length - 2) {
|
|
// odcinek lamanej nie jest ostatni, zatem bez ostatniego kwadratu odcinka,
|
|
// gdyz powtorzy sie jako pierwszy w nastepnym odcinku lamanej
|
|
lko = kwadraty.length - 1;
|
|
} else {
|
|
// ostatni odcinek łamanej, zatem wszystkie kwadraty odcinka
|
|
lko = kwadraty.length;
|
|
}
|
|
System.arraycopy(kwadraty, 0, helpTab, lastLen, lko);
|
|
// for (int j = 0; j < lko; j++) {
|
|
// helpTab[lastLen] = kwadraty[j];
|
|
// lastLen++;
|
|
// }
|
|
}
|
|
kwadratyWyj = new Coord.Grid[lastLen];
|
|
System.arraycopy(helpTab, 0, kwadratyWyj, 0, lastLen);
|
|
// for (int i = 0; i < lastLen; i++) {
|
|
// kwadratyWyj[i] = helpTab[i];
|
|
// }
|
|
return kwadratyWyj;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza tablice (ciąg) sąsiednich kwadratow na odcinku zadanym przez wspolrzedne jego koncow.
|
|
*
|
|
* @param pocz wspolrzedna poczatku odcinka
|
|
* @param kon wspolrzedna konca odcinka
|
|
* @return tablica sąsiednich kwadratow lezacych na odcinku
|
|
*/
|
|
public static Coord.Grid[] kwadratyOdcinka(Coord.Grid pocz, Coord.Grid kon) {
|
|
return kwadratyOdcinka(pocz.x, pocz.y, kon.x, kon.y);
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza tablice (ciąg) sąsiednich kwadratow na odcinku zadanym przez wspolrzedne jego koncow.
|
|
*
|
|
* @param xp wspolrzedna x poczatku
|
|
* @param yp wspolrzedna y poczatku
|
|
* @param xk wspolrzedna x konca
|
|
* @param yk wspolrzedna y konca
|
|
* @return tablica sąsiednich kwadratow lezacych na odcinku
|
|
*/
|
|
public static Coord.Grid[] kwadratyOdcinka(int xp, int yp, int xk, int yk) {
|
|
Coord.Grid[] kwadraty;
|
|
if ((xp == xk) && (yp == yk)) {
|
|
// odcinek skladajacy sie z jednego kwadratu
|
|
kwadraty = new Coord.Grid[1];
|
|
kwadraty[0] = new Coord.Grid(xp, yp);
|
|
return kwadraty;
|
|
}
|
|
if (xp == xk) {
|
|
// odcinek pionowy
|
|
kwadraty = kwadratyOdcinkaPionowego(xp, yp, xk, yk);
|
|
return kwadraty;
|
|
}
|
|
if (yp == yk) {
|
|
// odcinek poziomy
|
|
kwadraty = kwadratyOdcinkaPoziomego(xp, yp, xk, yk);
|
|
return kwadraty;
|
|
}
|
|
int dx = Math.abs(xk - xp);
|
|
int dy = Math.abs(yk - yp);
|
|
if (dx == dy) {
|
|
// odcinek na przekatnej duzego kwadratu
|
|
kwadraty = kwadratyOdcinkaNaPrzekatnej(xp, yp, xk, yk);
|
|
} else {
|
|
// odcinek na przekatnej duzego prostokata
|
|
kwadraty = kwadratyOdcinkaDowolnego(xp, yp, xk, yk);
|
|
}
|
|
return kwadraty;
|
|
}
|
|
|
|
/**
|
|
* Funkcja pomocnicza.
|
|
* Funkcja zwraca kwadraty odcinka/wektora zorientowanego względem osi OX pod katem 90 stop. lub 270 stop.
|
|
*
|
|
* @param xp wspolrzedna x poczatku
|
|
* @param yp wspolrzedna y poczatku
|
|
* @param xk wspolrzedna x konca
|
|
* @param yk wspolrzedna y konca
|
|
* @return tablica kwadratow lezacych na odcinku
|
|
*/
|
|
private static Coord.Grid[] kwadratyOdcinkaPionowego(int xp, int yp, int xk, int yk) {
|
|
Coord.Grid[] kwadraty = new Coord.Grid[Math.abs(yp - yk) + 1];
|
|
if (yp < yk) {
|
|
// zorientowanie wektora do gory
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadraty[i] = new Coord.Grid(xp, yp + i);
|
|
}
|
|
} else {
|
|
// zorientowanie wektora do dolu
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadraty[i] = new Coord.Grid(xp, yp - i);
|
|
}
|
|
}
|
|
return kwadraty;
|
|
}
|
|
|
|
/**
|
|
* Funkcja pomocnicza.
|
|
* Funkcja zwraca kwadraty odcinka/wektora zorientowanego względem osi OX pod katem 0 stop. lub 180 stop..
|
|
*
|
|
* @param xp wspolrzedna x poczatku
|
|
* @param yp wspolrzedna y poczatku
|
|
* @param xk wspolrzedna x konca
|
|
* @param yk wspolrzedna y konca
|
|
* @return tablica kwadratow lezacych na odcinku
|
|
*/
|
|
private static Coord.Grid[] kwadratyOdcinkaPoziomego(int xp, int yp, int xk, int yk) {
|
|
Coord.Grid[] kwadraty = new Coord.Grid[Math.abs(xp - xk) + 1];
|
|
if (xp < xk) {
|
|
// zorientowanie wektora w prawo
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadraty[i] = new Coord.Grid(xp + i, yp);
|
|
}
|
|
} else {
|
|
// zorientowanie wektora w lewo
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadraty[i] = new Coord.Grid(xp - i, yp);
|
|
}
|
|
}
|
|
return kwadraty;
|
|
}
|
|
|
|
/**
|
|
* Funkcja pomocnicza.
|
|
* Zwraca kwadraty leżące na odcinku/wektorze zorientowanym względem osi OX pod kątem innym niż: 0, 90, 180, 270.
|
|
*
|
|
* @param xp wspolrzedna x poczatku
|
|
* @param yp wspolrzedna y poczatku
|
|
* @param xk wspolrzedna x konca
|
|
* @param yk wspolrzedna y konca
|
|
* @return tablica kwadratow lezacych na odcinku
|
|
*/
|
|
private static Coord.Grid[] kwadratyOdcinkaDowolnego(int xp, int yp, int xk, int yk) {
|
|
int x = xp;
|
|
int y = yp;
|
|
int dx = xk - xp;
|
|
int dy = yk - yp;
|
|
Coord.Grid[] tab;
|
|
int abs_dx = Math.abs(dx);
|
|
int abs_dy = Math.abs(dy);
|
|
if (abs_dx > abs_dy) {
|
|
// przypadek, gdy poruszamy sie po osi OX
|
|
// wyznaczenie wspolczynnikow prostej zawierającej odcinek na podstawie środków kwadratów
|
|
double a = (double) dy / (double) dx;
|
|
double b = yp + 0.5 - a * (xp + 0.5);
|
|
tab = new Coord.Grid[abs_dx + 1];
|
|
int i = 0;
|
|
tab[i] = new Coord.Grid(x, y);
|
|
if (dx > 0) {
|
|
// idziemy w prawo w kierunku rosnacych wartosci x
|
|
if (dy > 0) {
|
|
// prosta zaierająca odcinek jest funkcją rosnącą
|
|
while (x < xk) {
|
|
x++;
|
|
int yy_ref = y + 1;
|
|
double yy_l_test = a * x + b;
|
|
double yy_h_test = a * (x + 1) + b;
|
|
double dy_l = Math.abs(yy_ref - yy_l_test);
|
|
double dy_h = Math.abs(yy_ref - yy_h_test);
|
|
if (dy_l <= dy_h) {
|
|
y++;
|
|
}
|
|
i++;
|
|
tab[i] = new Coord.Grid(x, y);
|
|
}
|
|
} else {
|
|
// prosta zawierająca odcinek jest funkcją malejącą
|
|
while (x < xk) {
|
|
x++;
|
|
int yy_ref = y;
|
|
double yy_l_test = a * x + b;
|
|
double yy_h_test = a * (x + 1) + b;
|
|
double dy_l = Math.abs(yy_ref - yy_l_test);
|
|
double dy_h = Math.abs(yy_ref - yy_h_test);
|
|
if (dy_l <= dy_h) {
|
|
y--;
|
|
}
|
|
i++;
|
|
tab[i] = new Coord.Grid(x, y);
|
|
}
|
|
}
|
|
} else {
|
|
// idziemy w lewo w kierunku malejacych wartosci x
|
|
if (dy > 0) {
|
|
// prosta zaierająca odcinek jest funkcją malejącą
|
|
while (x > xk) {
|
|
x--;
|
|
int yy_ref = y + 1;
|
|
double yy_l_test = a * x + b;
|
|
double yy_h_test = a * (x + 1) + b;
|
|
double dy_l = Math.abs(yy_ref - yy_l_test);
|
|
double dy_h = Math.abs(yy_ref - yy_h_test);
|
|
if (dy_l >= dy_h) {
|
|
y++;
|
|
}
|
|
i++;
|
|
tab[i] = new Coord.Grid(x, y);
|
|
}
|
|
} else {
|
|
// prosta zaierająca odcinek jest funkcją rosnącą
|
|
while (x > xk) {
|
|
x--;
|
|
int yy_ref = y;
|
|
double yy_l_test = a * x + b;
|
|
double yy_h_test = a * (x + 1) + b;
|
|
double dy_l = Math.abs(yy_ref - yy_l_test);
|
|
double dy_h = Math.abs(yy_ref - yy_h_test);
|
|
if (dy_l >= dy_h) {
|
|
y--;
|
|
}
|
|
i++;
|
|
tab[i] = new Coord.Grid(x, y);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// przypadek, gdy poruszamy sie po osi OY
|
|
// zamiana wspolrzednych koncow odcinka
|
|
tab = kwadratyOdcinkaDowolnego(yp, xp, yk, xk);
|
|
// zamiana wspolrzednych x <-> y
|
|
for (int i = 0; i < tab.length; i++) {
|
|
int temp = tab[i].x;
|
|
tab[i].x = tab[i].y;
|
|
tab[i].y = temp;
|
|
}
|
|
}
|
|
return tab;
|
|
}
|
|
|
|
/**
|
|
* Funkcja pomocnicza.
|
|
* Zwraca kwadraty lezace na odcinku zorientowanaym pod dowolnym katem wzgledem osi OX.
|
|
*
|
|
* @param xp wspolrzedna x poczatku
|
|
* @param yp wspolrzedna y poczatku
|
|
* @param xk wspolrzedna x konca
|
|
* @param yk wspolrzedna y konca
|
|
* @return tablica kwadratow lezacych na odcinku
|
|
*/
|
|
private static Coord.Grid[] kwadratyOdcinkaDowolnego2(int xp, int yp, int xk, int yk) {
|
|
int dx = xk - xp;
|
|
int dy = yk - yp;
|
|
if (Math.abs(dx) > Math.abs(dy)) {
|
|
// przypadek, gdy poruszamy sie po osi OX
|
|
// wyznaczenie wspolczynnikow prostej (wartosci w metrach)
|
|
float a;
|
|
float b;
|
|
float dxf = (float) dx;
|
|
float dyf = (float) dy;
|
|
a = dyf / dxf;
|
|
// wspolrzedne srodka kwadratu (xp, yp)
|
|
int xxp = xp * MapConsts.SS_SIZE + MapConsts.SS_SIZE / 2;
|
|
int yyp = yp * MapConsts.SS_SIZE + MapConsts.SS_SIZE / 2;
|
|
b = yyp - a * xxp;
|
|
|
|
if (dx > 0) {
|
|
// idziemy w prawo w kierunku rosnacych wartosci x
|
|
Coord.Grid[] temp = new Coord.Grid[Math.abs(dx) + Math.abs(dy) + 1];
|
|
int dl = 0;
|
|
temp[dl] = new Coord.Grid();
|
|
temp[dl].x = xp;
|
|
temp[dl].y = yp;
|
|
dl++;
|
|
for (int x = xp + 1; x <= xk - 1; x++) {
|
|
// wspolrzedne wierzcholkow kwadratu w metrach
|
|
int xd, xg;
|
|
int yd, yg;
|
|
int y1, y2;
|
|
xd = (x - 1) * MapConsts.SS_SIZE;
|
|
xg = x * MapConsts.SS_SIZE;
|
|
float ydf = a * xd + b;
|
|
float ygf = a * xg + b;
|
|
yd = (int) ydf;
|
|
yg = (int) ygf;
|
|
y1 = yd / MapConsts.SS_SIZE + 1;
|
|
y2 = yg / MapConsts.SS_SIZE + 1;
|
|
temp[dl] = new Coord.Grid();
|
|
temp[dl].x = x;
|
|
temp[dl].y = y1;
|
|
dl++;
|
|
if (y1 != y2) {
|
|
temp[dl] = new Coord.Grid();
|
|
temp[dl].x = x;
|
|
temp[dl].y = y2;
|
|
dl++;
|
|
}
|
|
}
|
|
temp[dl] = new Coord.Grid();
|
|
temp[dl].x = xk;
|
|
temp[dl].y = yk;
|
|
dl++;
|
|
Coord.Grid[] kwadraty = new Coord.Grid[dl];
|
|
System.arraycopy(temp, 0, kwadraty, 0, dl);
|
|
// for (int i = 0; i < kwadraty.length; i++) {
|
|
// // przepisanie referencji na wspolrzedne kwadratow
|
|
// kwadraty[i] = temp[i];
|
|
// }
|
|
return kwadraty;
|
|
} else {
|
|
// idziemy w lewo w kierunku malejacych wartosci x
|
|
// zamiana koncow odcinka
|
|
Coord.Grid[] temp = kwadratyOdcinkaDowolnego2(xk, yk, xp, yp);
|
|
Coord.Grid[] kwadraty = new Coord.Grid[temp.length];
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadraty[i] = temp[kwadraty.length - 1 - i];
|
|
}
|
|
return kwadraty;
|
|
}
|
|
} else {
|
|
// przypadek, gdy poruszamy sie po osi OY
|
|
// zamiana wspolrzednych koncow odcinka
|
|
Coord.Grid[] kwadraty = kwadratyOdcinkaDowolnego2(yp, xp, yk, xk);
|
|
// przepisanie wspolrzednych do nowej tablicy
|
|
// z zamiana wspolrzednych
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
int temp_x = kwadraty[i].x;
|
|
kwadraty[i].x = kwadraty[i].y;
|
|
kwadraty[i].y = temp_x;
|
|
}
|
|
return kwadraty;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Funkcja pomocnicza.
|
|
* Zwraca kwadraty lezace na odcinku zorientowanaym pod katem 45 lub 135 stop. wzgledem osi OX.
|
|
*
|
|
* @param xp wspolrzedna x poczatku
|
|
* @param yp wspolrzedna y poczatku
|
|
* @param xk wspolrzedna x konca
|
|
* @param yk wspolrzedna y konca
|
|
* @return tablica kwadratow lezacych na odcinku
|
|
*/
|
|
private static Coord.Grid[] kwadratyOdcinkaNaPrzekatnej(int xp, int yp, int xk, int yk) {
|
|
int dx = xk - xp;
|
|
int dy = yk - yp;
|
|
Coord.Grid[] kwadraty = new Coord.Grid[Math.abs(dx) + 1];
|
|
if ((dx > 0) && (dy > 0)) {
|
|
// wektor typu "/" do gory
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadraty[i] = new Coord.Grid(xp + i, yp + i);
|
|
}
|
|
} else if ((dx > 0) && (dy < 0)) {
|
|
// wektor typu "\" do dolu
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadraty[i] = new Coord.Grid(xp + i, yp - i);
|
|
}
|
|
} else if ((dx < 0) && (dy < 0)) {
|
|
// wektor typu "/" do dolu
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadraty[i] = new Coord.Grid(xp - i, yp - i);
|
|
}
|
|
} else {
|
|
// wektor typu "\" do gory
|
|
for (int i = 0; i < kwadraty.length; i++) {
|
|
kwadraty[i] = new Coord.Grid(xp - i, yp + i);
|
|
}
|
|
}
|
|
return kwadraty;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza ograniczenie dolne wspolrzednych rejonu
|
|
*
|
|
* @param rejon
|
|
* @return ograniczenie dolne wspolrzednych rejonu
|
|
*/
|
|
public static Coord.Grid wspXYOgranDolne(Coord.Grid[] rejon) {
|
|
if (rejon == null) {
|
|
return null;
|
|
}
|
|
Coord.Grid kw_min = new Coord.Grid();
|
|
kw_min.x = rejon[0].x;
|
|
kw_min.y = rejon[0].y;
|
|
for (int i = 1; i < rejon.length; i++) {
|
|
if (kw_min.x > rejon[i].x) {
|
|
kw_min.x = rejon[i].x;
|
|
}
|
|
if (kw_min.y > rejon[i].y) {
|
|
kw_min.y = rejon[i].y;
|
|
}
|
|
}
|
|
return kw_min;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza ograniczenie górne wspolrzednych rejonu
|
|
*
|
|
* @param rejon
|
|
* @return ograniczenie górne wspolrzednych rejonu
|
|
*/
|
|
public static Coord.Grid wspXYOgranGorne(Coord.Grid[] rejon) {
|
|
if (rejon == null) {
|
|
return null;
|
|
}
|
|
Coord.Grid kw_max = new Coord.Grid();
|
|
kw_max.x = rejon[0].x;
|
|
kw_max.y = rejon[0].y;
|
|
for (int i = 1; i < rejon.length; i++) {
|
|
if (kw_max.x < rejon[i].x) {
|
|
kw_max.x = rejon[i].x;
|
|
}
|
|
if (kw_max.y < rejon[i].y) {
|
|
kw_max.y = rejon[i].y;
|
|
}
|
|
}
|
|
return kw_max;
|
|
}
|
|
|
|
/**
|
|
* Funkcja bada należenie punktu do prostokąta zorientowanego równolegle do osi współrzędnych
|
|
*
|
|
* @param xMin minimalna współrzędna X prostokąta (lewego dolnego rogu)
|
|
* @param yMin minimalna współrzędna Y prostokąta (lewego dolnego rogu)
|
|
* @param xMax maksymalna współrzędna X prostokąta (prawego górnego rogu)
|
|
* @param yMax maksymalna współrzędna Y prostokąta (prawego górnego rogu)
|
|
* @param xTest współrzędna X punktu testowanego
|
|
* @param yTest współrzędna Y punktu testowanego
|
|
* @return true, jeśli testowany punkt należy do prostokąta
|
|
*/
|
|
public static boolean nalezyDoProstokata(int xMin, int yMin, int xMax, int yMax, int xTest, int yTest) {
|
|
if (xTest < xMin || xTest > xMax) {
|
|
return false;
|
|
}
|
|
if (yTest < yMin || yTest > yMax) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Funkcja usuwa z tablicy wejściowej rejon wierzchołków obszaru powtarzające się sąsiednie wierzchołki
|
|
*
|
|
* @param rejon tablica wierzchołków obszaru
|
|
* @return poprawioną tablicę wierzchołków obszaru
|
|
*/
|
|
public static Coord.Grid[] poprawRejon(Coord.Grid[] rejon) {
|
|
if ((rejon == null) || (rejon.length <= 0)) {
|
|
return null;
|
|
}
|
|
int j = 0;
|
|
Coord.Grid[] rejon_temp = new Coord.Grid[rejon.length];
|
|
rejon_temp[j] = rejon[j];
|
|
for (int i = j + 1; i < rejon.length; i++) {
|
|
if (!rejon[i].equals(rejon_temp[j])) {
|
|
if (i == rejon.length - 1) {
|
|
if (rejon[i].equals(rejon_temp[0])) {
|
|
break;
|
|
}
|
|
}
|
|
j++;
|
|
rejon_temp[j] = rejon[i];
|
|
}
|
|
}
|
|
if ((j > 0) && (rejon_temp[0].equals(rejon_temp[j]))) {
|
|
j--;
|
|
}
|
|
Coord.Grid[] rejon_popr = new Coord.Grid[j + 1];
|
|
System.arraycopy(rejon_temp, 0, rejon_popr, 0, rejon_popr.length);
|
|
// for (int k = 0; k < rejonPopr.length; k++) {
|
|
// rejonPopr[k] = rejon_temp[k];
|
|
// }
|
|
return rejon_popr;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza tablice (kolekcję) kwadratow należących do zadanego obszaru
|
|
*
|
|
* @param rej kolejne wierzchołki obszaru zadawane prawoskretnie
|
|
* @return tablica kwadratów należących do zadanego obszaru
|
|
*/
|
|
public static Coord.Grid[] kwadratyObszaru(Coord.Grid[] rej) {
|
|
if (rej == null) {
|
|
return null;
|
|
}
|
|
Coord.Grid[] kwadraty = null;
|
|
Coord.Grid[] rejon = poprawRejon(rej);
|
|
if (rejon.length == 1) { //TODO Tu raczej jest blad
|
|
kwadraty = new Coord.Grid[1];
|
|
return kwadraty;
|
|
}
|
|
if (rejon.length == 2) {
|
|
return kwadratyOdcinka(rejon[0].x, rejon[0].y, rejon[1].x, rejon[1].y);
|
|
}
|
|
Coord.Grid kw_min = wspXYOgranDolne(rejon);
|
|
Coord.Grid kw_max = wspXYOgranGorne(rejon);
|
|
int dl = (kw_max.x - kw_min.x + 1) * (kw_max.y - kw_min.y + 1);
|
|
Coord.Grid[] kwadraty_temp = new Coord.Grid[dl];
|
|
// sprawdzenie kazdego kwadratu z duzego obszaru
|
|
// (prostokat opisany na rejonie)
|
|
dl = 0;
|
|
for (int x = kw_min.x; x <= kw_max.x; x++) {
|
|
for (int y = kw_min.y; y <= kw_max.y; y++) {
|
|
if (insidePolygon(rejon, x, y)) {
|
|
// if (nalezyDoObszaru(rejon, i, j)) {
|
|
// kwadrat o indeksach (i,j) nalezy do obszaru
|
|
kwadraty_temp[dl] = new Coord.Grid(x, y);
|
|
dl++;
|
|
}
|
|
}
|
|
}
|
|
kwadraty = new Coord.Grid[dl];
|
|
System.arraycopy(kwadraty_temp, 0, kwadraty, 0, dl);
|
|
// for (int i = 0; i < kwadraty.length; i++) {
|
|
// kwadraty[i] = new Coord.GridCoord();
|
|
// kwadraty[i].x = kwadraty_temp[i].x;
|
|
// kwadraty[i].y = kwadraty_temp[i].y;
|
|
// }
|
|
return kwadraty;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza srodek zadanego odcinka
|
|
*
|
|
* @param odc odcinek wejściowy
|
|
* @return współrzędne środka zadanego odcinka
|
|
*/
|
|
public static Coord.Grid srodekOdcinka(Coord.Grid[] odc) {
|
|
Coord.Grid srodek = null;
|
|
int xsr = 0, ysr = 0;
|
|
if ((odc != null) && (odc.length > 0)) {
|
|
srodek = new Coord.Grid();
|
|
for (int j = 0; j < odc.length; j++) {
|
|
xsr = xsr + odc[j].x;
|
|
ysr = ysr + odc[j].y;
|
|
}
|
|
srodek.x = (int) xsr / odc.length;
|
|
srodek.y = (int) ysr / odc.length;
|
|
}
|
|
return srodek;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza srodek zadanego odcinka
|
|
*
|
|
* @param pocz początek wejściowego odcinka
|
|
* @param kon koniec wejsciowego odcinka
|
|
* @return współrzędne środka zadanego odcinka
|
|
*/
|
|
public static Coord.Grid srodekOdcinka(Coord.Grid pocz, Coord.Grid kon) {
|
|
Coord.Grid srodek = null;
|
|
int xsr = 0, ysr = 0;
|
|
if ((pocz == null) || (kon == null)) {
|
|
return srodek;
|
|
}
|
|
xsr = (pocz.x + kon.x) / 2;
|
|
ysr = (pocz.y + kon.y) / 2;
|
|
srodek = new Coord.Grid(xsr, ysr);
|
|
return srodek;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza ważony środek odcinka
|
|
*
|
|
* @param pocz początek wejściowego odcinka
|
|
* @param kon koniec wejsciowego odcinka
|
|
* @param waga waga współrzędnych początku odcinka
|
|
* @return ważone współrzędne środka zadanego odcinka
|
|
*/
|
|
public static Coord.Grid srodekOdcinkaWazony(Coord.Grid pocz,
|
|
Coord.Grid kon, float waga) {
|
|
Coord.Grid srodek = null;
|
|
if ((waga < 0.0f) || (waga > 1.0f)) {
|
|
return srodek;
|
|
}
|
|
int xsr = 0, ysr = 0;
|
|
if ((pocz == null) || (kon == null)) {
|
|
return srodek;
|
|
}
|
|
float f_xsr = pocz.x * waga + kon.x * (1.0f - waga);
|
|
float f_ysr = pocz.y * waga + kon.y * (1.0f - waga);
|
|
xsr = (int) f_xsr;
|
|
ysr = (int) f_ysr;
|
|
srodek = new Coord.Grid(xsr, ysr);
|
|
return srodek;
|
|
}
|
|
|
|
/**
|
|
* Funkcja wyznacza pozostałą długość drogi odcinka od zadanego punktu tej drogi do jej końca
|
|
*
|
|
* @param droga zadana droga
|
|
* @param pocz punkt od którego liczona pozostała długość drogi
|
|
* @return pozostała długość odcinka od punktu pocz [m]
|
|
*/
|
|
public static float wyznaczPozostalaDlugoscDrogi(ArrayList<Coord.Grid> droga, int pocz) {
|
|
if ((droga == null) || (droga.size() == 0) || (pocz < 0) || (pocz >= droga.size())) {
|
|
return 0.0f;
|
|
}
|
|
double dl = 0.0f;
|
|
Coord.Grid idkw1 = droga.get(pocz);
|
|
Coord.Grid idkw2;
|
|
for (int j = pocz + 1; j < droga.size() - 1; j++) {
|
|
idkw2 = droga.get(j);
|
|
dl += Coord.Grid.distance(idkw1.x, idkw1.y, idkw2.x, idkw2.y);
|
|
idkw1 = idkw2;
|
|
}
|
|
return (float) dl;
|
|
}
|
|
|
|
/**
|
|
* Funkcja zwraca odleglosc miedzy srodkami malych kwadratow [m].
|
|
*
|
|
* @param p1 współrzędna malego kwadratu pocz.
|
|
* @param p2 współrzędna malego kwadratu konc.
|
|
* @return Odległość między środkami małych kwadratów [m].
|
|
*/
|
|
public static float odleglosc(Coord.Grid p1, Coord.Grid p2) {
|
|
// odleglosc miedzy srodkami malych kwadratow
|
|
if (null == p1 || null == p2) {
|
|
return -1.0f;
|
|
}
|
|
int xx = p1.x - p2.x;
|
|
xx *= xx;
|
|
int yy = p1.y - p2.y;
|
|
yy *= yy;
|
|
float odl = (float) Math.sqrt(xx + yy);
|
|
odl *= MapConsts.SS_SIZE;
|
|
return odl;
|
|
}
|
|
|
|
/**
|
|
* Funkcja zwraca odległość między środkami małych kwadratów [m].
|
|
*
|
|
* @param x1 Wsp X id malego kwadratu pocz.
|
|
* @param y1 Wsp Y id malego kwadratu pocz.
|
|
* @param x2 Wsp X id malego kwadratu konc.
|
|
* @param y2 Wsp Y id malego kwadratu konc.
|
|
* @return Odległość miedzy srodkami malych kwadratow [m].
|
|
*/
|
|
public static float odleglosc(int x1, int y1, int x2, int y2) {
|
|
// odleglosc miedzy srodkami malych kwadratow
|
|
int xx = x1 - x2;
|
|
xx *= xx;
|
|
int yy = y1 - y2;
|
|
yy *= yy;
|
|
float odl = (float) Math.sqrt(xx + yy);
|
|
odl *= MapConsts.SS_SIZE;
|
|
return odl;
|
|
}
|
|
|
|
/**
|
|
* Funkcja zwraca odległość między środkami małych kwadratów [m].
|
|
*
|
|
* @param dx odległość w kwadratach na osi OX.
|
|
* @param dy odległość w kwadratach na osi OY.
|
|
* @return Odległość miedzy srodkami malych kwadratow [m].
|
|
*/
|
|
public static float odleglosc(int dx, int dy) {
|
|
float odl = (float) Math.sqrt(dx * dx + dy * dy);
|
|
odl *= MapConsts.SS_SIZE;
|
|
return odl;
|
|
}
|
|
|
|
// =====================================================================
|
|
|
|
public static void main(String[] args) {
|
|
double odl = Coord.Grid.distance(1, 1, 2, 2);
|
|
double odl2 = Coord.Grid.distanceApprox(1, 1, 2, 2);
|
|
logger.debug("dist = {}, dist2 = {}, DELTA = {}, delta = {}", odl, odl2, odl - odl2, (odl - odl2) / odl);
|
|
odl = Coord.Grid.distance(1, 1, 21, 21);
|
|
odl2 = Coord.Grid.distanceApprox(1, 1, 21, 21);
|
|
logger.debug("dist = {}, dist2 = {}, DELTA = {}, delta = {}", odl, odl2, odl - odl2, (odl - odl2) / odl);
|
|
|
|
odl = Coord.Grid.distance(1, 1, 1, 21);
|
|
odl2 = Coord.Grid.distanceApprox(1, 1, 1, 21);
|
|
logger.debug("dist = {}, dist2 = {}, DELTA = {}, delta = {}", odl, odl2, odl - odl2, (odl - odl2) / odl);
|
|
|
|
odl = Coord.Grid.distance(1, 1, 10, 21);
|
|
odl2 = Coord.Grid.distanceApprox(1, 1, 10, 21);
|
|
logger.debug("dist = {}, dist2 = {}, DELTA = {}, delta = {}", odl, odl2, odl - odl2, (odl - odl2) / odl);
|
|
|
|
odl = Coord.Grid.distance(1, 1, 100, 210);
|
|
odl2 = Coord.Grid.distanceApprox(1, 1, 100, 210);
|
|
logger.debug("dist = {}, dist2 = {}, DELTA = {}, delta = {}", odl, odl2, odl - odl2, (odl - odl2) / odl);
|
|
|
|
odl = Coord.Grid.distance(1, 1, 5, 210);
|
|
odl2 = Coord.Grid.distanceApprox(1, 1, 5, 210);
|
|
logger.debug("dist = {}, dist2 = {}, DELTA = {}, delta = {}", odl, odl2, odl - odl2, (odl - odl2) / odl);
|
|
|
|
|
|
Coord.Grid p = new Coord.Grid(4, 6);
|
|
Coord.Grid q = new Coord.Grid(8, 2);
|
|
Coord.Grid r = new Coord.Grid(6, 4);
|
|
Coord.Grid s = new Coord.Grid(8, 6);
|
|
|
|
Coord.Grid startCoord = new Coord.Grid(10, 10);
|
|
Coord.Grid stopCoord = new Coord.Grid();
|
|
for (int y = 20; y >= 0; y--) {
|
|
for (int x = 0; x <= 20; x++) {
|
|
stopCoord.set(x, y);
|
|
EGeoDirection kier = kierunek(startCoord, stopCoord);
|
|
switch (kier) {
|
|
case NORTH:
|
|
System.out.print('|');
|
|
break;
|
|
case NORTHEAST:
|
|
System.out.print('/');
|
|
break;
|
|
case EAST:
|
|
System.out.print('-');
|
|
break;
|
|
case SOUTHEAST:
|
|
System.out.print('\\');
|
|
break;
|
|
case SOUTH:
|
|
System.out.print('|');
|
|
break;
|
|
case SOUTHWEST:
|
|
System.out.print('/');
|
|
break;
|
|
case WEST:
|
|
System.out.print('-');
|
|
break;
|
|
case NORTHWEST:
|
|
System.out.print('\\');
|
|
break;
|
|
case UNDEFINED:
|
|
System.out.print('O');
|
|
break;
|
|
}
|
|
}
|
|
System.out.println();
|
|
}
|
|
System.out.println();
|
|
|
|
EGeoDirection kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(10, 15));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(10, 5));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(15, 10));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(5, 10));
|
|
System.out.println(kier);
|
|
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(9, 15));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(11, 15));
|
|
System.out.println(kier);
|
|
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(9, 5));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(11, 5));
|
|
System.out.println(kier);
|
|
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(15, 9));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(15, 11));
|
|
System.out.println(kier);
|
|
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(5, 9));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(5, 11));
|
|
System.out.println(kier);
|
|
|
|
|
|
// Kierunki pośrednie: PLN-WSC, PLD-WSC, PLN-ZAC, PLD-ZAC
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(15, 15));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(15, 5));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(5, 15));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(5, 5));
|
|
System.out.println(kier);
|
|
|
|
// PLN-WSC
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(15, 16));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(15, 14));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(16, 15));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(14, 15));
|
|
System.out.println(kier);
|
|
|
|
// PLD-WSC
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(15, 6));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(15, 4));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(16, 5));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(14, 5));
|
|
System.out.println(kier);
|
|
|
|
//PLN-ZAC
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(5, 16));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(5, 14));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(6, 15));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(4, 15));
|
|
System.out.println(kier);
|
|
|
|
// PLD-ZAC
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(5, 6));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(5, 4));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(6, 5));
|
|
System.out.println(kier);
|
|
kier = kierunek(new Coord.Grid(10, 10), new Coord.Grid(4, 5));
|
|
System.out.println(kier);
|
|
|
|
boolean przeciecie = intersection(p, q, r, s);
|
|
r.set(8, 2);
|
|
s.set(11, 5);
|
|
przeciecie = intersection(p, q, r, s);
|
|
r.set(6, 4);
|
|
s.set(7, 3);
|
|
przeciecie = intersection(p, q, r, s);
|
|
r.set(6, 4);
|
|
s.set(10, 0);
|
|
przeciecie = intersection(p, q, r, s);
|
|
r.set(4, 4);
|
|
s.set(6, 6);
|
|
przeciecie = intersection(p, q, r, s);
|
|
r.set(4, 8);
|
|
s.set(6, 10);
|
|
przeciecie = intersection(p, q, r, s);
|
|
r.set(2, 8);
|
|
s.set(1, 9);
|
|
przeciecie = intersection(p, q, r, s);
|
|
|
|
|
|
Coord.Grid[] lamana = {new Coord.Grid(8, 8), new Coord.Grid(3, 4), new Coord.Grid(6, 11)};
|
|
Coord.Grid[] tab = kwadratyLamanej2(lamana);
|
|
|
|
|
|
long det = det3(1, 0, 4, 0, 2, 2);
|
|
det = det3(1, 0, 4, 0, 2, -2);
|
|
|
|
det = det3(1, 1, 1, 4, 0, 2);
|
|
det = det3(1, 1, 1, 4, 2, 2);
|
|
|
|
det = det3(1, 1, 4, 4, 4, 3);
|
|
det = det3(1, 1, 4, 4, 3, 4);
|
|
|
|
|
|
// Coord.GridCoord[] polygon = new Coord.GridCoord[21];
|
|
// polygon[0] = new Coord.GridCoord(12, 18);
|
|
// polygon[1] = new Coord.GridCoord(16, 18);
|
|
// polygon[2] = new Coord.GridCoord(18, 13);
|
|
// polygon[3] = new Coord.GridCoord(21, 13);
|
|
// polygon[4] = new Coord.GridCoord(22, 9);
|
|
// polygon[5] = new Coord.GridCoord(20, 7);
|
|
// polygon[6] = new Coord.GridCoord(17, 7);
|
|
// polygon[7] = new Coord.GridCoord(15, 9);
|
|
// polygon[8] = new Coord.GridCoord(13, 7);
|
|
// polygon[9] = new Coord.GridCoord(15, 5);
|
|
// polygon[10] = new Coord.GridCoord(17, 5);
|
|
// polygon[11] = new Coord.GridCoord(14, 2);
|
|
// polygon[12] = new Coord.GridCoord(8, 8);
|
|
// polygon[13] = new Coord.GridCoord(9, 3);
|
|
// polygon[14] = new Coord.GridCoord(6, 4);
|
|
// polygon[15] = new Coord.GridCoord(3, 4);
|
|
// polygon[16] = new Coord.GridCoord(2, 10);
|
|
// polygon[17] = new Coord.GridCoord(6, 11);
|
|
// polygon[18] = new Coord.GridCoord(6, 13);
|
|
// polygon[19] = new Coord.GridCoord(7, 15);
|
|
// polygon[20] = new Coord.GridCoord(10, 13);
|
|
//
|
|
//
|
|
// // przesunięcie wielokata o wektor
|
|
// for (int k = 0; k < polygon.length; k++) {
|
|
// polygon[k].x += 1000;
|
|
// polygon[k].y += 1000;
|
|
// }
|
|
// Coord.GridCoord p = new Coord.GridCoord();
|
|
// for (int j = 20; j >= 0; j--) {
|
|
// for (int i = 0; i < 25; i++) {
|
|
// p.x = i + 1000;
|
|
// p.y = j + 1000;
|
|
// char c = ' ';
|
|
// if (insidePolygon(polygon, p)) {
|
|
// c = 'O';
|
|
// }
|
|
// for (int k = 0; k < polygon.length; k++) {
|
|
// if (polygon[k].equals(p)) {
|
|
// c = 'X';
|
|
// break;
|
|
// }
|
|
// }
|
|
// System.out.print(c);
|
|
// System.out.print(' ');
|
|
// }
|
|
// System.out.println();
|
|
// }
|
|
// int lp = args.length / 2;
|
|
// for (int i = 0; i < lp; i++) {
|
|
// p.x = Integer.parseInt(args[2 * i]);
|
|
// p.y = Integer.parseInt(args[2 * i + 1]);
|
|
// if (insidePolygon(polygon, p)) {
|
|
// System.out.println("Punkt " + p + " leży wewnatrz");
|
|
// } else {
|
|
// System.out.println("Punkt " + p + " leży na zewnatrz");
|
|
// }
|
|
// }
|
|
// float odl = odleglosc(5000, 4000, 2, 2);
|
|
// odl = odleglosc(1, 1000, 3999, 3);
|
|
// odl = odleglosc(5, 1, 27, 11);
|
|
// odl = odleglosc(10, 1, 2, 20);
|
|
// odl = odleglosc(1, 1, 2, 2);
|
|
//
|
|
// Coord.GridCoord[] rejon = new Coord.GridCoord[4];
|
|
// rejon[0] = new Coord.GridCoord(20, 18);
|
|
// rejon[1] = new Coord.GridCoord(27, 9);
|
|
// rejon[2] = new Coord.GridCoord(9, 1);
|
|
// rejon[3] = new Coord.GridCoord(2, 15);
|
|
//
|
|
// ArrayList< Coord.GridCoord> kwadraty = kwadratyLamanej(rejon);
|
|
// System.out.println(kwadraty);
|
|
|
|
|
|
// try {
|
|
// BufferedWriter wyj = new BufferedWriter(new FileWriter("A.txt"));
|
|
// if (args.length == 5 ) {
|
|
// int xp = Integer.parseInt(args[1]);
|
|
// int yp = Integer.parseInt(args[2]);
|
|
// int xk = Integer.parseInt(args[3]);
|
|
// int yk = Integer.parseInt(args[4]);
|
|
|
|
/*
|
|
* int xp = 50000; int yp = 8000; int xk = 20; int yk = 1;
|
|
*/
|
|
// Coord.GridCoord[] rejon = new Coord.GridCoord[4];
|
|
// rejon[0] = new Coord.GridCoord();
|
|
// rejon[0].x = 20;
|
|
// rejon[0].y = 18;
|
|
// rejon[1] = new Coord.GridCoord();
|
|
// rejon[1].x = 27;
|
|
// rejon[1].y = 9;
|
|
// rejon[2] = new Coord.GridCoord();
|
|
// rejon[2].x = 9;
|
|
// rejon[2].y = 1;
|
|
// rejon[3] = new Coord.GridCoord();
|
|
// rejon[3].x = 2;
|
|
// rejon[3].y = 15;
|
|
// Coord.GridCoord[] kwadraty = kwadratyObszaru(rejon);
|
|
|
|
/*
|
|
* WspXY[] kwadraty = kwadratyOdcinka(xp, yp, xk, yk);
|
|
* wyj.write("pocz: ("); wyj.write(Integer.toString(xp));
|
|
* wyj.write(", "); wyj.write(Integer.toString(yp)); wyj.write(")");
|
|
* wyj.newLine(); wyj.write("kon: (");
|
|
* wyj.write(Integer.toString(xk)); wyj.write(", ");
|
|
* wyj.write(Integer.toString(yk)); wyj.write(")"); wyj.newLine();
|
|
*/
|
|
// wyj.write(Integer.toString(kwadraty.length));
|
|
// wyj.newLine();
|
|
// for (int i = 0; i < kwadraty.length; i++) {
|
|
// wyj.write("(");
|
|
// wyj.write(Integer.toString(kwadraty[i].x));
|
|
// wyj.write(", ");
|
|
// wyj.write(Integer.toString(kwadraty[i].y));
|
|
// wyj.write(")");
|
|
// wyj.newLine();
|
|
// }
|
|
//
|
|
// wyj.close();
|
|
// } catch (IOException e) {
|
|
// e.printStackTrace();
|
|
// }
|
|
}
|
|
|
|
}
|