SUBROUTINE DTGFND(X,Y, TRIANG,NT,Q,INDTRI,TRI,S,MODE) c Copyright (c) 1996 California Institute of Technology, Pasadena, CA. c ALL RIGHTS RESERVED. c Based on Government Sponsored Research NAS7-03001. C>> 1997-06-15 DTGFND CLL In args: Removed NP. Changed meaning of MODE. c>> 1996-03-30 DTGFND Krogh Removed Fortran 90 comments. C>> 1996-02-02 DTGFND CLL C>> 1995-09-26 DTGFND CLL Editing for inclusion into MATH77. C c C.L.LAWSON, JPL, 1976 DEC 3 c LOOK UP POINT Q IN TRIANGULAR GRID. c c X(1:NP), Y(1:NP) [in] (x,y) coordinates of vertices of the c triangular grid. c c {NP is the number of vertices in the triangular grid, but is c not explicitly used in this subroutine.} c c TRIANG(1:6*NT) [in] Array of integer pointers defining the c connectivity of the triangular grid. c c NT [in] No. of triangles in the triangular grid. c c Q(1:2) [in] The (x,y) coordinates of the point for which this c subr will attempt to find an enclosing triangle. c c INDTRI [in] DESIGNATES TRIANGLE AT WHICH SEARCH WILL BEGIN. c ON RETURN INDTRI IS THE INDEX OF THE LAST TRIANGLE c TESTED. THIS IS THE TRIANGLE CONTAINING Q IF MODE=0. c IF MODE = 1, 2, or 3, THIS IS A BOUNDARY TRIANGLE AND Q c IS OUTSIDE A BOUNDARY EDGE OF THIS TRIANGLE. C c TRI(1:7) [out] INTEGER ARRAY OF POINTERS ASSOCIATED c WITH TRIANGLE INDTRI. c c S(1:3, 1:3) [out] If MODE=0 on return, S(,) CONTAINS c S(:,1) = UNNORMALIZED BARYCENTRIC COORDINATES OF Q. c S(:,2) = X COORDINATES OF EDGE VECTORS. c S(:,3) = Y COORDINATES OF EDGE VECTORS. C c MODE [out] c = 0 MEANS OK. Q IS INTERIOR OR ALMOST SO. c = 1, 2, or 3. Means Q is exterior by more than the built-in c tolerance. The value of MODE identifies the edge of the c triangle relative to which Q is outside. TRI(MODE) will be c zero, indicating a boundary edge. Q is outside this edge. c The vertices at the ends of this edge, in counterclockwise c order are TRI(3+MODE) and TRI(4+MODE). c c = -1 BAD. SUBR IS CYCLING IN THE SEARCH. THIS SHOULD NEVER c HAPPEN. C c ------------------------------------------------------------------ c Details of the contents of TRI(1:7) and S(1:3, 1:3). c c For descriptive convenience we regard the subscript of P() and the c 1st subsubscript of S(,) as always being reduced modulo 3 to 1, 2, c or 3. Also for convenience we shall write P(i) to mean the vertex c indexed by P(i). c c TRI() contains integer pointers defining the triangle indexed by c INDTRI. The indices of the vertices of this triangle, in counter- c clockwise order are P(1), P(2), and P(3) which may be obtained as c P(i) = TRI(3+i) for i = 1, 2, and 3. TRI(7) contains the same c value as TRI(4). The triangle adjacent to this triangle across c the edge from P(3+i) to P(4+i) is indexed by TRI(i) for i = 1, 2, c and 3. If there is no adjacent triangle across this edge then c TRI(i) = 0. c c The unnormalized barycentric coordinate that is zero along the edge c from P(i) to P(i+1) and has a positive value at P(i+2) is stored in c S(i,1). The (x,y) coordinates of the vector from P(i) to P(i+1) are c stored in (S(i,2), S(i,3)). c ------------------------------------------------------------------ c--D replaces "?": ?TGFND, ?TGGET c ------------------------------------------------------------------ integer icount, indtri, iskip, j, j1, j2, j2save, MODE, NT integer TRI(7), TRIANG(1:*) double precision p1, p2, Q(2), S(3,3), X(*), Y(*) c ------------------------------------------------------------------ IF( INDTRI .LE. 0 .OR. INDTRI .GT. NT) INDTRI=1 MODE = -1 ISKIP = 0 J2SAVE = 0 DO 50 ICOUNT = 1, NT CALL DTGGET(INDTRI,TRI,TRIANG) TRI(7)=TRI(4) DO 10 J=1,3 J1= TRI(J+3) IF ( J1 .EQ. J2SAVE) THEN ISKIP=J ELSE J2 = TRI(J+4) S(J,2) = X(J2)-X(J1) P2 = S(J,2) * (Q(2)-Y(J1)) S(J,3) = Y(J2)-Y(J1) P1 = S(J,3) * (Q(1)-X(J1)) S(J,1) = -P1+P2 C IF (S(J,1) .LT. -1.0D-4*(ABS(P1)+ABS(P2))) THEN C c Q IS OUTSIDE TRIANGLE INDTRI BY MORE THAN c TOLERANCE. MOVE TO NEIGHBORING TRIANGLE IF c THERE IS ONE. C IF (TRI(J) .NE. 0) THEN J2SAVE = J2 INDTRI = TRI(J) go to 40 ELSE MODE = J go to 80 END IF END IF END IF 10 continue c Q IS INSIDE OR ALMOST INSIDE c THIS TRIANGLE MODE = 0 go to 90 40 continue 50 continue 80 continue 90 continue c COMPUTE SKIPPED INFO FOR USE IN c INTERPOLATION SUBR. IF (ISKIP .NE. 0) THEN J1=TRI(ISKIP+3) J2=TRI(ISKIP+4) S(ISKIP,2)= X(J2)-X(J1) S(ISKIP,3)= Y(J2)-Y(J1) S(ISKIP,1)= -S(ISKIP,3)*(Q(1)-X(J1)) * +S(ISKIP,2)*(Q(2)-Y(J1)) END IF RETURN END