Tiedosto:Point in polygon problem.svg

Wikipediasta
Siirry navigaatioon Siirry hakuun

Alkuperäinen tiedosto(SVG-tiedosto; oletustarkkuus 709 × 709 kuvapistettä; tiedostokoko 690 tavua)

Yhteenveto

Kuvaus
English: Point in polygon problem. Image with scr code
Päiväys
Lähde Own work with use of the code by W. Randolph Franklin (WRF)
Tekijä Adam majewski

Lisenssi

Minä, tämän teoksen tekijänoikeuksien haltija, julkaisen täten tämän teoksen seuraavalla lisenssillä:
w:fi:Creative Commons
nimeäminen jaa samoin
Tämä tiedosto on lisensoitu Creative Commons Nimeä-JaaSamoin 4.0 Kansainvälinen -lisenssillä.
Voit:
  • jakaa – kopioida, levittää ja esittää teosta
  • remiksata – valmistaa muutettuja teoksia
Seuraavilla ehdoilla:
  • nimeäminen – Sinun on mainittava lähde asianmukaisesti, tarjottava linkki lisenssiin sekä merkittävä, mikäli olet tehnyt muutoksia. Voit tehdä yllä olevan millä tahansa kohtuullisella tavalla, mutta et siten, että annat ymmärtää lisenssinantajan suosittelevan sinua tai teoksen käyttöäsi.
  • jaa samoin – Jos muutat tai perustat tähän työhön, voit jakaa tuloksena syntyvää työtä vain tällä tai tämän kaltaisella lisenssillä.

c src code

/*

gcc p.c -Wall -lm

cd existing_folder
git init
git remote add origin git@gitlab.com:adammajewski/PointInPolygonTest_c.git
git add .
git commit
git push -u origin master

*/

#include <stdio.h>
#include <string.h> // strcat
#include <math.h> // round

#define LENGTH 6

/*

Argument	Meaning
nvert	Number of vertices in the polygon. Whether to repeat the first vertex at the end is discussed below.
vertx, verty	Arrays containing the x- and y-coordinates of the polygon's vertices.
testx, testy	X- and y-coordinate of the test point.

https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
PNPOLY - Point Inclusion in Polygon Test
W. Randolph Franklin (WRF)

	

I run a semi-infinite ray horizontally (increasing x, fixed y) out from the test point, 
and count how many edges it crosses. 
At each crossing, the ray switches between inside and outside. 
This is called the Jordan curve theorem.
The case of the ray going thru a vertex is handled correctly via a careful selection of inequalities. 
Don't mess with this code unless you're familiar with the idea of Simulation of Simplicity. 
This pretends to shift the ray infinitesimally down so that it either clearly intersects, or clearly doesn't touch. 
Since this is merely a conceptual, infinitesimal, shift, it never creates an intersection that didn't exist before, 
and never destroys an intersection that clearly existed before.

The ray is tested against each edge thus:

Is the point in the half-plane to the left of the extended edge? and
Is the point's Y coordinate within the edge's Y-range?
Handling endpoints here is tricky.

I run a semi-infinite ray horizontally (increasing x, fixed y) out from the test point, 
and count how many edges it crosses. At each crossing, 
the ray switches between inside and outside. This is called the Jordan curve theorem.
The variable c is switching from 0 to 1 and 1 to 0 each time the horizontal ray crosses any edge. 
So basically it's keeping track of whether the number of edges crossed are even or odd. 
0 means even and 1 means odd.

*/

