MODFLOW 6  version 6.6.0.dev0
USGS Modular Hydrologic Model
geomutilmodule Module Reference

Functions/Subroutines

logical function, public between (x, a, b)
 Check if a value is between two other values (inclusive). More...
 
logical function, public point_in_polygon (x, y, poly)
 Check if a point is within a polygon. More...
 
integer(i4b) function, public get_node (ilay, irow, icol, nlay, nrow, ncol)
 Get node number, given layer, row, and column indices for a structured grid. If any argument is invalid return -1. More...
 
subroutine, public get_ijk (nodenumber, nrow, ncol, nlay, irow, icol, ilay)
 Get row, column and layer indices from node number and grid dimensions. If nodenumber is invalid, irow, icol, and ilay are -1. More...
 
subroutine, public get_jk (nodenumber, ncpl, nlay, icpl, ilay)
 Get layer index and within-layer node index from node number and grid dimensions. If nodenumber is invalid, icpl and ilay are -1. More...
 
pure real(dp) function, dimension(2), public skew (v, s, invert)
 Skew a 2D vector along the x-axis. More...
 
subroutine, public transform (xin, yin, zin, xout, yout, zout, xorigin, yorigin, zorigin, sinrot, cosrot, invert)
 Apply a 3D translation and optional 2D rotation to coordinates. More...
 
subroutine, public compose (xorigin, yorigin, zorigin, sinrot, cosrot, xorigin_new, yorigin_new, zorigin_new, sinrot_new, cosrot_new, invert)
 Apply a 3D translation and 2D rotation to an existing transformation. More...
 
subroutine defaults (xorigin, yorigin, zorigin, sinrot, cosrot, invert, translate, rotate, xorigin_opt, yorigin_opt, zorigin_opt, sinrot_opt, cosrot_opt, invert_opt)
 Process arguments and set defaults. Internal use only. More...
 
real(dp) function, public area (xv, yv, cw)
 Calculate polygon area, with vertices given in CW or CCW order. More...
 
subroutine, public shared_face (iverts1, iverts2, iface)
 Find the lateral face shared by two cells. More...
 
subroutine, public clamp_bary (alpha, beta, gamma, pad)
 Clamp barycentric coordinates to the interior of a triangle, with optional padding some minimum distance from any face. More...
 

Function/Subroutine Documentation

◆ area()

real(dp) function, public geomutilmodule::area ( real(dp), dimension(:), intent(in)  xv,
real(dp), dimension(:), intent(in)  yv,
logical(lgp), intent(in), optional  cw 
)

Definition at line 369 of file GeomUtil.f90.

370  ! dummy
371  real(DP), dimension(:), intent(in) :: xv
372  real(DP), dimension(:), intent(in) :: yv
373  logical(LGP), intent(in), optional :: cw
374  ! result
375  real(DP) :: a
376  integer(I4B) :: s
377 
378  if (present(cw)) then
379  if (cw) then
380  s = 1
381  else
382  s = -1
383  end if
384  else
385  s = 1
386  end if
387 
388  a = -dhalf * sum(xv(:) * cshift(yv(:), s) - cshift(xv(:), s) * yv(:))
389 
Here is the caller graph for this function:

◆ between()

logical function, public geomutilmodule::between ( real(dp), intent(in)  x,
real(dp), intent(in)  a,
real(dp), intent(in)  b 
)

Definition at line 16 of file GeomUtil.f90.

17  real(DP), intent(in) :: x, a, b
18  between = ((x >= a .and. x <= b) .or. (x <= a .and. x >= b))
Here is the caller graph for this function:

◆ clamp_bary()

subroutine, public geomutilmodule::clamp_bary ( real(dp), intent(inout)  alpha,
real(dp), intent(inout)  beta,
real(dp), intent(out)  gamma,
real(dp), intent(in), optional  pad 
)

This routine requires 0 <= tol <= 1/3 and 1 = alpha + beta + gamma.

Definition at line 465 of file GeomUtil.f90.

