Changeset 2263 in lmdz_wrf


Ignore:
Timestamp:
Dec 20, 2018, 1:54:00 PM (6 years ago)
Author:
lfita
Message:

Adding final functions for the coincident polygons !!

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/module_scientific.f90

    r2262 r2263  
    3030! path_properties: Subroutine to determine the properties of a path
    3131! percentiles_R_K*D: Subroutine to compute the percentiles of a *D R_K array along given set of axis
     32! point_in_face: Function to determine if a given point is on a face of a polygon
    3233! point_inside: Function to determine if a given point is inside a polygon providing its sorted vertices
    3334! poly_has_point: Function to determine if a polygon has already a given point as one of its vertex
     
    5253! runmean_F1D: Subroutine fo computing the running mean of a given set of float 1D values
    5354! shoelace_area_polygon: Computing the area of a polygon using sholace formula
    54 ! sort_polygon: Subroutine to sort a polygon using its center as average of the coordinates
     55! sort_polygon: Subroutine to sort a polygon using its center as average of the coordinates and remove duplicates
    5556! SortR_K*: Subroutine receives an array x() r_K and sorts it into ascending order.
    5657! StatsR_K: Subroutine to provide the minmum, maximum, mean, the quadratic mean, and the standard deviation of a
     
    44134414    ! First, include that vertex which do not lay within any polygon
    44144415    DO iA=1, NvertexA
    4415       PRINT *, '  iA:', iA, ':', polyA(iA,:), point_inside(polyA(iA,:), NvertexB, polyB)
     4416      !PRINT *, '  iA:', iA, ':', polyA(iA,:), point_inside(polyA(iA,:), NvertexB, polyB)
    44164417      IF (.NOT. point_inside(polyA(iA,:), NvertexB, polyB)) THEN
    44174418        icoin = icoin + 1
     
    44214422
    44224423    DO iB=1, NvertexB
    4423       PRINT *, '  iB:', iB, ':', polyB(iB,:), point_inside(polyB(iB,:), NvertexA, polyA)
     4424      !PRINT *, '  iB:', iB, ':', polyB(iB,:), point_inside(polyB(iB,:), NvertexA, polyA)
    44244425      IF (.NOT. point_inside(polyB(iB,:), NvertexA, polyA)) THEN
    44254426        icoin = icoin + 1
     
    44484449        ! Compute areas of the four possible triangles. Introduce the coincident vertexs not included
    44494450        CALL intersectfaces(face1, face2, intersct, ptintersct)
    4450         PRINT *,iA,':',face1(1,:),';',face1(2,:), '=', iB, face2(1,:),';',face2(2,:), '<>', intersct,':', ptintersct
     4451        !PRINT *,iA,':',face1(1,:),';',face1(2,:), '=', iB, face2(1,:),';',face2(2,:), '<>', intersct,':', ptintersct
    44514452        IF (intersct == 1) THEN
    44524453          IF (.NOT.poly_has_point(icoin,coinpoly(1:icoin,:),ptintersct) ) THEN
     
    44674468  END SUBROUTINE join_polygon
    44684469
    4469   SUBROUTINE sort_polygon(Nvertex, polygon, sortpoly)
    4470   ! Subroutine to sort a polygon using its center as average of the coordinates
     4470  SUBROUTINE sort_polygon(Nvertex, polygon, sense, Nnewvertex, newpoly)
     4471  ! Subroutine to sort a polygon using its center as average of the coordinates and remove duplicates
    44714472  !    Should be used the centroid instead, but by now let do it simple
    44724473  !    https://en.wikipedia.org/wiki/Centroid
     
    44754476    IMPLICIT NONE
    44764477
    4477     INTEGER, INTENT(in)                                  :: Nvertex
     4478    INTEGER, INTENT(in)                                  :: Nvertex, sense
    44784479    REAL(r_k), DIMENSION(Nvertex,2), INTENT(in)          :: polygon
    4479     REAL(r_k), DIMENSION(Nvertex,2), INTENT(out)         :: sortpoly
     4480    INTEGER, INTENT(out)                                 :: Nnewvertex
     4481    REAL(r_k), DIMENSION(Nvertex,2), INTENT(out)         :: newpoly
    44804482
    44814483! Local
     
    44844486    REAL(r_k), DIMENSION(2)                              :: center
    44854487    REAL(r_k), DIMENSION(Nvertex)                        :: angles
     4488    REAL(r_k), DIMENSION(Nvertex,2)                      :: sortpoly
    44864489
    44874490!!!!!!! Variables
    4488 ! Nvertex: number of vetexs
     4491! Nvertex: number of vertices
    44894492! polygon: coordinates of the vertices of the polygon
    4490 ! sortpoly: sorted polygon (clockwise)
     4493! sense: sens of sorting thepolygon (1: clockwise, -1: anti-clockwise)
     4494! sortpoly: sorted polygon
     4495! Nnewvertex: number of vertices new polygon
     4496! newpoly: sorted and duplicate removed polygon
    44914497
    44924498    fname = 'sort_polygon'
     
    45064512        vang = ATAN2(polygon(j,2)-center(2), polygon(j,1)-center(1))
    45074513        IF (angles(iv) == vang) THEN
    4508           sortpoly(iv,:) = polygon(j,:)
     4514          IF (sense == -1) THEN
     4515            sortpoly(iv,:) = polygon(j,:)
     4516          ELSE
     4517            sortpoly(Nvertex-iv+1,:) = polygon(j,:)
     4518          END IF
    45094519          EXIT
    45104520        END IF
    45114521      END DO
    45124522    END DO
     4523
     4524    newpoly(1,:) = sortpoly(1,:)
     4525    j = 1
     4526    DO iv=2, Nvertex
     4527      IF (.NOT.poly_has_point(j,newpoly(1:j,:),sortpoly(iv,:)) ) THEN
     4528        j = j+1
     4529        newpoly(j,:) = sortpoly(iv,:)
     4530      END IF
     4531    END DO
     4532    Nnewvertex = j
    45134533
    45144534  END SUBROUTINE sort_polygon
     
    45694589  END FUNCTION point_inside
    45704590
     4591  LOGICAL FUNCTION point_in_face(pt, Nvertex, poly)
     4592  ! Function to determine if a given point is on a face of a polygon
     4593
     4594    IMPLICIT NONE
     4595
     4596    REAL(r_k), DIMENSION(2), INTENT(in)                  :: pt
     4597    INTEGER, INTENT(in)                                  :: Nvertex
     4598    REAL(r_k), DIMENSION(Nvertex,2), INTENT(in)          :: poly
     4599! Local
     4600    INTEGER                                              :: iv
     4601    REAL(r_k)                                            :: ix, ex, iy, ey, tmpv
     4602    REAL(r_k)                                            :: dx, dy, A, B
     4603
     4604!!!!!!! Variables
     4605! pt: point to look for
     4606! Nvertex: Number of vertices of the polygon
     4607! poly: polygon
     4608    fname = 'point_in_face'
     4609
     4610    point_in_face = .FALSE.
     4611    DO iv=1, Nvertex
     4612      IF (iv < Nvertex) THEN
     4613        ix = poly(iv,1)
     4614        ex = poly(iv+1,1)
     4615        iy = poly(iv,2)
     4616        ey = poly(iv+1,2)
     4617      ELSE
     4618        ix = poly(iv,1)
     4619        ex = poly(1,1)
     4620        iy = poly(iv,2)
     4621        ey = poly(1,2)
     4622      END IF   
     4623      dx = ex - ix
     4624      dy = ey - iy
     4625
     4626      IF (dx == zeroRK) THEN
     4627        IF (pt(1) == ix) THEN
     4628          IF ( (iy < ey) .AND. (pt(2) >= iy) .AND. pt(2) <= ey) THEN
     4629            point_in_face = .TRUE.
     4630            EXIT
     4631          ELSE IF ( (iy > ey) .AND. (pt(2) >= ey) .AND. pt(2) <= iy) THEN
     4632            point_in_face = .TRUE.
     4633            EXIT
     4634          END IF
     4635        END IF
     4636      ELSE
     4637        IF (dy == zeroRK) THEN
     4638          IF (pt(2) == iy) THEN
     4639            IF ((ix < ex) .AND. (pt(1) >= ix) .AND. pt(1) <= ex) THEN
     4640              point_in_face = .TRUE.
     4641              EXIT           
     4642            ELSE IF ((ix > ex) .AND. (pt(1) >= ex) .AND. pt(1) <= ix) THEN
     4643              point_in_face = .TRUE.
     4644              EXIT
     4645            END IF
     4646          END IF
     4647        ELSE
     4648          A = iy
     4649          B = (ey-iy)/(ex-ix)
     4650          IF (A+B*(pt(1)-ix) == pt(2)) THEN
     4651            point_in_face = .TRUE.
     4652            EXIT
     4653          END IF
     4654        END IF
     4655      END IF
     4656    END DO
     4657
     4658  END FUNCTION point_in_face
     4659
     4660  SUBROUTINE coincident_polygon(NvertexA, NvertexB, NvertexAB, polyA, polyB, Ncoinvertex, coinpoly)
     4661  ! Subroutine to provide the intersection polygon between two polygons
     4662  ! AFTER: http://www.cap-lore.com/MathPhys/IP/ and http://www.cap-lore.com/MathPhys/IP/IL.html
     4663
     4664    IMPLICIT NONE
     4665
     4666    INTEGER, INTENT(in)                                  :: NvertexA, NvertexB, NvertexAB
     4667    REAL(r_k), DIMENSION(NvertexA,2), INTENT(in)         :: polyA
     4668    REAL(r_k), DIMENSION(NvertexB,2), INTENT(in)         :: polyB
     4669    INTEGER, INTENT(out)                                 :: Ncoinvertex
     4670    REAL(r_k), DIMENSION(NvertexAB,2), INTENT(out)       :: coinpoly
     4671
     4672! Local
     4673    INTEGER                                              :: iA, iB, icoin, ii
     4674    REAL(r_k), DIMENSION(2,2)                            :: face1, face2
     4675    INTEGER                                              :: intersct
     4676    REAL(r_k), DIMENSION(2)                              :: ptintersct
     4677
     4678!!!!!!! variables
     4679! NvertexA: number of vertexs polygon A
     4680! NvertexB: number of vertexs polygon B
     4681! polyA: pairs of coordinates for the polygon A (clockwise)
     4682! polyB: pairs of coordinates for the polygon B (clockwise)
     4683! Ncoinvertex: number of vertexes for the coincident polygon
     4684! coinpoly: pairs of coordinates for the coincident polygon (clockwise)
     4685
     4686    fname = 'coincident_polygon'
     4687
     4688    icoin = 0
     4689    coinpoly = 0.
     4690    ! First, include that vertex which lay within any polygon
     4691    DO iA=1, NvertexA
     4692      IF (point_inside(polyA(iA,:), NvertexB, polyB)) THEN
     4693        icoin = icoin + 1
     4694        coinpoly(icoin,:) = polyA(iA,:)
     4695      END IF
     4696      IF (point_in_face(polyA(iA,:), NvertexB, polyB)) THEN
     4697        icoin = icoin + 1
     4698        coinpoly(icoin,:) = polyA(iA,:)
     4699      END IF
     4700    END DO
     4701
     4702    DO iB=1, NvertexB
     4703      IF (point_inside(polyB(iB,:), NvertexA, polyA)) THEN
     4704        icoin = icoin + 1
     4705        coinpoly(icoin,:) = polyB(iB,:)
     4706      END IF
     4707      IF (point_in_face(polyB(iB,:), NvertexA, polyA)) THEN
     4708        icoin = icoin + 1
     4709        coinpoly(icoin,:) = polyB(iB,:)
     4710      END IF
     4711    END DO
     4712
     4713    ! Look interesections
     4714    DO iA=1, NvertexA
     4715      ! Getting couple of vertexs from polyA and polyB
     4716      IF (iA /= NvertexA) THEN
     4717        face1(1,:) = polyA(iA,:)
     4718        face1(2,:) = polyA(iA+1,:)
     4719      ELSE
     4720        face1(1,:) = polyA(iA,:)
     4721        face1(2,:) = polyA(1,:)
     4722      END IF
     4723      DO iB=1, NvertexB
     4724        IF (iB /= NvertexB) THEN
     4725          face2(1,:) = polyB(iB,:)
     4726          face2(2,:) = polyB(iB+1,:)
     4727        ELSE
     4728          face2(1,:) = polyB(iB,:)
     4729          face2(2,:) = polyB(1,:)
     4730        END IF
     4731       
     4732        ! Compute areas of the four possible triangles. Introduce the coincident vertexs not included
     4733        CALL intersectfaces(face1, face2, intersct, ptintersct)
     4734        !PRINT *,iA,':',face1(1,:),';',face1(2,:), '=', iB, face2(1,:),';',face2(2,:), '<>', intersct,':', ptintersct
     4735        IF ((intersct /= 0) .AND. (.NOT.poly_has_point(icoin,coinpoly(1:icoin,:),ptintersct)) ) THEN
     4736          icoin = icoin + 1
     4737          coinpoly(icoin,:) = ptintersct
     4738        END IF
     4739
     4740      END DO
     4741    END DO
     4742    Ncoinvertex = icoin
     4743
     4744  END SUBROUTINE coincident_polygon
     4745
    45714746END MODULE module_scientific
Note: See TracChangeset for help on using the changeset viewer.