# How can I make a GeoNodes equivalent of an array modifier that uses object offset?

I'm trying to create a GeoNodes setup that behaves like an array modifier (See 1). I've managed to get part of it working (See 2). Mine can translate properly when no rotations are considered but I'm unsure how to account for rotations. My rotations are right but the positions are now incorrect and I don't know how to do that in a simple matter. 3 shows my current setup.

Here's a version that can handle arbitrary rotations:

The math is a bit more demanding than you'd usually find in geometry nodes, but i hope some of this will become standard nodes in the future. The nodes should be usable as is, even if the internals remain shrouded in mystery, but i will try to explain anyway.

The basic concept here is that the array modifier applies a loc/rot/scale transformation repeatedly to some mesh M:

M1 = R*S*M0 + L
M2 = R*S*M1 + L
= R^2*S^2*M0 + R*S*L + L
M3 = R * S * M2 + L
= R^3*S^3*M0 + R^2*S^2*L + R*S*L + L
...
Mn = R^n*S^n*M0 + SUM(R^i*S^i*L, i=0..n-1)


The first term describes an exponential of the rotation matrix and the scale vector respectively. While computing the power of the scale vector is fairly straightforward, the rotation is usually given as an Euler vector and notoriously difficult to work with. So my first step was to build conversion functions to get from Euler rotations to Quaternions and back: (the insides of these node groups is pretty terrifying, so you'll have to go there at your own risk ;) https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles )

The exponential and logarithm as well as the n-th power of a quaternion can be computed according to https://en.wikipedia.org/wiki/Quaternion#Exponential,_logarithm,_and_power_functions.

For the location of the instances we need to compute the sum of the R^i*S^i*L terms, which is where the Accumulate Field node comes in very handy.

It probably won't work very well with non-uniform scaling yet, but that's always a difficult proposition.

Hope this proves useful!

• Yes, you're absolutely right, of course, I didn't get that right here: you can't accumulate the Euler as easily as I did here, unfortunately. By the way, "Terrifying" hits it very well ;-) Jun 9, 2022 at 19:32
• ...But again, we simply lack a loop node here. If we had that, we could simply rotate the rotation with a rotation (Node Rotate Euler) :D Jun 9, 2022 at 19:52
• Yes. The exponential approach is slightly more efficient because you can compute multiplications in parallel (probably could even avoid the accumulate for location), but loops should be perfectly fine for reasonable instance counts and much more flexible. Regardless, it was a fun bit of math to figure out :)
– user436
Jun 9, 2022 at 19:59

In some cases, this solution is sufficient:

The difficulty here lies in the fact that the rotation of each object influences all positions of the following objects.

Therefore, it is not sufficient to accumulate the rotation alone, and separately calculate the positions based on the scaling.

Instead, one must first capture the scaled vectors between the cubes, and then rotate them in the correct direction using the accumulating rotation.

This way you get single correctly aligned vectors/segments, which you finally only have to add/accumulate to get the final positions of the individual cubes.

Note: The disadvantage of this relatively simple solution, however, is that it only works on one axis, since rotations cannot be accumulated simply like that!

• This is really close. It breaks down when you rotate along all three axis at the same time but it's so close. It looks like it gets mirrored. It might have something to do with the order the rotations are allowed. Side note: Why doesn't your accumulate field have 2 drop down menus? Jun 9, 2022 at 17:17
• @timeslidr Indeed, I have not tested that, I'll take a closer look. The node has no dropdowns for me, because I have hidden them to save space. Simply right click -> Toggle Node Options. Jun 9, 2022 at 17:55