466  ! dummy
467  real(DP), intent(inout) :: alpha
468  real(DP), intent(inout) :: beta
469  real(DP), intent(out) :: gamma
470  real(DP), intent(in), optional :: pad
471  ! local
472  real(DP) :: lolimit
473  real(DP) :: hilimit
474  real(DP) :: delta
475  real(DP) :: lpad
476 
477  if (present(pad)) then
478  lpad = pad
479  if (pad < dzero .or. pad > donethird) &
480  call pstop(1, "pad must be between 0 and 1/3, inclusive")
481  else
482  lpad = dzero
483  end if
484 
485  gamma = done - alpha - beta
486  lolimit = lpad
487  hilimit = done - dtwo * lpad
488  ! Check alpha coordinate against lower limit
489  if (alpha < lolimit) then
490  ! Alpha is too low, so nudge alpha to lower limit; this is a move
491  ! parallel to the "alpha axis," which also changes gamma
492  alpha = lolimit
493  gamma = done - alpha - beta
494  ! Check beta coordinate against lower limit (which in this
495  ! case is equivalent to checking gamma coordinate against
496  ! upper limit)
497  if (beta < lolimit) then
498  ! Beta is too low (gamma is too high), so nudge beta to lower limit;
499  ! this is a move parallel to the "beta axis," which also changes gamma
500  beta = lolimit
501  gamma = hilimit
502  ! Check beta coordinate against upper limit (which in this
503  ! case is equivalent to checking gamma coordinate against
504  ! lower limit)
505  else if (beta > hilimit) then
506  ! Beta is too high (gamma is too low), so nudge beta to lower limit;
507  ! this is a move parallel to the "beta axis," which also changes gamma
508  beta = hilimit
509  gamma = lolimit
510  end if
511  end if
512  ! Check beta coordinate against lower limit. (If alpha coordinate
513  ! was nudged to lower limit, beta and gamma coordinates have also
514  ! been adjusted as necessary to place particle within subcell, and
515  ! subsequent checks on beta and gamma will evaluate to false, and
516  ! no further adjustments will be made.)
517  if (beta < lolimit) then
518  ! Beta is too low, so nudge beta to lower limit; this is a move
519  ! parallel to the "beta axis," which also changes gamma
520  beta = lolimit
521  gamma = done - alpha - beta
522  ! Check alpha coordinate against lower limit (which in this
523  ! case is equivalent to checking gamma coordinate against
524  ! upper limit)
525  if (alpha < lolimit) then
526  ! Alpha is too low (gamma is too high), so nudge alpha to lower limit;
527  ! this is a move parallel to the "alpha axis," which also changes gamma
528  alpha = lolimit
529  gamma = hilimit
530  ! Check alpha coordinate against upper limit (which in this
531  ! case is equivalent to checking gamma coordinate against
532  ! lower limit)
533  else if (alpha > hilimit) then
534  ! Alpha is too high (gamma is too low), so nudge alpha to lower limit;
535  ! this is a move parallel to the "alpha axis," which also changes gamma
536  alpha = hilimit
537  gamma = lolimit
538  end if
539  end if
540  ! Check gamma coordinate against lower limit.(If alpha and/or beta
541  ! coordinate was nudged to lower limit, gamma coordinate has also
542  ! been adjusted as necessary to place particle within subcell, and
543  ! subsequent check on gamma will evaluate to false, and no further
544  ! adjustment will be made.)
545  if (gamma < lolimit) then
546  ! Gamma is too low, so nudge gamma to lower limit; this is a move
547  ! parallel to the "gamma axis," which also changes alpha and beta
548  delta = dhalf * (lolimit - gamma)
549  gamma = lpad
550  alpha = alpha - delta
551  beta = beta - delta
552  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ compose()

subroutine, public geomutilmodule::compose ( real(dp)  xorigin,
real(dp)  yorigin,
real(dp)  zorigin,
real(dp)  sinrot,
real(dp)  cosrot,
real(dp), optional  xorigin_new,
real(dp), optional  yorigin_new,
real(dp), optional  zorigin_new,
real(dp), optional  sinrot_new,
real(dp), optional  cosrot_new,
logical(lgp), optional  invert 
)
Parameters
zoriginorigin coordinates (original)
cosrotsine and cosine of rotation (original)
zorigin_neworigin coordinates (new)
cosrot_newsine and cosine of rotation (new)
invertwhether to invert

Definition at line 238 of file GeomUtil.f90.

