Changeset 2263 in lmdz_wrf
- Timestamp:
- Dec 20, 2018, 1:54:00 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/module_scientific.f90
r2262 r2263 30 30 ! path_properties: Subroutine to determine the properties of a path 31 31 ! 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 32 33 ! point_inside: Function to determine if a given point is inside a polygon providing its sorted vertices 33 34 ! poly_has_point: Function to determine if a polygon has already a given point as one of its vertex … … 52 53 ! runmean_F1D: Subroutine fo computing the running mean of a given set of float 1D values 53 54 ! 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 55 56 ! SortR_K*: Subroutine receives an array x() r_K and sorts it into ascending order. 56 57 ! StatsR_K: Subroutine to provide the minmum, maximum, mean, the quadratic mean, and the standard deviation of a … … 4413 4414 ! First, include that vertex which do not lay within any polygon 4414 4415 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) 4416 4417 IF (.NOT. point_inside(polyA(iA,:), NvertexB, polyB)) THEN 4417 4418 icoin = icoin + 1 … … 4421 4422 4422 4423 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) 4424 4425 IF (.NOT. point_inside(polyB(iB,:), NvertexA, polyA)) THEN 4425 4426 icoin = icoin + 1 … … 4448 4449 ! Compute areas of the four possible triangles. Introduce the coincident vertexs not included 4449 4450 CALL intersectfaces(face1, face2, intersct, ptintersct) 4450 PRINT *,iA,':',face1(1,:),';',face1(2,:), '=', iB, face2(1,:),';',face2(2,:), '<>', intersct,':', ptintersct4451 !PRINT *,iA,':',face1(1,:),';',face1(2,:), '=', iB, face2(1,:),';',face2(2,:), '<>', intersct,':', ptintersct 4451 4452 IF (intersct == 1) THEN 4452 4453 IF (.NOT.poly_has_point(icoin,coinpoly(1:icoin,:),ptintersct) ) THEN … … 4467 4468 END SUBROUTINE join_polygon 4468 4469 4469 SUBROUTINE sort_polygon(Nvertex, polygon, s ortpoly)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 4471 4472 ! Should be used the centroid instead, but by now let do it simple 4472 4473 ! https://en.wikipedia.org/wiki/Centroid … … 4475 4476 IMPLICIT NONE 4476 4477 4477 INTEGER, INTENT(in) :: Nvertex 4478 INTEGER, INTENT(in) :: Nvertex, sense 4478 4479 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 4480 4482 4481 4483 ! Local … … 4484 4486 REAL(r_k), DIMENSION(2) :: center 4485 4487 REAL(r_k), DIMENSION(Nvertex) :: angles 4488 REAL(r_k), DIMENSION(Nvertex,2) :: sortpoly 4486 4489 4487 4490 !!!!!!! Variables 4488 ! Nvertex: number of ve texs4491 ! Nvertex: number of vertices 4489 4492 ! 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 4491 4497 4492 4498 fname = 'sort_polygon' … … 4506 4512 vang = ATAN2(polygon(j,2)-center(2), polygon(j,1)-center(1)) 4507 4513 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 4509 4519 EXIT 4510 4520 END IF 4511 4521 END DO 4512 4522 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 4513 4533 4514 4534 END SUBROUTINE sort_polygon … … 4569 4589 END FUNCTION point_inside 4570 4590 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 4571 4746 END MODULE module_scientific
Note: See TracChangeset
for help on using the changeset viewer.