Need some math help with aligning objects

I have various approximately cylindrically/cuboid shaped objects. The exact shape varies, but they’re generally going to have one dimension significantly longer than the other two. Which axis is the long one, is a factor that can vary. But it has been prechecked in advance, and the object has a stored vector which indicates its long axis (for example, <1,0,0> when X is the longest)

What i need to do, is to rotate them relative to a reference object, so that they (the long axis) run perpendicular to the forward vector of that reference object.

Alternatively, i may need them to run parallel. it’s a kind of either/or thing, so i need to be able to code for both.

The roll of these objects will usually not matter. But it will matter in some cases, and for those i’ll want the object to either lie flat, or lie upside down, and not roll values inbetween. For all other cases, i want it to not specifically change, and be left at whatever it was before

And once i eventually have a target rotation, i need to do some lerping to it, not just insta setting

Perhaps some context is needed:

The reference object here, is a dog’s mouth (actually a tiny marker object inside the mouth), and the other objects i’m rotating are generally dog toys (or grabbable parts of multipart toys). My overall purpose here is to figure out reasonably logical angles for a toy to be picked up at

I need some help with the math here, i’m not quite sure where to start

Well, it would be much easier if your objects were all modeled so that the long axis is always the same (say, the Z axis). If that’s not the case, then you have to do an additional rotation so that it is the case… but for now, let’s ignore that and just get it working in the simple case.

So you’ve got an object that’s long in the +Z direction, and you want to orient it parallel perpendicular to the forward vector of the dog’s mouth.

To do that, you need to just rotate the object by the rotation of the dog’s mouth, possibly with some additional rotation. So, something like this:

obj.transform.rotation = Quaternion.Euler(0, 90, 0) * dogMouth.transform.rotation;

That’s it… in this case. Honestly, just make a big select case for each of the possible orientations (long axis) of the object, and fiddle with the above until you’ve got it right in each case. The constants in the Euler call will vary, but the rest should be the same I think.

Hi joe
I do see some problems with that solution, the most obvious one that comes to mind, is that there are at least two correct solutions (90 and 270 degrees rotated) and i’d like the object to rotate along the shortest route of the two

Can you clarify this additional rotation? I don’t quite understand how it could be made the case, as any rotation to the object will rotate its axes too (rotating a parent/container object is not an option). i definitely cannot guarantee the long axis always being a specific one, i have to code around that limitation

That’s a good point. Now it gets a little trickier. What you’ll have to do is consider both rotations, and then measure how far each one is from the current rotation, using Quaternion.Angle. Then pick whichever is smaller.

For the second point, you have to deal with that by just having a different case for each possible long axis. (This is something you have to know — that is, if you don’t know which axis is the long axis, then we’ll have to back up and figure out a way to find that out.)

For the first point, the additional rotation is just something you throw in to account for the object rotation. In other words, you’re going to compose two rotations:

  • A rotation to get the object so that its long axis is pointing down +Z in the world.

  • A rotation that takes an object pointing down +Z, and makes it point the way we want it relative to the dog’s mouth.

You compose rotations by just multiplying them together.

ok, this seems helpful.

Farther to the problem of knowing which is the long side, there’s also the problem of knowing which of the object’s axes is its “up”, i think that might be a necessary thing in order to set the roll where it matters.

assuming i already figured that out (ill probably go with the second-longest side, i need to incorporate that into the calculations too, any idea how?

Again with the perpendicular thing, i’ll want it to pick the shortest path to either being face up, or face down