@@ -5,15 +5,18 @@ module dm_transform
55 use :: dm_const
66 use :: dm_error
77 use :: dm_kind
8- use :: dm_la
98 use :: dm_util
109 implicit none (type, external )
1110 private
1211
1312 public :: dm_transform_coord_2d
1413 public :: dm_transform_polar_3d
14+ public :: dm_transform_cartesian_to_polar
15+ public :: dm_transform_polar_to_cartesian
1516contains
1617 integer function dm_transform_coord_2d (cs , ct , observs , trans , params , residuals , variance , rotation , scale_factor ) result(rc)
18+ use :: dm_la
19+
1720 integer , parameter :: NRHS = 4 ! ! Number of columns in matrix A.
1821
1922 real (kind= r8 ), intent (inout ) :: cs(:) ! ! Common control points in source system.
@@ -113,21 +116,47 @@ integer function dm_transform_polar_3d(vx, vy, vz, tx, ty, hz, v, dist_hz, x, y,
113116 if (present (azimuth)) then
114117 ! Remove the global azimuth angle of the sensor from the
115118 ! calculated local azimuth.
116- if (z /= 0.0 ) z = z - azimuth
119+ if (.not. dm_equals(z, 0.0_r8 ) ) z = z - azimuth
117120 end if
118121
119122 ! Append the measured horizontal direction to the angle.
120123 t = z + hz
121124
122125 ! Calculate coordinates of the target point.
123- dx = dist_hz * sin (v) * cos (t)
124- dy = dist_hz * sin (v) * sin (t)
125- dz = dist_hz * cos (v)
126+ call dm_transform_polar_to_cartesian(t, v, dist_hz, dx, dy, dz)
126127
127128 x = vx + dx
128129 y = vy + dy
129130 z = vz + dz
130131
131132 rc = E_NONE
132133 end function dm_transform_polar_3d
134+
135+ pure elemental subroutine dm_transform_cartesian_to_polar(x, y, z, hz, v, r)
136+ ! ! Transforms cartesian coordinates to polar (spherical) coordinates.
137+ real (kind= r8 ), intent (in ) :: x ! ! X coordinate.
138+ real (kind= r8 ), intent (in ) :: y ! ! Y coordinate.
139+ real (kind= r8 ), intent (in ) :: z ! ! Z coordinate.
140+ real (kind= r8 ), intent (out ) :: hz ! ! Horizontal angle (phi).
141+ real (kind= r8 ), intent (out ) :: v ! ! Vertical angle (omega).
142+ real (kind= r8 ), intent (out ) :: r ! ! Radius.
143+
144+ r = sqrt (x** 2 + y** 2 + z** 2 )
145+ hz = atan2 (y, x)
146+ v = acos (z / r)
147+ end subroutine dm_transform_cartesian_to_polar
148+
149+ pure elemental subroutine dm_transform_polar_to_cartesian(hz, v, r, x, y, z)
150+ ! ! Transforms polar (spherical) coordinates to cartesian coordinates.
151+ real (kind= r8 ), intent (in ) :: hz ! ! Horizontal angle (phi).
152+ real (kind= r8 ), intent (in ) :: v ! ! Vertical angle (omega).
153+ real (kind= r8 ), intent (in ) :: r ! ! Radius.
154+ real (kind= r8 ), intent (out ) :: x ! ! X coordinate.
155+ real (kind= r8 ), intent (out ) :: y ! ! Y coordinate.
156+ real (kind= r8 ), intent (out ) :: z ! ! Z coordinate.
157+
158+ x = r * sin (v) * cos (hz)
159+ y = r * sin (v) * sin (hz)
160+ z = r * cos (v)
161+ end subroutine dm_transform_polar_to_cartesian
133162end module dm_transform
0 commit comments