How can I rotate an object to one of two specific rotations?

   738   5   2
User Avatar
Member
1 posts
Joined: 10月 2018
Offline
Hello,

I am a total beginner so please bear that in mind!

I am having a hellish time trying to understand how to do some basic things, namely how can I simply rotate an instanced object to specific rotational values.

I am instancing a group of identical bricks to a grid using copy to points, and trying to randomise their rotations.

As they are bricks, they need to be in specific orientations. I.e. they can have either 0, or 180 degrees rotation in any axis, but they cannot have for example a 90 degree rotation.

I have tried so many methods to achieve this for two days and nothing seems to work.

I would really appreciate any help, even if it means finding a mentor to get me past understanding the basics.

Thanks!

Attachments:
Brick_Grid.png (2.7 MB)

User Avatar
Member
776 posts
Joined: 2月 2017
Offline
The easiest way would be to rotate the bricks into each of the desired rotations and merge them all together.
So you have each brick like four times(each possible rotation).
Another method would be: assign a random integer (eg.: RandInt) to each point.
Set the normal for each value of RandInt with a normal node. And something like this in the group field:
@RandInt==1

Cheers
CYTE
Edited by CYTE - 2025年6月9日 10:14:50
User Avatar
Member
395 posts
Joined: 4月 2017
Offline
MOPs Randomize [github.com] has a "step" feature that allows you to quantize rotations to specific increments.

If you want to do it manually, it can be done with VEX but it's a little annoying. What you want to do is create a random angle/axis rotation where the number of degrees is either 90 or 180 degrees (pi/2 or pi radians). You can do one of these rotations for each of the axes that you want to rotate around (let's say Y and X in your example), then accumulate the result by multiplying the rotations together.

// generate random value between 0 and 180
float randY = fit01(rand(@ptnum), 0, 180);
float randX = fit01(rand(@ptnum+123), 0, 180);
// quantize to increments of 90 
randY = rint(randY / 90) * 90;
randX = rint(randX / 90) * 90;
// create angle/axis quaternions to rotate around specified axes
vector4 rotY = quaternion(radians(randY), {0,1,0});
vector4 rotX = quaternion(radians(randX), {1,0,0});
// accumulate rotations and bind to the orient attribute for copy to points
p@orient = qmultiply(rotY, rotX);

MOPs will make this much easier for you. Example file is attached in any case.
Edited by toadstorm - 2025年6月9日 13:31:33

Attachments:
quantized_rotations_toadstorm.hip (269.0 KB)

MOPs (Motion Operators for Houdini): http://www.motionoperators.com [www.motionoperators.com]
User Avatar
Member
432 posts
Joined: 4月 2018
Online
Houdini's rotation systems have been far too arcane and obtuse for way too long. They made some steps towards easing some of the pain with the Attribute Adjust Vector node, but honestly, that's still extremely limited in what it can do, and is pretty unintuitive to use.

Please express your desire for better, more intuitive tools to handle rotations by dropping a feature request on their official site:
https://www.sidefx.com/bugs/submit/ [www.sidefx.com]

The page says "Submit Bugs", but you can also submit a feature request through there and it will get logged.
User Avatar
Member
4985 posts
Joined: 2月 2012
Offline
Hi,

There are many ways to do this. Here is one way using VEX:

float r = rand ( @ptnum );
float angles [ ] = array ( 0, 180 );
float angle = radians ( angles [ r > 0.5 ] );

p@orient = quaternion ( angle, set ( 0,1,0 ) );



The full list of supported instance attributes like orient, pscale, etc. is here:
https://www.sidefx.com/docs/houdini/copy/instanceattrs [www.sidefx.com]
That doc breaks down what each one does when using Copy to Points.

Attachments:
a.png (592.2 KB)

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com] https://lnk.bio/animatrix [lnk.bio]
User Avatar
Member
432 posts
Joined: 4月 2018
Online
For your understanding, you need to know that when copying to points, there are several attributes that can affect rotation, including (but not limited to) N, up and orient.

The Copy to Points node recognises when these attributes exist on the template points and will rotate the copies accordingly.

One of the more confusing (but ultimately more elegant) ways to rotate copies is via the orientattribute. orientis technically a quaternion, but you don't need to know what a quaternion is or how it works (and indeed, none of us actually do, except a tiny fraction, I'd venture).

All you need to know is that Houdini can build a quaternion for you if you give it an axis to rotate around and the amount you want to rotate it by.

So just tell Houdini, "I want to rotate around X by 30 degrees," and it can spit out a valid orientattribute that Copy to Points can use.

You can supply this instruction via an Attribute Wrangle (using VEX) or an Attribute VOP (which is a node-builder for VEX).

Here is a VOP example in its simplest form to create an orient attribute that demonstrates the above:


Here is a breakdown:
The const (Constant) node supplies the angle in degrees.
The degtorad (Degrees to Radians) node converts that into radians, because Houdini internally uses radians for this stuff.
The rotate node uses that angle and a specified axis (in this case 1,0,0) to build a matrix that defines this transformation.
The matxtoquat node converts that matrix into a quaternion.
The bind1 node outputs that quaternion to the orientattribute.

I have attached the scene file to help you get started. It's a pretty deep rabbit hole, be warned, so you'll need to do some reading to catch up.

Edited by eikonoklastes - 2025年6月12日 04:56:21

Attachments:
orient.png (40.1 KB)
rotated_copies.png (292.6 KB)
Random_Rotations.hiplc (108.4 KB)

  • Quick Links