source: issm/trunk/src/c/shared/Exp/IsInPoly.cpp@ 6965

Last change on this file since 6965 was 6965, checked in by Mathieu Morlighem, 14 years ago

Speeded up IsInPoly.cpp by checking extremas

File size: 2.5 KB
RevLine 
[1]1/*!\file IsInPoly.c
2 * \brief: from a contour, determine which nodes are in domain.
3 */
4
5#include <math.h>
6#include "../../toolkits/toolkits.h"
7#include "./exp.h"
[291]8#include "../shared.h"
[1]9
[2587]10#ifdef HAVE_CONFIG_H
11 #include "config.h"
12#else
13#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
14#endif
[1]15
[291]16
[1]17
[2587]18
19int IsInPoly(Vec in,double* xc,double* yc,int numgrids,double* x,double* y,int i0,int i1, int edgevalue){
20
[291]21 int i;
[1]22 double x0,y0;
23 double value;
[6965]24 double xmin=xc[0];
25 double xmax=xc[0];
26 double ymin=yc[0];
27 double ymax=yc[0];
[1]28
[6965]29 /*Get extrema*/
30 for (i=1;i<numgrids;i++){
31 if(xc[i]<xmin) xmin=xc[i];
32 if(xc[i]>xmax) xmax=xc[i];
33 if(yc[i]<ymin) ymin=yc[i];
34 if(yc[i]>ymax) ymax=yc[i];
35 }
36
[1]37 /*Go through all grids of the mesh:*/
[2587]38 for (i=i0;i<i1;i++){
[291]39
40 //Get current value of value[i] -> do not change it if != 0
41 VecGetValues(in,1,&i,&value);
42 if (value){
43 /*this grid already is inside one of the contours, continue*/
44 continue;
[1]45 }
[291]46
47 /*pick up grid (x[i],y[i]) and figure out if located inside contour (xc,yc)*/
48 x0=x[i]; y0=y[i];
[6965]49 if(x0<xmin || x0>xmax || y0<ymin || y0>ymax){
50 value=0;
51 }
52 else{
53 value=pnpoly(numgrids,xc,yc,x0,y0,edgevalue);
54 }
[1]55 VecSetValues(in,1,&i,&value,INSERT_VALUES);
56 }
[5016]57 return 1;
[1]58}
59
60int IsOutsidePoly(Vec out,double* xc,double* yc,int numgrids,double* x,double* y,int nods,int edgevalue){
61
62 int i,j;
63 double x0,y0;
64 double value;
65
66 /*Go through all grids of the mesh:*/
67 for (i=MPI_Lowerrow(nods);i<MPI_Upperrow(nods);i++){
68 /*pick up grid: */
69 x0=x[i];
70 y0=y[i];
71 if (pnpoly(numgrids,xc,yc,x0,y0,edgevalue)){
72 value=0;
73 }
74 else{
75 value=1;
76 }
77 VecSetValues(out,1,&i,&value,INSERT_VALUES);
78 }
[5016]79
80 return 1;
[1]81}
82
83int pnpoly(int npol, double *xp, double *yp, double x, double y, int edgevalue) {
84 int i, j, c = 0;
85 double n1, n2, normp, scalar;
86
87 /*first test, are they colinear? if yes, is the point in the middle of the segment*/
88 if (edgevalue != 2 ){
89 for (i = 0, j = npol-1; i < npol; j = i++) {
90 n1=pow(yp[i]-yp[j],2.0)+pow(xp[i]-xp[j],2.0);
91 n2=pow(y-yp[j],2.0)+pow(x-xp[j],2.0);
92 normp=pow(n1*n2,0.5);
93 scalar=(yp[i]-yp[j])*(y-yp[j])+(xp[i]-xp[j])*(x-xp[j]);
94
95 if (scalar == normp){
96 if (n2<=n1){
97 c = edgevalue;
98 return c;
99 }
100 }
101 }
102 }
103 /*second test : point is neither on a vertex, nor on a side, where is it ?*/
104 for (i = 0, j = npol-1; i < npol; j = i++) {
105 if ((((yp[i]<=y) && (y<yp[j])) ||
106 ((yp[j]<=y) && (y<yp[i]))) &&
107 (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])){
108 c = !c;
109 }
110 }
111 return c;
112}
Note: See TracBrowser for help on using the repository browser.