source: TOOLS/MOZAIC/src/POLY/u_polyg.f90 @ 3328

Last change on this file since 3328 was 3326, checked in by omamce, 7 years ago

O.M. : Utility to generate interpolatio weights for OASIS-MCT

File size: 20.2 KB
Line 
1MODULE u_polyg
2   !---------------------------------------------------------------------
3   !- utilitaires relatifs aux polygones
4   !---------------------------------------------------------------------
5   USE poly_types
6   USE m_g2d
7   USE mt_polyg
8   !-
9   IMPLICIT NONE
10   !-
11   !$ real,parameter :: v_eps = 1.e-4
12   REAL (kind=rp) :: v_eps = 100.0_rp *EPSILON(v_eps)
13   !---------------------------------------------------------------------
14CONTAINS
15   !=
16   SUBROUTINE p_dec   (pol,npd,pd)
17      !---------------------------------------------------------------------
18      !- decomposition d'un polygone quelconque en elements convexes
19      !---------------------------------------------------------------------
20      TYPE(polyg) :: pol
21      INTEGER :: npd
22      TYPE(polyg),DIMENSION(:) :: pd
23      !-
24      TYPE(polyg) :: pv
25      INTEGER :: nppol
26      INTEGER,DIMENSION(pol%n) :: kpt
27      INTEGER,DIMENSION(pol%n) :: tabpt
28      REAL (kind=rp), DIMENSION(pol%n)    :: tabcr
29      !- elements relatifs aux croisements
30      TYPE :: croisement
31         REAL (kind=rp)   :: c1,c2
32         INTEGER :: k1,k2,kp
33      END TYPE croisement
34      INTEGER :: nvcr
35      TYPE(croisement),DIMENSION(3*pol%n) :: tvcr
36      !- elements relatifs aux segments
37      TYPE :: segment
38         INTEGER :: ideb,ifin
39      END TYPE segment
40      INTEGER :: nsgm
41      TYPE(segment),DIMENSION(7*pol%n) :: tsgm
42      !-
43      INTEGER :: npt
44      TYPE(c2d),DIMENSION(5*pol%n) :: tpt
45      !-
46      INTEGER :: n1,n2,n3,ii,ki,kp
47      INTEGER :: ipd,ipc,ib,npw
48      REAL (kind=rp) :: c1,c2,cb,alfa
49      TYPE(c2d) :: d1,d2,ptn
50      INTRINSIC huge
51      !---------------------------------------------------------------------
52      npd = 0; pv = pol;
53      !- reduction du polygone ---------------------------------------------
54      CALL p_red   (pv)
55      !- obtention des elements constitutifs du polygone -------------------
56      nppol = 0; npt = 0;
57      IF (pv%n > 2) THEN
58         DO n1=1,pv%n
59            nppol = nppol+1; ptn = pv%pt(n1);
60            CALL p_apt   (ptn,npt,tpt,kp)
61            kpt(nppol) = kp;
62         ENDDO
63      ENDIF
64      !- recherche des croisements -----------------------------------------
65      nvcr = 0;
66      DO n1=1,nppol-2
67         d1 = tpt(kpt(n1+1))-tpt(kpt(n1));
68         DO n2=n1+2,nppol+MIN(n1-2,0)
69            d2 = tpt(kpt(MOD(n2,nppol)+1))-tpt(kpt(n2));
70            CALL p_i2d (tpt(kpt(n1)),d1,tpt(kpt(n2)),d2,c1,c2,ii)
71            IF (ii > 0) THEN
72               IF (     (     (c1 >  v_eps).AND.(c1 < (1.-v_eps))    &
73                  .AND.(c2 > -v_eps).AND.(c2 < (1.+v_eps)) )  &
74                  .OR.(     (c1 > -v_eps).AND.(c1 < (1.+v_eps))    &
75                  .AND.(c2 >  v_eps).AND.(c2 < (1.-v_eps)) )  ) THEN
76                  nvcr = nvcr+1;
77                  ptn = tpt(kpt(n2))+c2*d2
78                  CALL p_apt   (ptn,npt,tpt,kp)
79                  tvcr(nvcr) = croisement(c1,c2,n1,n2,kp)
80               ENDIF
81            ENDIF
82         ENDDO
83      ENDDO
84      !- creation des segments avec inclusion des croisements --------------
85      nsgm = 0;
86      DO n1=1,nppol
87         !--- creation des points
88         ki = 1; tabcr(ki) = 0.; tabpt(ki) = kpt(n1);
89         DO n2=1,nvcr
90            IF      (n1 == tvcr(n2)%k1) THEN
91               ki = ki+1; tabcr(ki) = tvcr(n2)%c1; tabpt(ki) = tvcr(n2)%kp;
92            ELSE IF (n1 == tvcr(n2)%k2) THEN
93               ki = ki+1; tabcr(ki) = tvcr(n2)%c2; tabpt(ki) = tvcr(n2)%kp;
94            ENDIF
95         ENDDO
96         ki = ki+1; tabcr(ki) = 1.; tabpt(ki) = kpt(MOD(n1,nppol)+1);
97         !--- ordonnancement des points
98         DO n3=3,ki-1
99            DO n2=2,n3-1
100               IF (tabcr(n3) < tabcr(n2)) THEN
101                  tabcr(n2:n3) = (/ tabcr(n3), tabcr(n2:n3-1) /)
102                  tabpt(n2:n3) = (/ tabpt(n3), tabpt(n2:n3-1) /)
103                  EXIT
104               ENDIF
105            ENDDO
106         ENDDO
107         !--- creation des segments
108         DO n2=1,ki-1
109            IF (ABS(tabcr(n2+1)-tabcr(n2)) > v_eps) THEN
110               nsgm = nsgm+1;
111               alfa   = 0.5_rp*(tabcr(n2)+tabcr(n2+1))
112               IF (p_qos(nppol,kpt,tpt,n1,alfa)) THEN
113                  tsgm(nsgm) = segment(tabpt(n2),tabpt(n2+1));
114               ELSE
115                  tsgm(nsgm) = segment(tabpt(n2+1),tabpt(n2));
116               ENDIF
117            ENDIF
118         ENDDO
119      ENDDO
120      !- creation des polygones sans croisement par chainage des segments
121      l_p: &
122         DO n1=1,nsgm
123      !--- recherche du prochain segment disponible
124      IF (tsgm(n1)%ideb <= 0)   CYCLE l_p
125      !--- creation d'un nouveau polygone
126      ipd = tsgm(n1)%ideb; ipc = tsgm(n1)%ifin;
127      tsgm(n1)%ideb = -ipd;
128      pv%n = 2; pv%pt(1:2) = (/ tpt(ipd),tpt(ipc) /);
129      DO
130         !----- recherche du segment suivant
131         ib = 0; cb = HUGE(cb);
132         DO n2=n1+1,nsgm
133            IF (tsgm(n2)%ideb == ipc) THEN
134               c1 =   (tpt(tsgm(n2)%ifin)-pv%pt(pv%n)) &
135                  .a.(pv%pt(pv%n-1)-pv%pt(pv%n))
136               IF (ABS(c1) > v_eps) THEN
137                  IF (    (ib == 0) &
138                     .OR.((cb < 0).AND.(c1 > cb)) &
139                     .OR.((cb > 0).AND.(c1 > 0).AND.(c1 < cb)) ) THEN
140                     ib = n2; cb = c1;
141                  ENDIF
142               ENDIF
143            ENDIF
144         ENDDO
145         IF (ib == 0) THEN
146            WRITE (unit=*,fmt='(" chainage interrompu !!!")');
147            CYCLE l_p;
148         ENDIF
149         !-----
150         tsgm(ib)%ideb = -ipc; ipc = tsgm(ib)%ifin;
151         IF (ipc /= ipd) THEN
152            !------- extension du polygone
153            pv%n = pv%n+1; pv%pt(pv%n) = tpt(ipc);
154         ELSE
155            !------- traitement des concavites
156            CALL p_dcv   (pv,npw,pd(npd+1:))
157            npd = npd+npw
158            EXIT
159         ENDIF
160      ENDDO
161   ENDDO l_p
162   !----------------------
163END SUBROUTINE p_dec
164!=
165SUBROUTINE p_dcv   (pg,npd,pd)
166   !---------------------------------------------------------------------
167   !- decomposition d'un polygone sans croisement en polygones convexes
168   !---------------------------------------------------------------------
169   TYPE(polyg) :: pg
170   INTEGER :: npd
171   TYPE(polyg),DIMENSION(:) :: pd
172   !-
173   TYPE(polyg) :: pw
174   TYPE(polyg),DIMENSION((pg%n+1)/2) :: pp
175   INTEGER :: jc,jp,js,np
176   INTEGER :: ks,k0,k1,k2
177   INTEGER :: jw,ii
178   REAL (kind=rp) :: c1,c2,cb
179   TYPE(c2d) :: d1,d2,ptn
180   INTRINSIC huge
181   !---------------------------------------------------------------------
182   npd = 0;
183   !- memorisation et reduction du polygone
184   np = 1; pp(1)%pt(1:pg%n) = pg%pt(1:pg%n); pp(1)%n = pg%n;
185   CALL p_red   (pp(1))
186   !- recherche et des traitements des concavites
187   DO
188      IF (np <= 0) EXIT
189      jc = 0;
190      DO
191         pw = pp(np)
192         jc = jc+1;
193         IF ( (pw%n <= 3).OR.(jc > pw%n) ) EXIT
194         jp = MOD(jc-2+pw%n,pw%n)+1; js = MOD(jc,pw%n)+1;
195         IF ( ((pw%pt(js)-pw%pt(jc)).a.(pw%pt(jp)-pw%pt(jc))) &
196            < -v_eps) THEN
197            !------- traitement d'un rebroussement
198            !------- partage du polygone pw par le segment (jc,jc+1)
199            d1 = pw%pt(MOD(jc,pw%n)+1)-pw%pt(jc);
200            !------- recherche de l'intersection la plus proche
201            ks = 0; cb = HUGE(cb);
202            DO jw=2,pw%n-2
203               k0 = MOD(jc+jw-1,pw%n)+1
204               d2 = pw%pt(MOD(k0,pw%n)+1)-pw%pt(k0)
205               CALL p_i2d (pw%pt(jc),d1,pw%pt(k0),d2,c1,c2,ii)
206               IF (ii > 0) THEN
207                  IF ( (c2 > -v_eps).AND.(c2 < (1.+v_eps)) ) THEN
208                     IF (c1 < v_eps) THEN
209                        IF (ABS(c1) < ABS(cb)) THEN
210                           ks = k0; ptn = pw%pt(k0)+c2*d2; cb = c1;
211                        ENDIF
212                     ENDIF
213                  ENDIF
214               ENDIF
215            ENDDO
216            IF (ks /= 0) THEN
217               !--------- polygones resultants
218               k1 = MIN(jc,ks); k2 = MAX(jc,ks);
219               pp(np)%n = k2-k1+1;
220               pp(np)%pt(1:pp(np)%n) = (/ ptn, pw%pt(k1+1:k2) /);
221               CALL p_red (pp(np));
222               np = np+1;
223               pp(np)%n = k1+1+pw%n-k2;
224               pp(np)%pt(1:pp(np)%n) = &
225                  (/ pw%pt(1:k1), ptn, pw%pt(k2+1:pw%n) /);
226               CALL p_red (pp(np));
227               jc = 0;
228            ELSE
229               WRITE (unit=*,fmt='(" echec !!!")'); STOP
230            ENDIF
231         ENDIF
232      ENDDO
233      npd = npd+1; pd(npd) = pw; np = np-1;
234   ENDDO
235   !----------------------
236END SUBROUTINE p_dcv
237!=
238SUBROUTINE p_apt (point,npt,tpt,kp)
239   !---------------------------------------------------------------------
240   !- recherche de l'index d'un point dans un tableau
241   !- creation de l'element si il n'existe pas
242   !---------------------------------------------------------------------
243   TYPE(c2d) :: point
244   INTEGER :: npt
245   TYPE(c2d),DIMENSION(*) :: tpt
246   INTEGER :: kp
247   !-
248   INTEGER :: i
249   TYPE(c2d) :: ddp
250   !---------------------------------------------------------------------
251   kp = 0
252   DO i=1,npt
253      ddp = point-tpt(i)
254      IF ((ddp.s.ddp) < v_eps) THEN
255         kp = i
256         EXIT
257      ENDIF
258   ENDDO
259   IF (kp == 0) THEN
260      npt = npt+1; kp = npt; tpt(kp) = point;
261   ENDIF
262   !----------------------
263END SUBROUTINE p_apt
264!=
265SUBROUTINE p_i2d (p1,d1,p2,d2,c1,c2,ii)
266   !---------------------------------------------------------------------
267   !- recherche de l'intersection de deux droites
268   !-
269   !-        1  droites secantes
270   !- ii =   0  droites paralleles distinctes
271   !-       -1  droites confondues
272   !---------------------------------------------------------------------
273   TYPE(c2d) :: p1,d1,p2,d2
274   REAL (kind=rp) :: c1,c2
275   INTEGER :: ii
276   !-
277   REAL (kind=rp) :: det
278   TYPE(c2d) :: vp,vn
279   !---------------------------------------------------------------------
280   det = d1.v.d2; vp = p2-p1;
281   IF (ABS(det) > v_eps) THEN
282      ii = 1;
283      c1 = (vp.v.d2)/det; c2 = (vp.v.d1)/det;
284   ELSE
285      ii =  0;
286      vn = c2d(-d1%y,d1%x);
287      det = vn.v.d2;
288      IF (ABS(det) > v_eps) THEN
289         c1 = (vp.v.d2)/det; c2 = (vp.v.vn)/det;
290         IF (ABS(c1) < v_eps) THEN
291            ii = -1;
292         ENDIF
293      ENDIF
294   ENDIF
295   !----------------------
296END SUBROUTINE p_i2d
297!=
298SUBROUTINE p_orp   (pw)
299   !---------------------------------------------------------------------
300   !- orientation d'un polygone (sans croisement)
301   !---------------------------------------------------------------------
302   !- comptage des intersections de la demi-mediatrice orientee
303   !- du segment (pw%n,1) avec le polygone.
304   !- si ce nombre est pair, la demi-mediatrice est exterieure,
305   !- et on inverse le sens du polygone.
306   !---------------------------------------------------------------------
307   TYPE(polyg) :: pw
308   !-
309   INTEGER :: i,ii,nic,issp,issc
310   REAL (kind=rp) :: c1,c2
311   TYPE(c2d) :: pm,vt,vn,vw
312
313!$$$   integer :: ntoto = 0
314   !---------------------------------------------------------------------
315   pm = 0.5_rp*(pw%pt(pw%n)+pw%pt(1));
316   vt = pw%pt(1)-pw%pt(pw%n);
317   vn = c2d(-vt%y,vt%x);
318   !-
319   nic = 0; issp = 0;
320   DO i=1,pw%n-1
321      vw  = pw%pt(i+1)-pw%pt(i);
322      CALL p_i2d   (pm,vn,pw%pt(i),vw,c1,c2,ii)
323      IF (ii > 0) THEN
324!$$$$$ if (c1 > 0.) then
325         IF (c1 > -v_eps) THEN
326            IF      ( (c2 >  v_eps).AND.(c2 < (1.-v_eps)) ) THEN
327               !--------- la normale passe par l'interieur du cote (i,i+1)
328               nic = nic+1
329               issp = 0;
330            ELSE IF ( (c2 > -v_eps).AND.(c2 < (1.+v_eps)) ) THEN
331               !--------- la normale passe par le sommet i
332               issc = NINT(SIGN(1.,vw.s.vt));
333               IF ((issc*issp) > 0) THEN
334                  nic = nic+1
335               ENDIF
336               issp = issc;
337            ENDIF
338         ENDIF
339      ENDIF
340   ENDDO
341   !-
342   IF (MOD(nic,2) == 0) THEN
343!$$$     write  (unit=*,fmt='(" inversion du sens du polygone")');
344!$$$     ntoto = ntoto + 1
345!$$$     write  (unit=*,fmt=*) pw%pt(1:pw%n:1)
346!$$$     if ( ntoto > 4 ) stop
347      pw%pt(1:pw%n:1) = pw%pt(pw%n:1:-1);
348!$$$   else
349!$$$     write  (unit=*,fmt='(" sens correct")');
350   ENDIF
351   !----------------------
352END SUBROUTINE p_orp
353!=
354LOGICAL FUNCTION p_qos   (nppol,kpt,tpt,isc,alfa)
355   !---------------------------------------------------------------------
356   !- test d'orientation d'un segment de polygone
357   !---------------------------------------------------------------------
358   !- comptage des intersections de la demi-mediatrice orientee
359   !- du segment (isc,isc+alpha*longueur(isc)) avec le polygone.
360   !- si ce nombre est pair, la demi-mediatrice est exterieure,
361   !- et le polygone est mal oriente.
362   !---------------------------------------------------------------------
363   INTEGER :: nppol
364   INTEGER,DIMENSION(*) :: kpt
365   TYPE(c2d),DIMENSION(*) :: tpt
366   INTEGER :: isc
367   REAL (kind=rp) :: alfa
368   !-
369   INTEGER :: i,ii,nic,issp,issc,isd
370   REAL (kind=rp) :: c1,c2
371   TYPE(c2d) :: ptm,pts,normale,segment
372   !---------------------------------------------------------------------
373   ptm = tpt(kpt(isc))+alfa*(tpt(kpt(MOD(isc,nppol)+1))-tpt(kpt(isc)));
374   segment = ptm-tpt(kpt(isc));
375   normale%x = -segment%y; normale%y = segment%x;
376   !-
377   nic = 0; issp = 0;
378   DO i=0,nppol-2
379      isd = MOD(isc+i,nppol)+1
380      pts  = tpt(kpt(MOD(isd,nppol)+1))-tpt(kpt(isd));
381      CALL p_i2d   (ptm,normale,tpt(kpt(isd)),pts,c1,c2,ii)
382      IF (ii > 0) THEN
383         IF (c1 > 0.) THEN
384            IF      ( (c2 > v_eps).AND.(c2 < (1.-v_eps)) ) THEN
385               !--------- la normale passe par l'interieur du cote (isd,isd+1)
386               nic = nic+1
387               issp = 0;
388            ELSE IF ( (c2 > -v_eps).AND.(c2 < (1.+v_eps)) ) THEN
389               !--------- la normale passe par le sommet isd
390               issc = NINT(SIGN(1.,pts.s.segment));
391               IF ((issc*issp) > 0) THEN
392                  nic = nic+1
393               ENDIF
394               issp = issc;
395            ENDIF
396         ENDIF
397      ENDIF
398   ENDDO
399   !-
400   p_qos = (MOD(nic,2) /= 0)
401   !--------------------
402END FUNCTION p_qos
403!=
404SUBROUTINE p_pcp   (p1,p2,p3)
405   !---------------------------------------------------------------------
406   !- polygone commun a 2 polygones convexes orientes
407   !---------------------------------------------------------------------
408   TYPE(polyg) :: p1,p2,p3
409   !-
410   TYPE(polyg),DIMENSION(2) :: pw
411   INTEGER :: j1d,j1f,j2d,j2f
412   INTEGER :: kc,kr
413   INTEGER :: ipd,ipf
414   TYPE(c2d) :: v1,v2
415   REAL (kind=rp) :: ww
416   !---------------------------------------------------------------------
417   !- copie du polygone p1 dans le polygone candidat
418   kc = 1; pw(kc)%n = p1%n; pw(kc)%pt(1:pw(kc)%n) = p1%pt(1:pw(kc)%n);
419   !- decoupage du polygone candidat par chaque cote de p2
420   j2d = p2%n;
421   l_r: &
422      DO j2f=1,p2%n
423   !--- definition du polygone resultat
424   kr = 3-kc; pw(kr)%n = 0;
425   !--- definition du vecteur decoupant
426   v2 = p2%pt(j2f)-p2%pt(j2d);
427   !--- traitement des cotes successifs du polygone candidat
428   j1d = pw(kc)%n;
429   !--- position relative (origine segment candidat)/(segment decoupant)
430   ipd = n_sgn(v2.v.(pw(kc)%pt(j1d)-p2%pt(j2d)))
431   DO j1f=1,pw(kc)%n
432      !----- definition du vecteur candidat
433      v1 = pw(kc)%pt(j1f)-pw(kc)%pt(j1d);
434      !----- position relative (fin segment candidat)/(segment decoupant)
435      ipf = n_sgn(v2.v.(pw(kc)%pt(j1f)-p2%pt(j2d)))
436      !----- si l'origine appartient au cote decoupant ou est du bon cote,
437      !----- on l'insere dans le nouveau polygone candidat
438      IF (ipd >= 0) THEN
439         pw(kr)%n = pw(kr)%n+1
440         pw(kr)%pt(pw(kr)%n) = pw(kc)%pt(j1d)
441      ENDIF
442      !----- si le segment candidat est coupe par le segment decoupant,
443      !----- on introduit l'intersection dans le polygone resultat
444      IF ((ipd*ipf) < 0) THEN
445         pw(kr)%n = pw(kr)%n+1
446         ww  = (v2.v.(pw(kc)%pt(j1d)-p2%pt(j2d)))/(v1.v.v2)
447         pw(kr)%pt(pw(kr)%n) = pw(kc)%pt(j1d)+ww*v1
448      ENDIF
449      !----- l'extremite du segment sera l'origine du segment suivant
450      ipd = ipf; j1d = j1f;
451   ENDDO
452   !--- si le polygone resultat est degenere, il n'y a pas de recouvrement
453   IF (pw(kr)%n < 3)   EXIT l_r
454   !--- le polygone resultat devient polygone candidat
455   kc = kr;
456   !--- passage au cote suivant de p2
457   j2d = j2f;
458ENDDO l_r
459!- fin de decoupage : rangement du resultat dans p3
460IF (pw(kr)%n < 3) THEN
461   p3%n = 0
462ELSE
463   p3%n = pw(kr)%n
464   p3%pt(1:p3%n) = pw(kr)%pt(1:pw(kr)%n)
465ENDIF
466!----------------------
467END SUBROUTINE p_pcp
468!=
469SUBROUTINE p_red (p0)
470   !---------------------------------------------------------------------
471   !- reduction d'un polygone
472   !- suppression des doublons et alignements
473   !---------------------------------------------------------------------
474TYPE(polyg) :: p0
475!-
476INTEGER :: ip,ic,is
477TYPE(c2d) :: dp,ds
478!---------------------------------------------------------------------
479ic = 1;
480DO
481   IF ( (p0%n < 3).OR.(ic > p0%n) ) EXIT
482   ip = MOD(ic-2+p0%n,p0%n)+1; is = MOD(ic,p0%n)+1;
483   dp = p0%pt(ic)-p0%pt(ip); ds = p0%pt(is)-p0%pt(ic);
484!$$$ if      ((dp.s.dp) < v_eps) then
485!$$$   p0%pt(ip:p0%n-1) = p0%pt(ip+1:p0%n); p0%n = p0%n-1;
486!$$$ else if ((ds.s.ds) < v_eps) then
487!$$$   p0%pt(is:p0%n-1) = p0%pt(is+1:p0%n); p0%n = p0%n-1;
488!$$$ else if (abs(dp.v.ds) < v_eps) then
489   IF (ABS(dp.v.ds) < v_eps) THEN
490      p0%pt(ic:p0%n-1) = p0%pt(ic+1:p0%n); p0%n = p0%n-1;
491      ic = MAX(ic-1,1);
492   ELSE
493      ic = ic+1;
494   ENDIF
495ENDDO
496!----------------------
497END SUBROUTINE p_red
498!=
499INTEGER FUNCTION n_sgn (v)
500   !---------------------------------------------------------------------
501   REAL (kind=rp):: v
502   !---------------------------------------------------------------------
503   IF      (v >  v_eps) THEN
504      n_sgn =  1
505   ELSE IF (v < -v_eps) THEN
506      n_sgn = -1
507   ELSE
508      n_sgn =  0
509   ENDIF
510   !--------------------
511END FUNCTION n_sgn
512!=
513FUNCTION p_srf   (pw)
514   !---------------------------------------------------------------------
515   !- calcul de la surface d'un polygone (sans croisement)
516   !---------------------------------------------------------------------
517   !- sommation des surfaces des triangles orientes composant le polygone
518   !---------------------------------------------------------------------
519   REAL (kind=rp) :: p_srf
520   TYPE(polyg) :: pw
521   !-
522   INTEGER :: j1,j2,j3,jp
523   !---------------------------------------------------------------------
524   p_srf = 0.0_rp ; j1 = 1;
525   DO jp=1,pw%n-2
526      j2 = jp+1; j3 = jp+2;
527      p_srf = p_srf+((pw%pt(j2)-pw%pt(j1)).v.(pw%pt(j3)-pw%pt(j1)))
528   ENDDO
529   p_srf = 0.5_rp * ABS(p_srf)
530   !--------------------
531END FUNCTION p_srf
532!=
533INTEGER FUNCTION p_tap   (pq,pw)
534   !---------------------------------------------------------------------
535   !- test d'appartenance d'un point a un polygone
536   !---------------------------------------------------------------------
537   !- calcul du nombre d'intersections de la demi-droite perpendiculaire
538   !- au premier cote avec les autres cotes.
539   !- si ce nombre est pair, le point appartient au polygone.
540   !---------------------------------------------------------------------
541   TYPE(c2d) :: pq
542   TYPE(polyg) :: pw
543   !-
544   INTEGER :: jp,ii,nic,issp,issc
545   REAL (kind=rp)   :: c1,c2
546   TYPE(c2d) :: vq,vs
547   !---------------------------------------------------------------------
548   nic = 0; issp = 0;
549vq  = c2d(pw%pt(1)%y-pw%pt(2)%y,pw%pt(2)%x-pw%pt(1)%x)
550DO jp=1,pw%n
551   vs   = pw%pt(MOD(jp,pw%n)+1)-pw%pt(jp)
552   CALL p_i2d   (pq,vq,pw%pt(jp),vs,c1,c2,ii)
553   IF (ii > 0) THEN
554      !----- la demi-droite coupe un cote
555      IF (c1 > v_eps) THEN
556         !------- le point est externe a la droite portant le cote
557         IF      ( (c2 > v_eps).AND.(c2 < (1.-v_eps)) ) THEN
558            !--------- la demi-droite passe par l'interieur du cote
559            nic = nic+1
560            issp = 0;
561         ELSE IF ( (c2 > -v_eps).AND.(c2 < (1.+v_eps)) ) THEN
562            !--------- la demi-droite passe par un sommet
563            issc = NINT(SIGN(1.,vq.s.vs));
564            IF ((issc*issp) < 0) THEN
565               nic = nic+1
566               issp = 0;
567            ENDIF
568            issp = issc;
569         ENDIF
570      ELSE IF (ABS(c1) < v_eps) THEN
571         !------- le point est sur la droite portant le cote
572         IF ( (c2 > -v_eps).AND.(c2 < (1.+v_eps)) ) THEN
573            !--------- le point appartient au cote
574            nic = -1
575            EXIT
576         ENDIF
577      ENDIF
578   ELSE IF (ii < 0) THEN
579      !----- la demi-droite est colineaire a un cote
580      IF ( (c2 > -v_eps).AND.(c2 < (1.+v_eps)) ) THEN
581         nic = -1
582         EXIT
583      ENDIF
584   ENDIF
585ENDDO
586!-
587p_tap = MOD(nic,2)
588!--------------------
589END FUNCTION p_tap
590!=
591!-----------------
592END MODULE u_polyg
Note: See TracBrowser for help on using the repository browser.