Skip to content

Commit 595aa22

Browse files
committed
use support points for sphere and ellipsoid for computing final contact points
1 parent dadbb06 commit 595aa22

File tree

3 files changed

+24
-23
lines changed

3 files changed

+24
-23
lines changed

src/Composition/_module.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export InteractionBehavior, Gripper, Movable, Lockable, NoInteraction
7070

7171
export rot123fromR, rot132fromR, Rfromrot123, Rfromrot132
7272

73-
export supportPoint, boundingBox!
73+
export supportPoint, boundingBox!, contactPointIsLocallyBijectiveToNormal
7474

7575
@enum InteractionBehavior Gripper Movable Lockable NoInteraction
7676

src/Composition/supportPoints.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,13 @@ function boundingBox!(obj::Composition.Object3D, AABB::Basics.BoundingBox; tight
144144
end
145145
return AABB
146146
end
147+
148+
149+
function contactPointIsLocallyBijectiveToNormal(obj::Composition.Object3D)
150+
isBijective = false
151+
shapeKind = obj.shapeKind
152+
if shapeKind == Modia3D.SphereKind || shapeKind == Modia3D.EllipsoidKind
153+
isBijective = true
154+
end
155+
return isBijective
156+
end

src/contactDetection/ContactDetectionMPR/mpr.jl

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ function mprGeneral(ch::Composition.ContactDetectionMPR_handler{T}, shapeA::Comp
416416
end
417417

418418

419-
function mprTwoSpheres(ch::Composition.ContactDetectionMPR_handler{T}, shapeA::Composition.Object3D, shapeB::Modia3D.Composition.Object3D,
419+
function distanceTwoSpheres(ch::Composition.ContactDetectionMPR_handler{T}, shapeA::Composition.Object3D, shapeB::Modia3D.Composition.Object3D,
420420
sphereA::Shapes.Sphere, sphereB::Shapes.Sphere) where {T}
421421
neps = Modia3D.nepsType(T)
422422
radiusA = T(sphereA.diameter*0.5)
@@ -445,31 +445,22 @@ function mpr(ch::Composition.ContactDetectionMPR_handler{T}, shapeA::Composition
445445
sphereA::Shapes.Sphere = shapeA.shape
446446
sphereB::Shapes.Sphere = shapeB.shape
447447
(distance, contactPoint1, contactPoint2, normal, supportPointsDefined,
448-
support1A, support1B, support2A, support2B, support3A, support3B) = mprTwoSpheres(ch, shapeA, shapeB, sphereA, sphereB)
449-
elseif shapeKindA != Modia3D.SphereKind && shapeKindB != Modia3D.SphereKind
450-
(distance, contactPoint1, contactPoint2, normal, supportPointsDefined,
451-
support1A, support1B, support2A, support2B, support3A, support3B) = mprGeneral(ch, shapeA, shapeB)
448+
support1A, support1B, support2A, support2B, support3A, support3B) = distanceTwoSpheres(ch, shapeA, shapeB, sphereA, sphereB)
452449
else
453450
(distance, contactPoint1, contactPoint2, normal, supportPointsDefined,
454451
support1A, support1B, support2A, support2B, support3A, support3B) = mprGeneral(ch, shapeA, shapeB)
455452

456-
if shapeKindA == Modia3D.SphereKind
457-
centroidSphere = getCentroid(shapeA)
458-
sphereA1::Shapes.Sphere = shapeA.shape
459-
radius = T(sphereA1.diameter*0.5)
460-
contactPointSphere = centroidSphere + radius*normal
461-
contactPointOtherShape = contactPointSphere + distance*normal
462-
contactPoint1 = contactPointSphere
463-
contactPoint2 = contactPointOtherShape
464-
elseif shapeKindB == Modia3D.SphereKind
465-
normalLocal = -normal
466-
centroidSphere = getCentroid(shapeB)
467-
sphereB1::Shapes.Sphere = shapeB.shape
468-
radius = T(sphereB1.diameter*0.5)
469-
contactPointSphere = centroidSphere + radius*normalLocal
470-
contactPointOtherShape = contactPointSphere + distance*normalLocal # distance is negative (otherwise direction of normal must be changed)
471-
contactPoint1 = contactPointOtherShape
472-
contactPoint2 = contactPointSphere
453+
if Modia3D.contactPointIsLocallyBijectiveToNormal(shapeA) && Modia3D.contactPointIsLocallyBijectiveToNormal(shapeB)
454+
algebraicSign = sign(distance)
455+
contactPoint1 = Modia3D.supportPoint(shapeA, normal)
456+
contactPoint2 = Modia3D.supportPoint(shapeB, -normal)
457+
distance = algebraicSign * norm(contactPoint2 - contactPoint1)
458+
elseif Modia3D.contactPointIsLocallyBijectiveToNormal(shapeA) && !Modia3D.contactPointIsLocallyBijectiveToNormal(shapeB)
459+
contactPoint1 = Modia3D.supportPoint(shapeA, normal)
460+
contactPoint2 = contactPoint1 + distance*normal
461+
elseif !Modia3D.contactPointIsLocallyBijectiveToNormal(shapeA) && Modia3D.contactPointIsLocallyBijectiveToNormal(shapeB)
462+
contactPoint2 = Modia3D.supportPoint(shapeB, -normal)
463+
contactPoint1 = contactPoint2 + distance*-normal
473464
end
474465
end
475466
return (Float64(distance), SVector{3,Float64}(contactPoint1), SVector{3,Float64}(contactPoint2), SVector{3,Float64}(normal), supportPointsDefined,

0 commit comments

Comments
 (0)