@@ -21,14 +21,6 @@ function getSupportPoint(shapeA::Modia3D.Composition.Object3D, shapeB::Compositi
2121 return SupportPoint ((a- b). * scale,n,a,b)
2222end
2323
24- #=
25- function getSupportPoint(shapeA::Modia3D.Composition.Object3D, shapeB::Composition.Object3D, n::Nothing; scale::Float64=1.0)
26- println(Modia3D.fullName(shapeA), " r_abs ", shapeA.r_abs, " R_abs ", shapeA.R_abs)
27- println(Modia3D.fullName(shapeB), " r_abs ", shapeB.r_abs, " R_abs ", shapeB.R_abs)
28- error("numerical issues computing normalized vector")
29- return nothing
30- end
31- =#
3224
3325function barycentric (r1:: SupportPoint ,r2:: SupportPoint ,r3:: SupportPoint ,r4:: SupportPoint )
3426 r21 = r2. p - r1. p
@@ -178,7 +170,7 @@ function constructR4(r0::SupportPoint,r1::SupportPoint,r2::SupportPoint,r3::Supp
178170 return (r3, r4, n4)
179171end
180172
181-
173+ # computes twice a parallelepipedial product (Spatprodukt)
182174isNextPortal (r0,r1,r2,r4) = dot ( cross ( (r2. p- r0. p), (r4. p- r0. p) ), r0. n ) <= 0.0 &&
183175 dot ( cross ( (r4. p- r0. p), (r1. p- r0. p) ), r0. n ) <= 0.0
184176
@@ -191,20 +183,17 @@ isNextPortal(r0,r1,r2,r4) = dot( cross( (r2.p-r0.p), (r4.p-r0.p) ), r0.n ) <= 0.
191183# r3r1r4
192184function createBabyTetrahedrons (r0:: SupportPoint ,r1:: SupportPoint ,r2:: SupportPoint ,r3:: SupportPoint ,r4:: SupportPoint ,
193185 shapeA:: Composition.Object3D ,shapeB:: Composition.Object3D )
186+ nextPortal = true
194187 if isNextPortal (r0,r1,r2,r4)
195188 r3 = r4
196189 elseif isNextPortal (r0,r2,r3,r4)
197190 r1 = r4
198191 elseif isNextPortal (r0,r3,r1,r4)
199192 r2 = r4
200193 else
201- # Compute the closest distance to the portal and return it:
202- (r4. p, distance) = signedDistanceToPortal (r0. p,r1. p,r2. p,r3. p)
203- barycentric (r1,r2,r3,r4)
204- error (" MPR: Numerical issues with distance computation between shapeA = " , shapeA, " and shapeB = " , shapeB," . Used distance = " ,distance)
205- return (r1, r2, r3)
194+ nextPortal = false # the signs of all tried combinations of parallelepipedial products are not negative
206195 end
207- return (r1, r2, r3)
196+ return (nextPortal, r1, r2, r3)
208197end
209198
210199
@@ -221,6 +210,30 @@ function skalarization(r0,r1,r2,r3)
221210 return (r0, r1, r2, r3, scale)
222211end
223212
213+ function finalTC2 (r1, r2, r3, r4)
214+ # println("TC 2")
215+ # if !analyzeFinalPortal(r1.p, r2.p, r3.p, r4.p, neps)
216+ # error("shapeA = ", shapeA, " shapeB = ", shapeB)
217+ # end
218+ distance = - dot (r4. n, r4. p)
219+ barycentric (r1,r2,r3,r4)
220+ return distance, r1, r2, r3, r4
221+ end
222+
223+ function finalTC3 (r0, r1, r2, r3, r4)
224+ # println("TC 3")
225+
226+ # doesRayIntersectPortal(r1.p,r2.p,r3.p, r4.p,neps)
227+ # println("r1.p = ", r1.p , " r2.p = ", r2.p ," r3.p = ", r3.p)
228+ # println("r4.p = ", r4.p)
229+ # println(" ")
230+ # if !analyzeFinalPortal(r1.p, r2.p, r3.p, r4.p, neps)
231+ # error("shapeA = ", shapeA, " shapeB = ", shapeB)
232+ # end
233+ (r4. p, distance) = signedDistanceToPortal (r0. p,r1. p,r2. p,r3. p)
234+ barycentric (r1,r2,r3,r4)
235+ return distance, r1, r2, r3, r4
236+ end
224237
225238# MPR - Minkowski Portal Refinement algorithm
226239# construction of points r0 is in the interior of Minkowski Difference and points r1,r2,r3,r4 are on the boundary of Minkowski Difference
@@ -301,6 +314,13 @@ function mprGeneral(ch::Composition.ContactDetectionMPR_handler, shapeA::Composi
301314
302315
303316 # ########## Phase 3, Minkowski Portal Refinement ###################
317+ new_tol = 42.0
318+ isTC2 = false
319+ isTC3 = false
320+ r1_new:: SupportPoint = r0
321+ r2_new:: SupportPoint = r0
322+ r3_new:: SupportPoint = r0
323+ r4_new:: SupportPoint = r0
304324 for i in 1 : niter_max
305325 # ## Phase 3.1: construct r4 ###
306326 # Find support point using the tetrahedron face
@@ -311,49 +331,55 @@ function mprGeneral(ch::Composition.ContactDetectionMPR_handler, shapeA::Composi
311331 # check if the new point r4 is already on the plane of the triangle r1,r2,r3,
312332 # we're already as close as we can get to the origin
313333
334+ TC2 = norm (cross (r4. p,r4. n)) # TC2
335+ TC3 = abs (dot (r4. p- r1. p, r4. n)) # TC3
314336 # # TERMINATION CONDITION 2 ##
315- if norm (cross (r4. p,r4. n)) < tol_rel
316- # println("TC 2")
317- # if !analyzeFinalPortal(r1.p, r2.p, r3.p, r4.p, neps)
318- # error("shapeA = ", shapeA, " shapeB = ", shapeB)
319- # end
320- distance = - dot (r4. n, r4. p)
321- barycentric (r1,r2,r3,r4)
322-
337+ if TC2 < tol_rel
338+ (distance,r1,r2,r3,r4) = finalTC2 (r1,r2,r3,r4)
323339 return (distance, r4. a, r4. b, r4. n, true , r1. a, r1. b, r2. a, r2. b, r3. a, r3. b)
324340
325341 # # TERMINATION CONDITION 3 ##
326- elseif abs (dot (r4. p- r1. p, r4. n)) < tol_rel
327- # println("TC 3")
328-
329- # doesRayIntersectPortal(r1.p,r2.p,r3.p, r4.p,neps)
330- # println("r1.p = ", r1.p , " r2.p = ", r2.p ," r3.p = ", r3.p)
331- # println("r4.p = ", r4.p)
332- # println(" ")
333- # if !analyzeFinalPortal(r1.p, r2.p, r3.p, r4.p, neps)
334- # error("shapeA = ", shapeA, " shapeB = ", shapeB)
335- # end
336- (r4. p, distance) = signedDistanceToPortal (r0. p,r1. p,r2. p,r3. p)
337- barycentric (r1,r2,r3,r4)
338-
342+ elseif TC3 < tol_rel
343+ (distance,r1,r2,r3,r4) = finalTC3 (r0, r1, r2, r3, r4)
339344 return (distance, r4. a, r4. b, r4. n, true , r1. a, r1. b, r2. a, r2. b, r3. a, r3. b)
345+ else
346+ if TC2 < new_tol
347+ new_tol = TC2
348+ isTC2 = true
349+ isTC3 = false
350+ r1_new = r1
351+ r2_new = r2
352+ r3_new = r3
353+ r4_new = r4
354+ end
355+ if TC3 < new_tol
356+ new_tol = TC3
357+ isTC2 = false
358+ isTC3 = true
359+ r1_new = r1
360+ r2_new = r2
361+ r3_new = r3
362+ r4_new = r4
363+ end
340364 end
341365
342366 # ### Phase 3.3: construct baby tetrahedrons with r1,r2,r3,r4 and create a new portal ###
343367 # Construction of three baby tetrahedrons
344- (r1,r2,r3) = createBabyTetrahedrons (r0,r1,r2,r3,r4,shapeA,shapeB)
345-
346-
347- #=
348- r0RayOnPortal = isr0RayOnPortal(r0.p,r1.p,r2.p,r3.p)
349- if r0RayOnPortal[1] != true
350- println("r0RayOnPortal = ", r0RayOnPortal, ": Wrong baby-tetrahedron selected. " , i)
368+ (nextPortal, r1,r2,r3) = createBabyTetrahedrons (r0,r1,r2,r3,r4,shapeA,shapeB)
369+
370+ if ! nextPortal # createBabyTetrahedrons failed
371+ @warn (" MPR (phase 3): Numerical issues with distance computation between $(Modia3D. fullName (shapeA)) and $(Modia3D. fullName (shapeB)) . tol_rel increased locally for this computation to $new_tol ." )
372+ if isTC2
373+ (distance,r1,r2,r3,r4) = finalTC2 (r1_new,r2_new,r3_new,r4_new)
374+ return (distance, r4. a, r4. b, r4. n, true , r1. a, r1. b, r2. a, r2. b, r3. a, r3. b)
375+ end
376+ if isTC3
377+ (distance,r1,r2,r3,r4) = finalTC3 (r0, r1_new, r2_new, r3_new, r4_new)
378+ return (distance, r4. a, r4. b, r4. n, true , r1. a, r1. b, r2. a, r2. b, r3. a, r3. b)
379+ end
351380 end
352- =#
353-
354381 end
355- error (" MPR: Should never get here! Computation failed. Look at shapeA = " , Modia3D. instanceName (shapeA),
356- " shapeB = " , Modia3D. instanceName (shapeB))
382+ error (" MPR (phase 3): Numerical issues with distance computation between $(Modia3D. fullName (shapeA)) and $(Modia3D. fullName (shapeB)) ." )
357383end
358384
359385
0 commit comments