243  ! -- dummy
244  real(DP) :: xorigin, yorigin, zorigin !< origin coordinates (original)
245  real(DP) :: sinrot, cosrot !< sine and cosine of rotation (original)
246  real(DP), optional :: xorigin_new, yorigin_new, zorigin_new !< origin coordinates (new)
247  real(DP), optional :: sinrot_new, cosrot_new !< sine and cosine of rotation (new)
248  logical(LGP), optional :: invert !< whether to invert
249  ! -- local
250  logical(LGP) :: ltranslate, lrotate, linvert
251  real(DP) :: xorigin_add, yorigin_add, zorigin_add
252  real(DP) :: sinrot_add, cosrot_add
253  real(DP) :: x0, y0, z0, s0, c0
254 
255  ! -- Process option arguments and set defaults and flags
256  call defaults(xorigin_add, yorigin_add, zorigin_add, &
257  sinrot_add, cosrot_add, linvert, &
258  ltranslate, lrotate, &
259  xorigin_new, yorigin_new, zorigin_new, &
260  sinrot_new, cosrot_new, invert)
261 
262  ! -- Copy existing transformation into working copy
263  x0 = xorigin
264  y0 = yorigin
265  z0 = zorigin
266  s0 = sinrot
267  c0 = cosrot
268 
269  ! -- Modify transformation
270  if (.not. linvert) then
271  ! -- Apply additional transformation to existing transformation
272  if (ltranslate) then
273  ! -- Calculate modified origin, XOrigin + R^T XOrigin_add, where
274  ! -- XOrigin and XOrigin_add are the existing and additional origin
275  ! -- vectors, respectively, and R^T is the transpose of the existing
276  ! -- rotation matrix
277  call transform(xorigin_add, yorigin_add, zorigin_add, &
278  xorigin, yorigin, zorigin, &
279  x0, y0, z0, s0, c0, .true.)
280  end if
281  if (lrotate) then
282  ! -- Calculate modified rotation matrix (represented by sinrot
283  ! -- and cosrot) as R_add R, where R and R_add are the existing
284  ! -- and additional rotation matrices, respectively
285  sinrot = cosrot_add * s0 + sinrot_add * c0
286  cosrot = cosrot_add * c0 - sinrot_add * s0
287  end if
288  else
289  ! -- Apply inverse of additional transformation to existing transformation
290  !
291  ! -- Calculate modified origin, R^T (XOrigin + R_add XOrigin_add), where
292  ! -- XOrigin and XOrigin_add are the existing and additional origin
293  ! -- vectors, respectively, R^T is the transpose of the existing rotation
294  ! -- matrix, and R_add is the additional rotation matrix
295  if (ltranslate) then
296  call transform(-xorigin_add, -yorigin_add, zorigin_add, &
297  x0, y0, z0, xorigin, yorigin, zorigin, &
298  -sinrot_add, cosrot_add, .true.)
299  end if
300  xorigin = c0 * x0 - s0 * y0
301  yorigin = s0 * x0 + c0 * y0
302  zorigin = z0
303  if (lrotate) then
304  ! -- Calculate modified rotation matrix (represented by sinrot
305  ! -- and cosrot) as R_add^T R, where R and R_add^T are the existing
306  ! -- rotation matrix and the transpose of the additional rotation
307  ! -- matrix, respectively
308  sinrot = cosrot_add * s0 - sinrot_add * c0
309  cosrot = cosrot_add * c0 + sinrot_add * s0
310  end if
311  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ defaults()

subroutine geomutilmodule::defaults ( real(dp)  xorigin,
real(dp)  yorigin,
real(dp)  zorigin,
real(dp)  sinrot,
real(dp)  cosrot,
logical(lgp)  invert,
logical(lgp)  translate,
logical(lgp)  rotate,
real(dp), optional  xorigin_opt,
real(dp), optional  yorigin_opt,
real(dp), optional  zorigin_opt,
real(dp), optional  sinrot_opt,
real(dp), optional  cosrot_opt,
logical(lgp), optional  invert_opt 
)
private

Definition at line 315 of file GeomUtil.f90.

