algorytm.org

Implementacja w C/C++



Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Przynależność punktu do wielokąta - Implementacja w C/C++
Ocena użytkownikóww: *****  / 7
SłabyŚwietny
Nadesłany przez Michał Knasiecki, 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 c++/polygon.cpp:
/*
Algorytm sprawdza, czy punkt p nalezy do wielokata W
Program zostal pobrany ze strony www.algorytm.org
Opracowal: Michal Knasiecki
--------------------------------------------------------
Uwaga:
Daje wejsciowe sa wczytywane z pliku dane.txt
Format zapisu danych wejsciowych znajduje sie w pliku !FormatDatych.txt
*/
#include <conio>
#include <stdio>
#include <stdlib>

//funkcja min
int min(int a, int b)
{
   if (a<b) return a;
   return b;
}
//funkcja max
int max(int a, int b)
{
   if (a>b) return a;
   return b;
}
//funkcja signum
int sign(int a)
{
   if (a == 0)
      return 0;
   if (a < 0)
      return -1;
   return 1;
}

struct vertex 			//Wierzcholek
{
int 		x,y;
};
vertex 	polygon[20];	//Tablica wierzcholow wielokata, max: 20
vertex 	p;				//Dany punkt p
vertex 	r;				//Drugi koniec odcinka |PR|
vertex 	tmp;
int 		n=0;			//Liczba wierzchalkow wielokata
int 		k;
//********************************************************
int przynaleznosc(vertex x, vertex y,vertex z)
{
int	det;
det=x.x*y.y+y.x*z.y+z.x*x.y-z.x*y.y-x.x*z.y-y.x*x.y;
if (det!=0) return(0); else
{
if ((min(x.x,y.x)<=z.x)&&(z.x<=max(x.x,y.x)) && (min(x.y,y.y)<=z.y)&&(z.y<=max(x.y,y.y)))
return(1);  else return(0);
};
};
int det(vertex x,vertex y,vertex z) //Wyznacznik macierzy kwadratowej stopnia 3.
{
return(x.x*y.y+y.x*z.y+z.x*x.y-z.x*y.y-x.x*z.y-y.x*x.y);
}
int przecinanie(vertex a,vertex b)
{
if ((przynaleznosc(p,r,a)==0)&&(przynaleznosc(p,r,b)==0))
{ //pólprosta nie przecina odcinka |AB| w koncach
if ((sign(det(p,r,a)) != sign(det(p,r,b))) &&
    (sign(det(a,b,p)) != sign(det(a,b,r)))) return(1); else return(0);
} else //do pólprostej nalezy przynajmniej jeden koniec odcinka |AB|
	{
   if ((przynaleznosc(p,r,a)==1)&&(przynaleznosc(p,r,b)==1))
   	{
      if ((sign(det(p,r,polygon[(k-1+n)%n])) == sign(det(p,r,polygon[(k+2)%n]))) &&
          (sign(det(p,r,polygon[(k-1+n)%n])) != 0)) return(0); else return(1);
      } else
      if ((przynaleznosc(p,r,polygon[(k-1+n)%n])==1)||(przynaleznosc(p,r,polygon[(k+2)%n])==1)) return(0);
       	else
      	{ //polprosta zawiera tylko wierzcholek
         	if (przynaleznosc(p,r,b)==1)
            	{
                  tmp=a;
                  return(0);
                }
                if (przynaleznosc(p,r,a)==1)
            	{
                  if ((sign(det(p,r,tmp)) == sign(det(p,r,b))) &&
                      (sign(det(p,r,tmp)) != 0)) return(0); else return(1);
                }
         }
   }
   return 0;
}
void oblicz(void)
{
int       l=0; //liczba przeciec
int       i;
div_t		 w;
//
for (i=0;i<n;i++)
{
   k=i;
   if (przynaleznosc(polygon[i], polygon[(i+1)%n], p) == 1)
   {
      printf("Punkt nalezy do krawedzi wielokata\n");
      printf("Dowlony klawisz...");
      return;
   }
   if (przecinanie(polygon[i],polygon[(i+1)%n])==1) l++;
}
printf("Rozwiazanie--------------\n");
printf("Liczba przeciec: %i\n",l);
w=div(l,2);
if (w.rem==0) printf("Punkt p NIE nalezy do wielokata\n"); else
printf("Punkt p nalezy do wielokata\n");
printf("Dowlony klawisz...");
}
void main(void)
{
FILE *plik;
int max_x=0;			//Najwieksza rzedna
int j=0;					//aktualny index tablicy wierzcholkow
//
clrscr();
printf("Dane wejsciowe:\n");
if ((plik=fopen("dane.txt","r"))==NULL)
	{
   printf("Plik \"dane.txt\" z danymi wejsciowymi nie istnieje\n");
   printf("Dowlony klawisz...");
   getch();
   } else
   {
   fscanf(plik,"%i",&p.x);
   fscanf(plik,"%i",&p.y);
   printf("Punkt p=(%i,%i)\n",p.x,p.y);
   do
   {
   fscanf(plik,"%i",&polygon[j].x);
   if (polygon[j].x>max_x) max_x=polygon[j].x;
   fscanf(plik,"%i",&polygon[j].y);
   j++;
   n=j;
   printf("Wierzcholek #%i=(%i,%i)\n",j,polygon[j-1].x,polygon[j-1].y);
   }
   while (!feof(plik));
   fclose(plik);
   //Wyznaczanie wspólrzednych drugiego konca odcinka
   r.x=max_x+1;
   r.y=p.y;
   //Punkt r na pewno znajduje sie poza wielokatem
   printf("Punkt r=(%i,%i)\n",r.x,r.y);
   oblicz();
   getch();
   }
}
Dodaj komentarz