Best way to align arbitrary bodies?

JesusFreke
Advocate

Best way to align arbitrary bodies?

JesusFreke
Advocate
Advocate

Let's say I have 2 bodies, and I want to move one body along a specific vector up to the point where it touches the other body. The intent is to place the body at that location, not necessarily the actual "movement" of the body. I've implemented a solution that I'll describe below, but I'm not very happy with it, and was hoping someone might have a suggestion on a better way to approach it.

 

I know that with joints and contact sets, you can specify a joint and manually move a body so that it touches another. But I couldn't find any way to push the joint to it's endpoint like that using the API, other than using a binary search or similar.  e.g. using a slider joint, and modifying joint.jointMotion.slideValue, the modification simply silently fails if you specify a slide value that would cause the body to intersect another body in the contact set. And you can specify a larger value that successfully skips past any bodies in the joint's way. So I guess you could do some sort of binary search to find the largest joint value within some tolerance of touching the other object. But if  the first contact point is a very small feature the two bodies, it seems like it would be possible for the binary search to skip past and miss that contact point. i.e. if there were 2 parallel boxes with very thin tabs sticking out. 

 

The approach I ended up implementing is similar, but doesn't actually use joints.

1. call MeasureManager.measureMinimumDistance

2. move the body along the vector by that distance

3. check if the bodies are touching (within some tolerance)

4. using oriented bounding boxes, check if the moving body has moved past the other body without intersecting it

5. loop

 

The theory is that you can "safely" move the body along the vector by the measure minimum distance, and be certain that you won't have moved it too far so that it intersects with the other body. But if the minimum distance vector isn't parallel to the movement vector, you'll end up getting closer to the body, but not actually touching. So for every iteration you get closer and closer, until you get close enough within some tolerance.

 

This works reasonably well in most cases, but if you have 2 parallel faces that slide past each other with a very small distance between them, the above algorithm could require many iterations, since the shortest distance, and the resulting movement amount would be very small.

 

One improvement I'm considering is that you might be able to do a pair-wise "measureMinimumDistance" for each pair of faces on the two bodies, and find the minimum distance, ignoring those distances where the minimum distance vector between the 2 faces is perpendicular to, or is the opposite direction of the movement vector (i.e. if their dot product is <= 0). But that could be potentially expensive for bodies with a large number of faces.

 

Although, you know that the minimum distance for any pair of faces won't decrease by more than the movement amount for that iteration, so you could eliminate many face pairs just based on their minimum distance from the previous iteration, especially when the movement amount for that iteration is small.

 

It seems like you might be able to extend the silhouette of the body and somehow use its intersection with the target body? I can't quite come up with a reliable algorithm though - other than as a way to determine beforehand if there is an intersection or not. Maybe as a way to pare down the number of faces to be considered in the above cartesion product.. needs more thought.

 

Can anyone think of any better approaches for doing this? 

 

 

 

 

 

 

0 Likes
Reply
488 Views
2 Replies
Replies (2)

p.seem
Advocate
Advocate

I've been trying to work out a scheme where you create a new body that is an extrusion of the face of one component to the face of the other component and get your distance by analyzing that body.  But it all gets convoluted when you have work out which faces you care about or start doing every permutation of face pairs.

 

So as tempting as it is to start sketching out new algorithms, my instinct is that this is the kind of case where Fusion has already done the heavy lifting by calculating contact sets, and we should lean on that rather than reinventing the wheel.

 

I've found joint calculation to be quite slow, so my first thought would be to try a hybrid of the two approaches you described -- set up contact sets to actually detect the collision, but use your manual (that is, through the API...) free move rather than a slider joint.  I never realized you could just jump right over the collision; that's quite frustrating, and I don't see a way around that except by iterating.  You could either use the mininum distance you described as the increment, or you could just define your smallest allowable feature size and move in increments of 1/2 that to guarantee you never skip small features.  Presumably this comes down to how expensive a calculation of measureMinimumDistance is compared to previewing the move.  The former certainly feels smarter, but the latter mimics what happens when you're dragging the part around in the UI and that feels responsive enough in simple designs. 

 

In either case I'm imaging something where you do a small free move along the vector you care about and keep repeating until the move silently fails (i.e. until the position of your component is unchanged from the last iteration), which is really just mimicking how I'd do it in the UI -- drag the thing until it stops moving, at which point you know your parts in contact as Fusion defines it.

 

My only other thought is that you could speed it up by analytically working out the range of distances over which the two simple bounding boxes overlap, so 1) you're only moving in small steps when there's at least the potential to overlap, and 2) you know when to stop trying (and when to never bother trying, if that's a case you encounter).

 

Reading over what I've just written, I'm not sure I've actually managed to add anything to what you've already worked out!  But I'll post in anyway, on the off chance something I've written triggers a new idea for you.

 

Good luck, and happy New Year.

1 Like

JesusFreke
Advocate
Advocate

Hmm, yeah, an extruded face would only work for planar faces. And doing something like extruding the silhouette might not find the closest contact point, e.g. if the body has some protrusion on the front.

 

I do like the idea of the hybrid solution. I guess I wasn't thinking of using contact sets outside the context of a joint

0 Likes