int pnpoly(int nvert, double *vertx, double *verty, double testx, double testy)
{
  int i, j, c = 0;
  for (i = 0, j = nvert-1; i < nvert; j = i++) {
    if ( ((verty[i]>testy) != (verty[j]>testy)) &&
	 (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
       c = !c;
  }

  return c;
}

void CheckPoint(int nvert, double *vertx, double *verty, double testx, double testy){

int flag;

flag =  pnpoly(nvert, vertx, verty, testx, testy);

 switch(flag){
   case 0  : printf("Outside\n"); break;
   case 1  : printf("Inside\n"); break;
   default : printf(" ??? \n");
 }
}

// http://stackoverflow.com/questions/3437404/min-and-max-in-c
 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
 #define MIN(x, y) (((x) < (y)) ? (x) : (y))

// find max value from array of points and one point
double GiveMax(int na, double *aa,  double a){
  double amax = a;
  int i;

   for (i = 0; i < na;  i++)
     if (aa[i]>amax) amax=aa[i];

   return amax;
   

}

// find min value from array of points and one point
double GiveMin(int na, double *aa,  double a){
  double amin = a;
  int i;

   for (i = 0; i < na;  i++)
     if (aa[i]<amin) amin=aa[i];

   return amin;
   

}

// ---------- svg ------------------------------------------------

int MakeSVG(int n, int nvert, double *xx, double *yy, double x1, double y1, double x2, double y2){

 // svg viewBox = <min-x> <min-y> <width> <height>
 // https://sarasoueidan.com/blog/svg-coordinate-systems/
 double xMax ;
 double yMax ;
 double xMin;
 double yMin;
 // compute good viewBox for input polygon and point 

 xMax = GiveMax(nvert, xx, MAX(x1,x2));
 xMin = GiveMin(nvert, xx, MIN(x1,x2));
 yMax = GiveMax(nvert, yy, MAX(y1,y2));
 yMin = GiveMin(nvert, yy, MIN(y1,y2)); 

 //printf(" xMax = %f ; xMin = %f, yMax = %f , yMin = %f \n ", xMax, xMin, yMax, yMin);        

 // http://www.december.com/html/spec/color4.html  
char *black    = "#000000"; /* hexadecimal number as a string for svg color*/
//char *white    = "#FFFFFF";
//char *burgundy = "#9E0508";
// char *SeaGreen = "#068481";
char *turquoise= "#40E0D0";
char *red      = "#FF0000";
//char *navy     = "#000080";
// char *blue     = "#0000FF";

char *color;

	 	 

 FILE * fp;
 char *filename;
 char name [100]; /* name of file */
 char *comment = "<!-- sample comment in SVG file  \n can be multi-line -->";
 // char points[LENGTH*8]; // length * sizeof(double) to do 

 snprintf(name, sizeof name, "%d", n ); /*  */
  filename =strncat(name,".svg", 4);
  

 fp = fopen( filename,"w");
 if( fp == NULL ) {printf (" file open error \n"); return 1; }

 fprintf(fp,
     "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
     "%s \n "
           "<svg width=\"20cm\" height=\"20cm\" viewBox=\"%f %f %f %f \"\n"
           " xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n",
           comment, xMin*0.9, yMin*0.9, 1.2*(xMax - xMin), 1.2*(yMax - yMin));
  //  printf(" begin done \n");

 

 // polygon 
 // to do : fprintf(fp,"<polygon points=\"%s\" style=\"fill: #FFEBCD;stroke:black;stroke-width:0.2\"/>\n", points);
   fprintf(fp,"<polygon points=\"%f,%f %f,%f %f,%f %f,%f %f,%f %f,%f\" style=\"fill: #FFEBCD;stroke:black;stroke-width:0.2\"/>\n", xx[0],yy[0], xx[1], yy[1], xx[2],yy[2], xx[3], yy[3], xx[4],yy[4] , xx[5],yy[5]);

    // mark point
    if (pnpoly(nvert, xx, yy, x1, y1)) 
       {color = turquoise; printf("inside\n");}
        else {color = red;  printf("outside \n");} 
    fprintf(fp,"<circle cx=\"%f\" cy=\"%f\" r=\"%f\" style=\"stroke:%s; stroke-width:0.5; fill:%s\" opacity=\"0.4\"/>\n",
    x1, y1,(yMax - yMin)/30.0 , black, color);

    if (pnpoly(nvert, xx, yy, x2, y2)) 
       {color = turquoise; printf("inside\n");}
        else {color = red;  printf("outside \n");} 
    fprintf(fp,"<circle cx=\"%f\" cy=\"%f\" r=\"%f\" style=\"stroke:%s; stroke-width:0.5; fill:%s\" opacity=\"0.4\"/>\n",
    x2, y2,(yMax - yMin)/30.0 , black, color);

// end svg 
fprintf(fp,"</svg>\n");
 fclose(fp);
 printf(" file %s saved \n",filename );

return 0;

}

// ================================== main =====================================================

int main (){

// values from http://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon
// number from 0 to (LENGTH-1)
double zzx[LENGTH] = { 13.5,  6.0, 13.5, 42.5, 39.5, 42.5};
double zzy[LENGTH] = {100.0, 70.5, 41.5, 56.5, 69.5, 84.5};
       

CheckPoint(LENGTH, zzx, zzy, zzx[4]- 9, zzy[4]);
CheckPoint(LENGTH, zzx, zzy, zzx[4] + 9, zzy[4]);
MakeSVG(1, LENGTH, zzx, zzy, zzx[4]- 9, zzy[4], zzx[4] + 9, zzy[4]);

return 0;
}

Kuvatekstit

Lisää yhden rivin pituinen kuvaus tästä tiedostosta

Kohteet, joita tässä tiedostossa esitetään

esittää

13. tammikuu 2016

Tiedoston historia

Päiväystä napsauttamalla näet, millainen tiedosto oli kyseisellä hetkellä.

PäiväysPienoiskuvaKokoKäyttäjäKommentti
nykyinen13. tammikuuta 2016 kello 23.52Pienoiskuva 13. tammikuuta 2016 kello 23.52 tallennetusta versiosta709 × 709 (690 tavua)Soul windsurferUser created page with UploadWizard

Seuraavat 2 sivua käyttävät tätä tiedostoa:

Tiedoston järjestelmänlaajuinen käyttö

Seuraavat muut wikit käyttävät tätä tiedostoa:

Metatieto