Give 2 parts (with same sizes, but in different axes) the same "visual orientation"

Let’s say I have 2 parts, part A and part B. Both parts have the ‘same’ size (visually), but these are in different axes:
image

  • So part A has size (1, 8, 15)
  • And part B has size (1, 15, 8)
  • Both parts have equal orientation vectors of (0, 0, 0)

How could I produce a function that rotates B, which could have any arbitrary orientation, such that it is the same “visual orientation” as A?

This function would need to work given a part A of any size, including e.g. a part which was longest in the X or Y axis. Note that part A and part B will always have equal sizes.

Many thanks in advance!

.
.

(Context for those interested: I am trying to generalise this module: Part fracturing system V3 such that it will work with any part, not just parts that are dominant in the Y and Z axis. I believe the easiest solution to this is to create a new part, but change its ‘dominant’ axes to Y and Z such that the part is the same size visually, and then match the position. Then, where this post comes in: orient this part so that it is the same ‘visual orientation’ as the previous part. This leaves a final result of a part with the same size, position, and orientation (visually), but its local size axes are different, so that it now has axes Y and Z as the largest.)

You can add the all X,Y,Z sizes all together.

For example part A has size (1, 8, 15)
and part B has size (1, 15, 8)

Let’s get the total size of part A.

local totalSize = partA.Size.X + partA.Size.Y + partA.Size.Z
print(totalSize)
-- OUTPUT: 24

And let’s get the total size of part B.

local totalSize = partB.Size.X + partB.Size.Y + partB.Size.Z
print(totalSize)
-- OUTPUT: 24

Orientation doesn’t matter if the parts are the same size with different vector3 values. They are always same size.

Or you could just get the magnitude of the size Vector3 and compare that

I think you misunderstood my question. I am not looking to give the parts equal orientation vectors. Instead, they should have the same visual orientation. The question body explains this better than the title.

I have edited the title and body to make this more clear now.

So you want mathmatically different orientation but visually same with the other part?

Yeah that’s it. In other words, if part A and part B had the same position, they would be “z-fighting” on all faces.

I’m a bit stuck on how to approach it, other than guessing LookVectors may be handy.

Why don’t you size them same if the total is same?

For the reason explained in the ‘context’ part of the question. The module fractures parts assuming that parts are longest along their local Y and Z axes. E.g. a window may be 1x5x5 which would work as intended, but what if it is 5x1x5? I believe it would be far easier to programmatically create a new part with a size of 1x5x5, and then rotate this to replace the original window part.

I don’t want to manually do this in studio to all window parts, plus it would be much more satisfying to generalise the module and also future proof it against any additional windows added of arbitrary size.

Given that I want the part positions to be equal, another way of looking at it is: I want the global coordinates of part B’s corners to be the same as part A’s corners. Again, I can’t get my head around a solution for that…

Maybe try creating an instance of the alignorientation constraint between the two parts:

https://developer.roblox.com/en-us/api-reference/class/AlignOrientation

I believe AlignOrientation just constrains the orientation of a part based off another. So I don’t see a way this would help with matching part B’s “visual orientation” with part A’s orientation.

Besides, this would require the constrained part to be unanchored.

1 Like

One solution would be to make the positions of the parts equal, and then rotate part B randomly (or exhaust all combinations) (by 90 degree increments) until: the coordinates of the corners of part A and part B are equal.

But this is far from ideal/optimal.

I think the first step would be figuring out which axis is largest / middle / smallest for each part. It is then a case of changing the cframe (just the rotation part) of PartB so that the largest / middle / smallest vectors are the same.

With Part A I’ll define a1, a2, a3 to be the large, middle, small axes respectively. The same goes for part be with b1, b2, b3. It is worth noting that these vectors should be orthonormal to each other.

We want to find a matrix, called R (for rotation) such that:

R * b1 = a1
R * b2 = a2
R * b3 = a3

which can be thought of as just one equation with:

  • R - rotation matrix
  • B - matrix with columns b1, b2, b3
  • A - matrix with columns a1, a2, a3

R * B = A

which we can invert to give:

R = A * B^-1

giving our desired rotation matrix R.

1 Like

I forgot to say that the a and b vectors need to be in world space rather than the parts’ cframe space so some transforming will need to be done there.

E.g.

PartA.Size = Vector3.new(1, 2, 3)

a1 = PartA.CFrame.lookVector -- +ive / -ive shouldn't matter too much for symmetrical shapes
a2 = PartA.CFrame.upVector
a3 = PartA.CFrame.rightVector

1 Like

Okay I’ve came up with a general solution now (haven’t tested it in code yet but I believe it will work)…

Basically the size vectors of parts A and B are what give the visual illusion of part B being rotated differently, so I used the relationship between them to come up with a list of rules.

Let’s say part A has size (1, 2, 3) and part B has size (2, 1, 3). Observe that the Z values are the same. Thus, to rotate part B, simply rotate by 90° in its Z axis.

So some rules follow from this:

  • If the X values of the vectors match, rotate part B by 90° in its X axis.
  • If the Y values of the vectors match, rotate part B by 90° in its Y axis.
  • If the Z values of the vectors match, rotate part B by 90° in its Z axis.
  • If all values match, no rotations are required.

But what if none of the values match? E.g. part A has size (1, 2, 3) and part B has size (2, 3, 1).
Now the rotations will depend on the axes part A is longest in. E.g. if part A has size (1, 2, 3) then it is longest in its local Y and Z axes. So part B will need to be rotated by 90° in its Y axis and 90° in its Z axis.

So the rest of the rules are as follows:

  • If no values of the vectors match, and part A is longest in its local X and Y axes: rotate part B by 90° in its X axis and 90° in its Y axis.
  • If no values of the vectors match, and part A is longest in its local Y and Z axes: rotate part B by 90° in its X axis and 90° in its Z axis.
  • If no values of the vectors match, and part A is longest in its local Z and X axes: rotate part B by 90° in its Z axis and 90° in its Y axis.

I don’t think that the orders of these rotations matter, and it doesn’t matters if you are rotating by -90° instead of 90° too.

I hope that this solution may help someone in the future if they somehow come across the same problem and find this post.

Oops, only just saw you post. An interesting solution nevertheless, similar principles.

Yeah I’m hoping that although my suggestion is a bit more mathmatical that it hopefully leads to a simpler implementation. Let me know how you get on :slight_smile:

Would using pivot-tools be a option because you could just rotate the pivot of partA or partB so that when you set the CFrame they match perfectly