-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdisk_point_dist_3d.f90
More file actions
102 lines (94 loc) · 2.49 KB
/
disk_point_dist_3d.f90
File metadata and controls
102 lines (94 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
subroutine disk_point_dist_3d ( pc, r, axis, p, dist )
!*****************************************************************************80
!
!! DISK_POINT_DIST_3D determines the distance from a disk to a point in 3D.
!
! Discussion:
!
! A disk in 3D satisfies the equations:
!
! ( P(1) - PC(1) )^2 + ( P(2) - PC(2) )^2 + ( P(3) - PC(3) <= R^2
!
! and
!
! P(1) * AXIS(1) + P(2) * AXIS(2) + P(3) * AXIS(3) = 0
!
! Licensing:
!
! This code is distributed under the GNU LGPL license.
!
! Modified:
!
! 17 August 2005
!
! Author:
!
! John Burkardt
!
! Parameters:
!
! Input, double precision PC(3), the center of the disk.
!
! Input, double precision R, the radius of the disk.
!
! Input, double precision AXIS(3), the axis vector.
!
! Input, double precision P(3), the point to be checked.
!
! Output, double precision DIST, the distance of the point to the disk.
!
implicit none
integer, parameter :: dim_num = 3
double precision axial_component
double precision axis(dim_num)
double precision axis_length
double precision dist
double precision r8vec_norm
double precision off_axis_component
double precision off_axis(dim_num)
double precision p(dim_num)
double precision pc(dim_num)
double precision r
!
! Special case: the point is the center.
!
if ( all ( p(1:dim_num) == pc(1:dim_num) ) ) then
dist = 0.0D+00
return
end if
axis_length = r8vec_norm ( dim_num, axis(1:dim_num) )
if ( axis_length == 0.0D+00 ) then
dist = -huge ( dist )
return
end if
axial_component = dot_product ( p(1:dim_num) - pc(1:dim_num), &
axis(1:dim_num) ) / axis_length
!
! Special case: the point satisfies the disk equation exactly.
!
if ( sum ( p(1:dim_num) - pc(1:dim_num) )**2 <= r * r .and. &
axial_component == 0.0D+00 ) then
dist = 0.0D+00
return
end if
!
! Decompose P-PC into axis component and off-axis component.
!
off_axis(1:dim_num) = p(1:dim_num) - pc(1:dim_num) &
- axial_component * axis(1:dim_num) / axis_length
off_axis_component = r8vec_norm ( dim_num, off_axis )
!
! If the off-axis component has norm less than R, the nearest point is
! the projection to the disk along the axial direction, and the distance
! is just the dot product of P-PC with unit AXIS.
!
if ( off_axis_component <= r ) then
dist = abs ( axial_component )
return
end if
!
! Otherwise, the nearest point is along the perimeter of the disk.
!
dist = sqrt ( axial_component**2 + ( off_axis_component - r )**2 )
return
end