Jump to content
Andy Broomell

Random Rotation

Recommended Posts

Is there a way to select a large number of objects and rotate each of them around their respective center points by a random amount? Perhaps via scripting (@PatStanford)

 

I have many instances of a Symbol arranged in a grid, but I'd like each instance to be rotated randomly for a more natural look. It'd be great to be able to select them and simply run a command.

Share this post


Link to post

I think I may have done something like this by making my symbols into PLant objects, since that object has a built-in random rotation ability on placement. I'll take another look.

A more generic version of this ability would certainly be useful in a number of areas. Crowd placement, landscaping elements like rocks, etc.

Share this post


Link to post

This sounds familiar.  This script was on the old forum and does something very similar to what you are looking for:

 


Procedure RandomRotate;
{Badly scripted by Michael Klaers}

{April, 2014}
{© 2014, Small Group, Inc - Michael Klaers michaelk@verysmallgroup.com}
{Licensed under the GNU Lesser General Public License}

{Gets all the symbols named 'HEX' and rotates them by random (0-5) multiples of 60 degrees}



VAR
	
	SymbolHandle		: Handle; 				{Handle to Symbol}
	RandomNum    :  Integer;
	xLoc, yLoc : Real;

  PROCEDURE SpinBySixty(SymbolHandle:HANDLE);

BEGIN

RandomNum := (((Random *10) / 2) DIV 1);

GetSymLoc(SymbolHandle, xLoc, yLoc);

HRotate(SymbolHandle, xLoc, yLoc, (RandomNum * 60) );

	END;


BEGIN
       ForEachObject(SpinBySixty, ((S='HEX')));
END;



RUN(RandomRotate);

 

  • Like 1

Share this post


Link to post

Cool, thanks! This gets me by for now. One thing I noticed is that it doesn't seem to work when the Symbols are inside of another Symbol, even if you're inside the parent Symbol editing mode. (In this case I have a bunch of bolt heads on an metal industrial door; the bolt symbols are inside of the door symbol. All 2D.) If I copy out the boltheads to the top level, run the script, then paste back into the door symbol it works fine. :)

 

For future use, is there a way to alter the script so that it affects selected objects rather than operating by symbol name? That way you could:

  • Perform the operation on multiple different symbol definitions at once.
  • Perform the operation on some but not all of a particular symbol.
  • Run the script without having to go inside the script and specify the symbol name beforehand.
  • Include non-symbol objects such as rectangles, polygons, etc.

 

I wish I knew scripting, but not yet, unfortunately...

Share this post


Link to post

Yes.  All of those are possible :D

 

This script was a response to someone who needed a specific rotation solution.

 

But you could have it operate on just selected objects, or whatever criteria you need.

Share this post


Link to post

Perhaps this one is closer to what you want.

 

It will rotate all visible selected objects by a random amount between 0 and 90°. If used inside a group (edit mode), only the selected objects in the group are rotated. If used inside a Symbol Definition (edit mode), only selected objects inside the symbol definition are rotated.

 

Test on a backup copy to ensure suitability before using on an active work file to ensure you understand the performance.

 

Procedure RotateRandomEachObject;
{Rotates each selected object in the active layer a random amount <90°}

{Works on selected objects in a layer, symbol definition, or group}

{Symbols and PIOs are rotated around the insertion point}
{Other Objects are rotated around their center point}

{© 2007,2008,2010 Coviana, Inc - Pat Stanford pat@coviana.com}
{© 2017 Pat Stanford pat@coviana.com}
{Licensed under the GNU Lesser General Public License}
{No Warranty Expressed or Implied. Do no operate motor vehicles}
{while using this script.Side effects include baldness and acne.}

Var	X1,Y1	 :Real;

Procedure WithIt(Hd:Handle);
Begin

	If ((GetType(Hd) = 15) or (GetType(Hd)=86)) then GetSymLoc(Hd,X1,Y1)
	else HCenter(Hd,X1,Y1);

	HRotate(Hd,X1,Y1,(90*Random));

End;



Begin
	ForEachObject(WithIt,((InSymbol & VSEL=TRUE)));
End;

Run(RotateRandomEachObject);

 

  • Like 2

Share this post


Link to post
15 hours ago, Pat Stanford said:

Perhaps this one is closer to what you want.

 

It will rotate all visible selected objects by a random amount between 0 and 90°. If used inside a group (edit mode), only the selected objects in the group are rotated. If used inside a Symbol Definition (edit mode), only selected objects inside the symbol definition are rotated.

 

 

YES. This is perfect. Definitely adding this as a command to my workspace. Thank you thank you!

Share this post


Link to post

I've just search in the forum "random rotation symbol" and i find this script! :)

Thank You!

 

Share this post


Link to post

Just stumbled across this (while fighting with randomizing plant rotations in a Landscape Area...).  This is great!  I've made it into a menu command.  Thanks Pat!

Share this post


Link to post

be careful that each selected objet will rotate!  Even objets on another layer !

It gave me some surprises.. :-)

 

Share this post


Link to post

You could change the criteria in the ForEachObject line to include a specific layer if you want to make sure it only works on the active layer.  Or just set your Layer Visibility to Active Only. The VSEL=TRUE criteria is only supposed to operate on visible selected objects.

 

 

Share this post


Link to post
8 hours ago, Pat Stanford said:

You could change the criteria in the ForEachObject line to include a specific layer if you want to make sure it only works on the active layer.  Or just set your Layer Visibility to Active Only. The VSEL=TRUE criteria is only supposed to operate on visible selected objects.

 

Now that you mention it, I did notice one time recently that the script operates on objects which are "selected" on other layers even when the Layer Options are set to "Show Others" and "Show/Snap" others. In these two cases, selected objects on other layers don't display their highlighting, so it's really easy to accidentally rotate something unintentionally.

 

"Snow/Snap/Others" works as one would expect.

 

Here's a video illustrating what I mean: RotateRandomly.mov

(note I'm using a key command for the rotate randomly script... which I've made Cmd+Opt+Shift+?)

 

8 hours ago, Pat Stanford said:

The VSEL=TRUE criteria is only supposed to operate on visible selected objects.

 

Is there a way to change "visible selected objects" to "visible, selected, editable objects"? If not, how do you make the ForEachObject criteria be Active layer only?

 

 

Share this post


Link to post

Andy

 

I have several scripts that use the selected state of objects and run into the same issues you are seeing here.

 

The best solution I've found (because it's easier than rewriting the scripts :)) is to first run another script that deselects everything in the drawing.

 

It's a complicated script.

 

DSelectAll;

That's the whole script.  In this case it's a vectorscript (as opposed to Python).

 

 

Share this post


Link to post
47 minutes ago, michaelk said:

AI have several scripts that use the selected state of objects and run into the same issues you are seeing here.

 

The best solution I've found (because it's easier than rewriting the scripts :)) is to first run another script that deselects everything in the drawing.

 

It's a complicated script.


DSelectAll;

That's the whole script.  In this case it's a vectorscript (as opposed to Python).

 

Hmm, I can't seem to get this to deselect objects on layers that aren't Editable; it only deselects the objects on the Active layer. But I might be doing something wrong? (The goal is to be able to leave Layer Options on Show/Snap Others).

 

Thanks!

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

 

7150 Riverwood Drive, Columbia, Maryland 21046, USA   |   Contact Us:   410-290-5114

 

© 2018 Vectorworks, Inc. All Rights Reserved. Vectorworks, Inc. is part of the Nemetschek Group.

×