Jump to content

Random Rotation


Recommended Posts

  • Vectorworks, Inc Employee

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.

Link to comment

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
Link to comment

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...

Link to comment

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
Link to comment
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!

Link to comment
  • 5 months later...
  • 1 month later...
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?

 

 

Link to comment

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).

 

 

Link to comment
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!

Link to comment
  • 4 years later...

I have being usig this script  a lot, and modified it to 20º rotation.

Now I need a random +/- 20º, any idea how to scipt it ?

Thanks !

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,(20*Random));

End;



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

Run(RotateRandomEachObject);

 

Link to comment

Try this.  There may be some very slight bias toward either positive or negative, but it seems to do OK.

Procedure RotateRandomEachObject;

{Updated May 27, 2022 to do positive and negative rotation.}
{Rotates each selected object in the active layer a random amount <20°}

{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}
{© 2022 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,R1	 :Real;

Procedure WithIt(Hd:Handle);
Begin

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

	IF Random>=0.501 Then R1:=1 Else R1:=-1;
	HRotate(Hd,X1,Y1,(20*Random*R1));

End;



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

Run(RotateRandomEachObject);

 

  • Like 1
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...