320  ! -- dummy
321  real(DP) :: xorigin, yorigin, zorigin
322  real(DP) :: sinrot, cosrot
323  logical(LGP) :: invert, translate, rotate
324  real(DP), optional :: xorigin_opt, yorigin_opt, zorigin_opt
325  real(DP), optional :: sinrot_opt, cosrot_opt
326  logical(LGP), optional :: invert_opt
327 
328  translate = .false.
329  xorigin = dzero
330  if (present(xorigin_opt)) then
331  xorigin = xorigin_opt
332  translate = .true.
333  end if
334  yorigin = dzero
335  if (present(yorigin_opt)) then
336  yorigin = yorigin_opt
337  translate = .true.
338  end if
339  zorigin = dzero
340  if (present(zorigin_opt)) then
341  zorigin = zorigin_opt
342  translate = .true.
343  end if
344  rotate = .false.
345  sinrot = dzero
346  cosrot = done
347  if (present(sinrot_opt)) then
348  sinrot = sinrot_opt
349  if (present(cosrot_opt)) then
350  cosrot = cosrot_opt
351  else
352  ! -- If sinrot_opt is specified but cosrot_opt is not,
353  ! -- default to corresponding non-negative cosrot_add
354  cosrot = dsqrt(done - sinrot * sinrot)
355  end if
356  rotate = .true.
357  else if (present(cosrot_opt)) then
358  cosrot = cosrot_opt
359  ! -- cosrot_opt is specified but sinrot_opt is not, so
360  ! -- default to corresponding non-negative sinrot_add
361  sinrot = dsqrt(done - cosrot * cosrot)
362  rotate = .true.
363  end if
364  invert = .false.
365  if (present(invert_opt)) invert = invert_opt
Here is the caller graph for this function:

◆ get_ijk()

subroutine, public geomutilmodule::get_ijk ( integer(i4b), intent(in)  nodenumber,
integer(i4b), intent(in)  nrow,
integer(i4b), intent(in)  ncol,
integer(i4b), intent(in)  nlay,
integer(i4b), intent(out)  irow,
integer(i4b), intent(out)  icol,
integer(i4b), intent(out)  ilay 
)

Definition at line 99 of file GeomUtil.f90.

100  ! -- dummy variables
101  integer(I4B), intent(in) :: nodenumber
102  integer(I4B), intent(in) :: nrow
103  integer(I4B), intent(in) :: ncol
104  integer(I4B), intent(in) :: nlay
105  integer(I4B), intent(out) :: irow
106  integer(I4B), intent(out) :: icol
107  integer(I4B), intent(out) :: ilay
108  ! -- local variables
109  integer(I4B) :: nodes
110  integer(I4B) :: ij
111 
112  nodes = nlay * nrow * ncol
113  if (nodenumber < 1 .or. nodenumber > nodes) then
114  irow = -1
115  icol = -1
116  ilay = -1
117  else
118  ilay = (nodenumber - 1) / (ncol * nrow) + 1
119  ij = nodenumber - (ilay - 1) * ncol * nrow
120  irow = (ij - 1) / ncol + 1
121  icol = ij - (irow - 1) * ncol
122  end if
Here is the caller graph for this function:

◆ get_jk()

subroutine, public geomutilmodule::get_jk ( integer(i4b), intent(in)  nodenumber,
integer(i4b), intent(in)  ncpl,
integer(i4b), intent(in)  nlay,
integer(i4b), intent(out)  icpl,
integer(i4b), intent(out)  ilay 
)

Definition at line 127 of file GeomUtil.f90.

128  ! -- dummy variables
129  integer(I4B), intent(in) :: nodenumber
130  integer(I4B), intent(in) :: ncpl
131  integer(I4B), intent(in) :: nlay
132  integer(I4B), intent(out) :: icpl
133  integer(I4B), intent(out) :: ilay
134  ! -- local variables
135  integer(I4B) :: nodes
136 
137  nodes = ncpl * nlay
138  if (nodenumber < 1 .or. nodenumber > nodes) then
139  icpl = -1
140  ilay = -1
141  else
142  ilay = (nodenumber - 1) / ncpl + 1
143  icpl = nodenumber - (ilay - 1) * ncpl
144  end if
Here is the caller graph for this function:

◆ get_node()

integer(i4b) function, public geomutilmodule::get_node ( integer(i4b), intent(in)  ilay,
integer(i4b), intent(in)  irow,
integer(i4b), intent(in)  icol,
integer(i4b), intent(in)  nlay,
integer(i4b), intent(in)  nrow,
integer(i4b), intent(in)  ncol 
)

Definition at line 82 of file GeomUtil.f90.

83  integer(I4B), intent(in) :: ilay, irow, icol, nlay, nrow, ncol
84  integer(I4B) :: get_node
85 
86  if (nlay > 0 .and. nrow > 0 .and. ncol > 0 .and. &
87  ilay > 0 .and. ilay <= nlay .and. &
88  irow > 0 .and. irow <= nrow .and. &
89  icol > 0 .and. icol <= ncol) then
90  get_node = &
91  icol + ncol * (irow - 1) + (ilay - 1) * nrow * ncol
92  else
93  get_node = -1
94  end if
Here is the caller graph for this function:

