Andy Broomell Posted August 10, 2017 Share Posted August 10, 2017 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. Quote Link to comment
zoomer Posted August 10, 2017 Share Posted August 10, 2017 I don't know the way but it is highly needed Quote Link to comment
Vectorworks, Inc Employee PVA - Admin Posted August 10, 2017 Vectorworks, Inc Employee Share Posted August 10, 2017 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. Quote Link to comment
michaelk Posted August 10, 2017 Share Posted August 10, 2017 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); 1 Quote Link to comment
Andy Broomell Posted August 10, 2017 Author Share Posted August 10, 2017 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... Quote Link to comment
michaelk Posted August 10, 2017 Share Posted August 10, 2017 Yes. All of those are possible 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. Quote Link to comment
Pat Stanford Posted August 11, 2017 Share Posted August 11, 2017 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); 2 Quote Link to comment
Andy Broomell Posted August 11, 2017 Author Share Posted August 11, 2017 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! Quote Link to comment
Nico_be Posted February 8, 2018 Share Posted February 8, 2018 I've just search in the forum "random rotation symbol" and i find this script! Thank You! Quote Link to comment
willofmaine Posted April 6, 2018 Share Posted April 6, 2018 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! Quote Link to comment
Nico_be Posted April 6, 2018 Share Posted April 6, 2018 be careful that each selected objet will rotate! Even objets on another layer ! It gave me some surprises.. :-) Quote Link to comment
Pat Stanford Posted April 6, 2018 Share Posted April 6, 2018 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. Quote Link to comment
Andy Broomell Posted April 6, 2018 Author Share Posted April 6, 2018 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? Quote Link to comment
michaelk Posted April 6, 2018 Share Posted April 6, 2018 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). Quote Link to comment
Andy Broomell Posted April 6, 2018 Author Share Posted April 6, 2018 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! Quote Link to comment
setdesigner Posted May 27, 2022 Share Posted May 27, 2022 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); Quote Link to comment
Pat Stanford Posted May 27, 2022 Share Posted May 27, 2022 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); 1 Quote Link to comment
setdesigner Posted May 27, 2022 Share Posted May 27, 2022 Many thanks, this works perfectly. So nice, and thanks for a quick fix, I am in middle of designing a set and I can achieve what I had in mind ! 1 Quote Link to comment
Recommended Posts
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.