Nadesłany przez Tomasz Lubiński, 03 sierpnia 2005 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
Polygon.java:
/**
* Algorytm sprawdza, czy punkt p nalezy do wielokata W
* Program zostal pobrany ze strony www.algorytm.org
* (c)2005 Tomasz Lubinski
*/
public class Polygon {
private static int n=0; //Liczba wierzchalkow wielokata
private static int polygonx[];
private static int polygony[];
private static int rx, ry; //wspolrzedne pomocnicze
private static int tmpx, tmpy; //wspolrzedne pomocnicze
private static int px, py; //wspolrzedne punktu
private static int k;
private static int przynaleznosc(int xx, int xy, int yx, int yy, int zx, int zy) {
int det = xx*yy + yx*zy + zx*xy - zx*yy - xx*zy - yx*xy;
if (det!=0)
return 0;
else {
if ((Math.min(xx, yx) <= zx) && (zx <= Math.max(xx, yx)) &&
(Math.min(xy, yy) <= zy) && (zy <= Math.max(xy, yy)))
return 1;
else
return 0;
}
}
//Wyznacznik macierzy kwadratowej stopnia 3.
private static int det(int xx, int xy, int yx, int yy, int zx, int zy) {
return (xx*yy + yx*zy + zx*xy - zx*yy - xx*zy - yx*xy);
}
private static int przecinanie(int ax, int ay, int bx, int by) {
if ((przynaleznosc(px, py, rx, ry, ax, ay) == 0) &&
(przynaleznosc(px, py, rx, ry, bx, by) == 0)) {
//pólprosta nie przecina odcinka |AB| w koncach
if ((Math.signum(det(px, py, rx, ry, ax, ay)) != Math.signum(det(px, py, rx, ry, bx, by))) &&
(Math.signum(det(ax, ay, bx, by, px, py)) != Math.signum(det(ax, ay, bx, by, rx, ry))))
return 1;
else
return 0;
}
else {
// do pólprostej nalezy przynajmniej jeden koniec odcinka |AB|
if ((przynaleznosc(px, py, rx, ry, ax, ay) == 1) &&
(przynaleznosc(px, py, rx, ry, bx, by)==1)) {
if (Math.signum(det(px, py, rx, ry, polygonx[(k-1+n)%n], polygony[(k-1+n)%n])) == Math.signum(det(px, py, rx, ry, polygonx[(k+2)%n], polygony[(k+2)%n])) &&
Math.signum(det(px, py, rx, ry, polygonx[(k-1+n)%n], polygony[(k-1+n)%n])) != 0)
return 0;
else
return 1;
} else {
if ((przynaleznosc(px, py, rx, ry, polygonx[(k-1+n)%n], polygony[(k-1+n)%n]) == 1) ||
(przynaleznosc(px, py, rx, ry, polygonx[(k+2)%n], polygony[(k+2)%n]) == 1))
return 0;
else {
//polprosta zawiera tylko wierzcholek
if (przynaleznosc(px, py, rx, ry, bx, by) == 1) {
tmpx = ax;
tmpy = ay;
return 0;
}
if (przynaleznosc(px, py, rx, ry, ax, ay)==1){
if (Math.signum(det(px, py, rx, ry, tmpx, tmpy)) == Math.signum(det(px, py, rx, ry, bx, by)) &&
Math.signum(det(px, py, rx, ry, tmpx, tmpy)) != 0)
return 0;
else
return 1;
}
}
}
}
return 0;
}
private static void oblicz() {
int l=0; //liczba przeciec
int i;
for (i=0; i<n; i++) {
k=i;
if (przynaleznosc(polygonx[i], polygony[i], polygonx[(i+1)%n], polygony[(i+1)%n], px, py) ==1) {
System.out.println("Punkt nalezy do krawedzi wielokata");
return;
}
if (przecinanie(polygonx[i], polygony[i], polygonx[(i+1)%n], polygony[(i+1)%n]) == 1)
l++;
}
System.out.println("Rozwiazanie--------------");
System.out.println("Liczba przeciec: " + l);
if ((l % 2) == 0)
System.out.println("Punkt p NIE nalezy do wielokata\n");
else
System.out.println("Punkt p nalezy do wielokata\n");
}
public static void main(String[] args) {
int max_x = Integer.MIN_VALUE; //Najwieksza rzedna
System.out.println("Dane wejsciowe:");
System.out.println("Podaj wspolrzedne punktu:");
px = Console.readInt("x=");
py = Console.readInt("y=");
System.out.println("Podaj liczbe punktow tworzacych wielokat:");
n = Console.readInt("n=");
polygonx = new int[n];
polygony = new int[n];
for (int i=0; i<n; i++){
System.out.println("Punkt " + (i+1));
polygonx[i] = Console.readInt("x=");
polygony[i] = Console.readInt("y=");
if (polygonx[i] > max_x)
max_x = polygonx[i];
}
//Wyznaczanie wspólrzednych drugiego konca odcinka
rx = max_x+1;
ry = py;
//Punkt r na pewno znajduje sie poza wielokatem
System.out.println("Punkt r=(" + rx + ", " + ry + ")");
oblicz();
}
}