◆ point_in_polygon()

logical function, public geomutilmodule::point_in_polygon ( real(dp), intent(in)  x,
real(dp), intent(in)  y,
real(dp), dimension(:, :), intent(in), allocatable  poly 
)

Vertices and edge points are considered in the polygon. Adapted from https://stackoverflow.com/a/63436180/6514033,

Parameters
[in]xx point coordinate
[in]yy point coordinate
[in]polypolygon vertices (column-major indexing)

Definition at line 26 of file GeomUtil.f90.

27  ! dummy
28  real(DP), intent(in) :: x !< x point coordinate
29  real(DP), intent(in) :: y !< y point coordinate
30  real(DP), allocatable, intent(in) :: poly(:, :) !< polygon vertices (column-major indexing)
31  ! local
32  integer(I4B) :: i, ii, num_verts
33  real(DP) :: xa, xb, ya, yb, c = 0.0_dp
34 
35  point_in_polygon = .false.
36  num_verts = size(poly, 2)
37  xa = poly(1, num_verts)
38  ya = poly(2, num_verts)
39 
40  do i = 0, num_verts - 1
41  ii = mod(i, num_verts) + 1
42  xb = poly(1, ii)
43  yb = poly(2, ii)
44 
45  if ((x == xa .and. y == ya) .or. &
46  (x == xb .and. y == yb)) then
47  ! on vertex
48  point_in_polygon = .true.
49  exit
50  else if (ya == yb .and. &
51  y == ya .and. &
52  between(x, xa, xb)) then
53  ! on horizontal edge
54  point_in_polygon = .true.
55  exit
56  else if (between(y, ya, yb)) then
57  if ((y == ya .and. yb >= ya) .or. &
58  (y == yb .and. ya >= yb)) then
59  xa = xb
60  ya = yb
61  cycle
62  end if
63  ! cross product
64  c = (xa - x) * (yb - y) - (xb - x) * (ya - y)
65  if (c == 0.0_dp) then
66  ! on edge
67  point_in_polygon = .true.
68  exit
69  else if ((ya < yb) .eqv. (c > 0)) then
70  ! ray intersection
71  point_in_polygon = .not. point_in_polygon
72  end if
73  end if
74 
75  xa = xb
76  ya = yb
77  end do
Here is the call graph for this function:
Here is the caller graph for this function:

◆ shared_face()

subroutine, public geomutilmodule::shared_face ( integer(i4b), dimension(:)  iverts1,
integer(i4b), dimension(:)  iverts2,
integer(i4b), intent(out)  iface 
)

Find the lateral (x-y plane) face shared by the given cells. The iface return argument will be 0 if they share no such face, otherwise the index of the shared face in cell 1's vertex array, where face N connects vertex N to vertex N + 1 going clockwise.

Note: assumes the cells are convex and share at most 2 vertices and that both vertex arrays are oriented clockwise.

Definition at line 402 of file GeomUtil.f90.

403  integer(I4B), dimension(:) :: iverts1
404  integer(I4B), dimension(:) :: iverts2
405  integer(I4B), intent(out) :: iface
406  integer(I4B) :: nv1
407  integer(I4B) :: nv2
408  integer(I4B) :: il1, iil1
409  integer(I4B) :: il2, iil2
410  logical(LGP) :: found
411  logical(LGP) :: wrapped
412 
413  iface = 0
414  found = .false.
415  nv1 = size(iverts1)
416  nv2 = size(iverts2)
417  wrapped = iverts1(1) == iverts1(nv1)
418 
419  ! Find a vertex shared by the cells, then check the adjacent faces.
420  ! If the cells share a face, it must be one of these. When looking
421  ! forward in the 1st cell's vertices, look backwards in the 2nd's,
422  ! and vice versa, since a clockwise face in cell 1 must correspond
423  ! to a counter-clockwise face in cell 2.
424  outerloop: do il1 = 1, nv1 - 1
425  do il2 = 1, nv2 - 1
426  if (iverts1(il1) == iverts2(il2)) then
427 
428  iil1 = il1 + 1
429  if (il2 == 1) then
430  iil2 = nv2
431  if (wrapped) iil2 = iil2 - 1
432  else
433  iil2 = il2 - 1
434  end if
435  if (iverts1(iil1) == iverts2(iil2)) then
436  found = .true.
437  iface = il1
438  exit outerloop
439  end if
440 
441  iil2 = il2 + 1
442  if (il1 == 1) then
443  iil1 = nv1
444  if (wrapped) iil1 = iil1 - 1
445  else
446  iil1 = il1 - 1
447  end if
448  if (iverts1(iil1) == iverts2(iil2)) then
449  found = .true.
450  iface = iil1
451  exit outerloop
452  end if
453 
454  end if
455  end do
456  if (found) exit
457  end do outerloop
Here is the caller graph for this function:

