The TELEMAC-MASCARET system  trunk
inpoly.f
Go to the documentation of this file.
1 ! ***********************
2  LOGICAL FUNCTION inpoly
3 ! ***********************
4 !
5  &( x , y , xsom , ysom , nsom )
6 !
7 !***********************************************************************
8 ! BIEF V6P1 21/08/2010
9 !***********************************************************************
10 !
11 !brief INDICATES IF A POINT WITH COORDINATES X AND Y IS
12 !+ IN A POLYGON WITH GIVEN VERTICES.
13 !code
14 !+ PRINCIPLE: TAKES HALF A LINE STARTING FROM THE POINT AND COUNTS THE
15 !+ NUMBER OF TIMES IT INTERSECTS WITH THE POLYGON
16 !+
17 !+ ALSO WORKS IF THE POLYGON IS NOT CONVEX
18 !+
19 !+ INTERSECTIONS ARE IDENTIFIED USING THE LINES PARAMETRIC EQUATIONS :
20 !+
21 !+
22 !+ X + A * MU = XDEP + (XARR-XDEP) * LAMBDA
23 !+ Y + B * MU = YDEP + (YARR-YDEP) * LAMBDA
24 !+
25 !+ THE HALF-LINE IS CHARACTERISED BY THE CHOICE OF A AND B, AND THE
26 !+ SIGN OF MU. THERE IS INTERSECTION IF MU > 0 AND 0 < LAMBDA < 1
27 !
28 !warning THE POLYGON VERTICES MUST BE DISTINCT (NO DUPLICATE NODES)
29 !
30 !history E. DAVID (LHF)
31 !+
32 !+
33 !+ ORIGINAL IDEA AND CODE
34 !
35 !history J.-M. HERVOUET (LNH)
36 !+ 18/06/96
37 !+ V5P2
38 !+
39 !
40 !history JEAN-PHILIPPE RENAUD (CSN BRISTOL)
41 !+ 27/07/99
42 !+
43 !+ CORRECTION FOR A SPECIAL CASE
44 !
45 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
46 !+ 13/07/2010
47 !+ V6P0
48 !+ Translation of French comments within the FORTRAN sources into
49 !+ English comments
50 !
51 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
52 !+ 21/08/2010
53 !+ V6P0
54 !+ Creation of DOXYGEN tags for automated documentation and
55 !+ cross-referencing of the FORTRAN sources
56 !
57 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58 !| NSOM |-->| NUMBER OF APICES OF POLYGON
59 !| X |-->| ABSCISSA OF POINT
60 !| Y |-->| ORDINATE OF POINT
61 !| XSOM |-->| ABSCISSAE OF POLYGON APICES
62 !| YSOM |-->| ORDINATES OF POLYGON APICES
63 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
64 !
66  IMPLICIT NONE
67 !
68 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 !
70  INTEGER, INTENT(IN) :: NSOM
71  DOUBLE PRECISION, INTENT(IN) :: X,Y
72  DOUBLE PRECISION, INTENT(IN) :: XSOM(nsom),YSOM(nsom)
73 !
74 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75 !
76  INTEGER N,NSECT
77 !
78  DOUBLE PRECISION A,B,ANGLE,XDEP,YDEP,XARR,YARR,DET,MU,LAMBDA,EPS
79 !
80  DOUBLE PRECISION PI
81  INTRINSIC cos,sin,abs,mod
82 !
83 !-----------------------------------------------------------------------
84 !
85  eps = 1.d-9
86  angle = -1.d0
87 !
88 ! CHOOSES A AND B SUCH AS TO AVOID SPECIAL CASES
89 !
90 1000 CONTINUE
91  angle = angle + 1.d0
92  IF(angle.GT.360.d0) THEN
93 ! SPECIAL CASE OF A POINT ON THE CONTOUR
94  inpoly=.true.
95  RETURN
96  ENDIF
97  pi = 4.d0 * atan( 1.d0 )
98  a = cos( angle*pi/180.d0 )
99  b = sin( angle*pi/180.d0 )
100  nsect=0
101 !
102 ! LOOP ON ALL THE SEGMENTS OF THE POLYGON
103 !
104  DO n=1,nsom
105 !
106 ! DEP : 1ST POINT OF THE SEGMENT ARR : 2ND POINT
107 !
108  xdep=xsom(n)
109  ydep=ysom(n)
110  IF(n.LT.nsom) THEN
111  xarr=xsom(n+1)
112  yarr=ysom(n+1)
113  ELSE
114  xarr=xsom(1)
115  yarr=ysom(1)
116  ENDIF
117 !
118 ! CASE WHERE TWO SUCCESSIVE POINTS ARE DUPLICATES
119 !
120  IF(abs(xdep-xarr)+abs(ydep-yarr).LT.eps) THEN
121  WRITE(lu,*) ' '
122  WRITE(lu,*) ' '
123  WRITE(lu,*) 'INPOLY: SUPERIMPOSED POINTS IN THE POLYGON'
124  WRITE(lu,*) 'AT POINT: ',xdep,' AND ',ydep,' WITH NUMBER ',n
125  IF(n.EQ.nsom) THEN
126  WRITE(lu,*) 'THE LAST POINT MUST NOT BE EQUAL TO THE FIRST'
127  WRITE(lu,*) 'FOR EXAMPLE, GIVE 3 POINTS FOR A TRIANGLE'
128  ENDIF
129  WRITE(lu,*) 'INPOLY IS PROBABLY CALLED BY FILPOL'
130  WRITE(lu,*) ' '
131  WRITE(lu,*) ' '
132  CALL plante(1)
133  stop
134  ENDIF
135 !
136 ! CASE WHERE THE POINT IS A VERTEX
137 ! (THE GENERAL ALGORITHM WOULD DEFINE IT AS EXTERNAL WITH 2 INTERSECTIONS)
138 !
139  IF(abs(x-xdep).LE.eps.AND.abs(y-ydep).LE.eps) THEN
140  nsect=1
141  EXIT
142  ENDIF
143 !
144 ! DETERMINANT OF THE KRAMER SYSTEM
145 !
146  det = a*(ydep-yarr)-b*(xdep-xarr)
147  IF(abs(det).LT.eps) GO TO 1000
148 !
149  mu = ( (xdep-x)*(ydep-yarr)-(ydep-y)*(xdep-xarr) ) / det
150  lambda = ( a *(ydep-y )- b *(xdep-x ) ) / det
151 !
152 !-------------------------------------------------------
153 ! JP RENAUD (CSN BRISTOL) CORRECTION TO AVOID THAT THE INTERSECTION
154 ! POINT BE ONE OF THE VRTICES
155 !
156 ! IF THE INTERSECTION POINT IS A VERTEX, INCREASES THE ANGLE
157 ! OTHERWISE THE POINT WOULD BE COUNTED TWICE INSTEAD OF JUST ONCE
158 !
159  IF ((abs(x+a*mu-xdep).LE.eps.AND.abs(y+b*mu-ydep).LE.eps)
160  & .OR.
161  & (abs(x+a*mu-xarr).LE.eps.AND.abs(y+b*mu-yarr).LE.eps))
162  & GOTO 1000
163 !
164 ! END OF JP RENAUD CORRECTION
165 !-------------------------------------------------------
166 !
167  IF(mu.GE.-eps.AND.lambda.GE.-eps.AND.lambda.LE.1.d0+eps) THEN
168  nsect=nsect+1
169  ENDIF
170 !
171  ENDDO ! N
172 !
173  inpoly=(mod(nsect,2).EQ.1)
174 !
175 !-----------------------------------------------------------------------
176 !
177  RETURN
178  END
logical function inpoly(X, Y, XSOM, YSOM, NSOM)
Definition: inpoly.f:7