OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
dist_node_seg4n.F
Go to the documentation of this file.
1Copyright> OpenRadioss
2Copyright> Copyright (C) 1986-2025 Altair Engineering Inc.
3Copyright>
4Copyright> This program is free software: you can redistribute it and/or modify
5Copyright> it under the terms of the GNU Affero General Public License as published by
6Copyright> the Free Software Foundation, either version 3 of the License, or
7Copyright> (at your option) any later version.
8Copyright>
9Copyright> This program is distributed in the hope that it will be useful,
10Copyright> but WITHOUT ANY WARRANTY; without even the implied warranty of
11Copyright> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12Copyright> GNU Affero General Public License for more details.
13Copyright>
14Copyright> You should have received a copy of the GNU Affero General Public License
15Copyright> along with this program. If not, see <https://www.gnu.org/licenses/>.
16Copyright>
17Copyright>
18Copyright> Commercial Alternative: Altair Radioss Software
19Copyright>
20Copyright> As an alternative to this open-source version, Altair also offers Altair Radioss
21Copyright> software under a commercial license. Contact Altair to discuss further if the
22Copyright> commercial version may interest you: https://www.altair.com/radioss/.
23!||====================================================================
24!|| dist_node_seg4n ../engine/source/tools/sensor/dist_node_seg4n.F
25!||--- called by ------------------------------------------------------
26!|| sensor_dist_surf0 ../engine/source/tools/sensor/sensor_dist_surf0.F
27!||====================================================================
28 SUBROUTINE dist_node_seg4n (
29 . DIST,DMIN,DMAX,NOD_X,NOD_Y,NOD_Z,
30 . AX,AY,AZ,BX,BY,BZ,CX,CY,CZ,DX,DY,DZ)
31c-----------------------------------------------------------------------
32c Calculates distance between NODE(NOD_X,NOD_Y,NOD_Z) and a 3 node segment (A-B-C)
33c returns distance to plane if node projection is inside the segment
34c otherwise : check closest distance to edges and segment points
35c-----------------------------------------------------------------------
36C I m p l i c i t T y p e s
37C-----------------------------------------------
38#include "implicit_f.inc"
39C-----------------------------------------------
40C D u m m y A r g u m e n t s
41C-----------------------------------------------
42 my_real , INTENT(IN) :: dmin,dmax,nod_x,nod_y,nod_z,
43 . ax,ay,az,bx,by,bz,cx,cy,cz,dx,dy,dz
44 my_real , INTENT(OUT) :: dist
45C----------------------------------------------------------
46C Local Variables
47C----------------------------------------------------------
48 INTEGER :: OK
49 my_real :: ABX,ABY,ABZ,ACX,ACY,ACZ,BCX,BCY,BCZ,CDX,CDY,CDZ,DAX,DAY,DAZ,
50 . ux,uy,uz,vx,vy,vz,wx,wy,wz,qx,qy,qz,qa_x,qa_y,qa_z,qb_x,qb_y,qb_z,
51 . qc_x,qc_y,qc_z,mx,my,mz,mpx,mpy,mpz,
52 . amx,amy,amz,bmx,bmy,bmz,cmx,cmy,cmz,dmx,dmy,dmz,
53 . n1x,n1y,n1z,n2x,n2y,n2z,n3x,n3y,n3z,n4x,n4y,n4z,
54 . sx,sy,sz,d,d1,d2,d3,d4,norm1,a1,a2,norm2,norm3,norm4
55C=======================================================================
56c segment barycenter
57 mx = fourth*(ax + bx + cx + dx)
58 my = fourth*(ay + by + cy + dy)
59 mz = fourth*(az + bz + cz + dz)
60 mpx = nod_x - mx
61 mpy = nod_y - my
62 mpz = nod_z - mz
63c Divide 4N segment into 4 segments 3N with common node in barycenter (possible warping)
64c A-B-M, B-C-M,C-D-M, D-M-A
65c calculate distance to 4 planes defined by each segment
66 abx = bx - ax
67 aby = by - ay
68 abz = bz - az
69 amx = mx - ax
70 amy = my - ay
71 amz = mz - az
72 n1x = amy*abz - amz*aby
73 n1y = amz*abx - amx*abz
74 n1z = amx*aby - amy*abx
75 norm1 = sqrt(n1x*n1x + n1y*n1y + n1z*n1z)
76 d1 = abs(n1x*mpx + n1y*mpy + n1z*mpz) / norm1
77c
78 bcx = cx - bx
79 bcy = cy - by
80 bcz = cz - bz
81 bmx = mx - bx
82 bmy = my - by
83 bmz = mz - bz
84 n2x = bmy*bcz - bmz*bcy
85 n2y = bmz*bcx - bmx*bcz
86 n2z = bmx*bcy - bmy*bcx
87 norm2 = sqrt(n2x*n2x + n2y*n2y + n2z*n2z)
88 d2 = abs(n2x*mpx + n2y*mpy + n2z*mpz) / norm2
89c
90 cdx = dx - cx
91 cdy = dy - cy
92 cdz = dz - cz
93 cmx = mx - cx
94 cmy = my - cy
95 cmz = mz - cz
96 n3x = cmy*cdz - cmz*cdy
97 n3y = cmz*cdx - cmx*cdz
98 n3z = cmx*cdy - cmy*cdx
99 norm3 = sqrt(n3x*n3x + n3y*n3y + n3z*n3z)
100 d3 = abs(n3x*mpx + n3y*mpy + n3z*mpz) / norm3
101c
102 dax = ax - dx
103 day = ay - dy
104 daz = az - dz
105 dmx = mx - dx
106 dmy = my - cy
107 dmz = mz - cz
108 n4x = dmy*daz - dmz*day
109 n4y = dmz*dax - dmx*daz
110 n4z = dmx*day - dmy*dax
111 norm4 = sqrt(n4x*n4x + n4y*n4y + n4z*n4z)
112 d4 = abs(n4x*mpx + n4y*mpy + n4z*mpz) / norm4
113c---------------------------------------------------
114 dist = min(d1,d2)
115 dist = min(dist,d3)
116 dist = min(dist,d4)
117 IF (dist > dmax .or. dist < dmin) RETURN ! distance is outside of valid range
118c---------------------------------------------------
119c check if projection is inside sub-segments
120c Q = projection of NODE on segment plane using normal(NPX,NPY,NPZ)
121c---------------------------------------------------
122c 1st sub-segment :
123 qx = nod_x - d1*n1x / norm1
124 qy = nod_y - d1*n1y / norm1
125 qz = nod_z - d1*n1z / norm1
126c
127 sx = (qy - my) * (az - mz) - (qz - mz) * (ay - my)
128 sy = (qz - mz) * (ax - mx) - (qx - mx) * (az - mz)
129 sz = (qx - mx) * (ay - my) - (qy - my) * (ax - mx)
130 a1 = sqrt(sx*sx + sy*sy + sz*sz) * half
131 sx = (by - my) * (qz - mz) - (bz - mz) * (qy - my)
132 sy = (bz - mz) * (qx - mx) - (bx - mx) * (qz - mz)
133 sz = (bx - mx) * (qy - my) - (by - my) * (qx - mx)
134 a2 = sqrt(sx*sx + sy*sy + sz*sz) * half
135 ok = 0
136 IF (a1 + a2 < half * norm1) THEN
137 dist = d1
138 ok = 1
139 END IF
140c
141 IF (ok == 0) THEN
142c Test 2nd sub-segment :
143 qx = nod_x - d2*n2x / norm2
144 qy = nod_y - d2*n2y / norm2
145 qz = nod_z - d2*n2z / norm2
146c
147 sx = (qy - my) * (bz - mz) - (qz - mz) * (by - my)
148 sy = (qz - mz) * (bx - mx) - (qx - mx) * (bz - mz)
149 sz = (qx - mx) * (by - my) - (qy - my) * (bx - mx)
150 a1 = sqrt(sx*sx + sy*sy + sz*sz) * half
151 sx = (cy - my) * (qz - mz) - (cz - mz) * (qy - my)
152 sy = (cz - mz) * (qx - mx) - (cx - mx) * (qz - mz)
153 sz = (cx - mx) * (qy - my) - (cy - my) * (qx - mx)
154 a2 = sqrt(sx*sx + sy*sy + sz*sz) * half
155 IF (a1 + a2 < half * norm2) THEN
156 dist = d2
157 ok = 1
158 END IF
159 END IF
160 IF (ok == 0) THEN
161c Test 3rd sub-segment :
162 qx = nod_x - d3*n3x / norm3
163 qy = nod_y - d3*n3y / norm3
164 qz = nod_z - d3*n3z / norm3
165c
166 sx = (qy - my) * (cz - mz) - (qz - mz) * (cy - my)
167 sy = (qz - mz) * (cx - mx) - (qx - mx) * (cz - mz)
168 sz = (qx - mx) * (cy - my) - (qy - my) * (cx - mx)
169 a1 = sqrt(sx*sx + sy*sy + sz*sz) * half
170 sx = (dy - my) * (qz - mz) - (dz - mz) * (qy - my)
171 sy = (dz - mz) * (qx - mx) - (dx - mx) * (qz - mz)
172 sz = (dx - mx) * (qy - my) - (dy - my) * (qx - mx)
173 a2 = sqrt(sx*sx + sy*sy + sz*sz) * half
174 IF (a1 + a2 < half * norm3) THEN
175 dist = d3
176 ok = 1
177 END IF
178 END IF
179 IF (ok == 0) THEN
180c Test 4th sub-segment :
181 qx = nod_x - d3*n3x / norm4
182 qy = nod_y - d3*n3y / norm4
183 qz = nod_z - d3*n3z / norm4
184c
185 sx = (qy - my) * (dz - mz) - (qz - mz) * (dy - my)
186 sy = (qz - mz) * (dx - mx) - (qx - mx) * (dz - mz)
187 sz = (qx - mx) * (dy - my) - (qy - my) * (dx - mx)
188 a1 = sqrt(sx*sx + sy*sy + sz*sz) * half
189 sx = (ay - my) * (qz - mz) - (az - mz) * (qy - my)
190 sy = (az - mz) * (qx - mx) - (ax - mx) * (qz - mz)
191 sz = (ax - mx) * (qy - my) - (ay - my) * (qx - mx)
192 a2 = sqrt(sx*sx + sy*sy + sz*sz) * half
193 IF (a1 + a2 < half * norm4) THEN
194 dist = d3
195 ok = 1
196 END IF
197 END IF
198c---------------------------------------------------
199c check distance to all nodes including barycenter
200c---------------------------------------------------
201 IF (ok == 0) THEN
202 dist = sqrt(mpx**2 + mpy**2 + mpz**2)
203 d1 = sqrt((nod_x - ax)**2 + (nod_y - ay)**2 + (nod_z - az)**2)
204 d2 = sqrt((nod_x - bx)**2 + (nod_y - by)**2 + (nod_z - bz)**2)
205 d3 = sqrt((nod_x - cx)**2 + (nod_y - cy)**2 + (nod_z - cz)**2)
206 d4 = sqrt((nod_x - dx)**2 + (nod_y - dy)**2 + (nod_z - dz)**2)
207 dist = min(dist, d1)
208 dist = min(dist, d2)
209 dist = min(dist, d3)
210 dist = min(dist, d4)
211 END IF
212c
213c we skip checking distance to external edges (for the moment)
214c
215c-----------
216 RETURN
217 END SUBROUTINE
218
#define my_real
Definition cppsort.cpp:32
subroutine dist_node_seg4n(dist, dmin, dmax, nod_x, nod_y, nod_z, ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz)
#define min(a, b)
Definition macros.h:20