◆ skew()

pure real(dp) function, dimension(2), public geomutilmodule::skew ( real(dp), dimension(2), intent(in)  v,
real(dp), dimension(3), intent(in)  s,
logical(lgp), intent(in), optional  invert 
)
Parameters
[in]vvector
[in]sskew matrix entries (top left, top right, bottom right)

Definition at line 148 of file GeomUtil.f90.

149  ! -- dummy
150  real(DP), intent(in) :: v(2) !< vector
151  real(DP), intent(in) :: s(3) !< skew matrix entries (top left, top right, bottom right)
152  logical(LGP), intent(in), optional :: invert
153  real(DP) :: res(2)
154  ! -- local
155  logical(LGP) :: linvert
156  real(DP) :: sxx, sxy, syy
157 
158  ! -- process optional arguments
159  if (present(invert)) then
160  linvert = invert
161  else
162  linvert = .false.
163  end if
164 
165  sxx = s(1)
166  sxy = s(2)
167  syy = s(3)
168  if (.not. linvert) then
169  res(1) = sxx * v(1) + sxy * v(2)
170  res(2) = syy * v(2)
171  else
172  res(2) = v(2) / syy
173  res(1) = (v(1) - sxy * res(2)) / sxx
174  end if
Here is the caller graph for this function:

◆ transform()

subroutine, public geomutilmodule::transform ( real(dp)  xin,
real(dp)  yin,
real(dp)  zin,
real(dp)  xout,
real(dp)  yout,
real(dp)  zout,
real(dp), optional  xorigin,
real(dp), optional  yorigin,
real(dp), optional  zorigin,
real(dp), optional  sinrot,
real(dp), optional  cosrot,
logical(lgp), optional  invert 
)
Parameters
zininput coordinates
zoutoutput coordinates
zoriginorigin coordinates
cosrotsine and cosine of rotation
invertwhether to invert

Definition at line 178 of file GeomUtil.f90.

183  ! -- dummy
184  real(DP) :: xin, yin, zin !< input coordinates
185  real(DP) :: xout, yout, zout !< output coordinates
186  real(DP), optional :: xorigin, yorigin, zorigin !< origin coordinates
187  real(DP), optional :: sinrot, cosrot !< sine and cosine of rotation
188  logical(LGP), optional :: invert !< whether to invert
189  ! -- local
190  logical(LGP) :: ltranslate, lrotate, linvert
191  real(DP) :: x, y
192  real(DP) :: lxorigin, lyorigin, lzorigin
193  real(DP) :: lsinrot, lcosrot
194 
195  ! -- Process option arguments and set defaults and flags
196  call defaults(lxorigin, lyorigin, lzorigin, &
197  lsinrot, lcosrot, linvert, &
198  ltranslate, lrotate, &
199  xorigin, yorigin, zorigin, &
200  sinrot, cosrot, invert)
201 
202  ! -- Apply transformation or its inverse
203  if (.not. linvert) then
204  ! -- Apply transformation to coordinates
205  if (ltranslate) then
206  xout = xin - lxorigin
207  yout = yin - lyorigin
208  zout = zin - lzorigin
209  else
210  xout = lxorigin
211  yout = lyorigin
212  zout = lzorigin
213  end if
214  if (lrotate) then
215  x = xout
216  y = yout
217  xout = x * lcosrot + y * lsinrot
218  yout = -x * lsinrot + y * lcosrot
219  end if
220  else
221  ! -- Apply inverse of transformation to coordinates
222  if (lrotate) then
223  x = xin * lcosrot - yin * lsinrot
224  y = xin * lsinrot + yin * lcosrot
225  else
226  x = xin
227  y = yin
228  end if
229  if (ltranslate) then
230  xout = x + lxorigin
231  yout = y + lyorigin
232  zout = zin + lzorigin
233  end if
234  end if
Here is the call graph for this function:
Here is the caller graph for this function: