arcobaleno Posted February 14 Share Posted February 14 (edited) Hello everyone, I am trying to write a script to select every wall objects which have the same angle as the currently selected object. How can I include the wall objects with reverse direction? For example: If the selected object has an angle of 0°, then the walls with an angle of -180° should be selected as well (which is not the case in my script). Actually I want to select parallel walls only, regardless of the direction. Is there a vectorscript function for this, or a function that gets the wall direction? I was looking for a way to invert the angle values with modulo division, for example: -10° %180 = 170°, and 10° % -180 = -170°. I also tried to convert the angle in vector with vs.Ang2Vec, reverse and convert it back, but I couldn't get it to work for every angle value. Plus it seems that some rounding errors would also occur. My poor maths and programming skills are being quite challenged here! Thank you very much for your help! pythonscript: import vs Rotation = vs.HAngle(vs.FSActLayer()) vs.DSelectAll() def SelectIdenticalWallAngle(h): ObjType = vs.GetTypeN(h) ObjAngle = vs.HAngle(h) if (ObjType == 68): #Wall Type = 68, as defined in Appendix if ObjAngle == Rotation: vs.SetSelect(h) vs.ForEachObjectInLayer(SelectIdenticalWallAngle, 1,1,0) Edited February 14 by arcobaleno Quote Link to comment
JBenghiat Posted February 14 Share Posted February 14 In this case, I think you can just increase the conditions under which you would select the object: OjbAngle == Rotation or OjbAngle == Rotation + 180 or OjbAngle == Rotation - 180 Quote Link to comment
Pat Stanford Posted February 14 Share Posted February 14 And you might want to use some sort of a range rather than an exact comparison. Binary math is often not exact. So if you had walls at 35.000001 degree and 34.9999999 degree you would probably want them to match. But s straight equals would not do it. You would either need to round the angles to the number of decimal places you need or use a double comparison (like Joshua suggests for the flipped versions) of > 34.999 and < 35.001 Or something similar. Quote Link to comment
arcobaleno Posted February 14 Author Share Posted February 14 Wow thank you so much for the speedy replies! By the way, I have learnt a lot about scripting from reading your posts on this forum, thank you both for your dedication! I tried the double comparison as described above, surprisingly all walls are then selected, regardless of the angle. I was thinking about a lazy workaround: Duplicate the first object and rotate by 180°, get its angle, then use double comparison. Trying quickly to modify the script as following, unfortunately it is still not working with every angles. @Pat StanfordActually I wanted to select the angle precisely, the purpose would be to identify Walls with minimal displacement, like between 35.0000° and 34.9999° as you described. But I will look further in the direction you describe. Thank you a lot for your help! import vs WallObj = vs.FSActLayer() Rotation = vs.HAngle(WallObj) if Rotation < 0: #not sure about this RotAngle = 180 else: RotAngle = -180 WallDuplicate = vs.Duplicate(0,0) vs.SetSelect(WallDuplicate) DuplRotate = vs.Rotate(RotAngle) RotationReverse = vs.HAngle(DuplRotate) vs.DeleteObjs() vs.DSelectAll() def SelectIdenticalWallAngle(h1): ObjType = vs.GetTypeN(h1) ObjAngle = vs.HAngle(h1) if (ObjType == 68): if ObjAngle == Rotation or ObjAngle == RotationReverse: vs.SetSelect(h1) vs.ForEachObjectInLayer(SelectIdenticalWallAngle, 1,2,0) Quote Link to comment
Pat Stanford Posted February 14 Share Posted February 14 I was thinking about something like this. Sorry if my Python is not very good. Change the accuracy to determine how close to the same angle you want. accuracy = 0.0001 if ((ObjAngle < Rotation + accuracy) and (ObjAngle > Rotation - accuracy)) or ((ObjAngle < RotationReverse + accuracy) and (ObjAngle > RotationReverse - accuracy)): Quote Link to comment
MullinRJ Posted February 15 Share Posted February 15 In the same vane as @Pat Stanford's example, but using abs(a-b <Tol) to combine the (a < b+Tol) and (a > b-Tol) into one expression, you will need three comparisons. This compares Rotation to Ang+0, Ang+180, and Ang-180, and tests them against a tolerance. Tol = 0.001 if (abs(ObjAng - Rotation) < Tol) or (abs(ObjAng - Rotation + 180) < Tol) or (abs(ObjAng - Rotation - 180) < Tol): I think this covers all options. Change the tolerance to change the sensitivity of acceptable values. If you want to include values at the tolerance limit, then use "<=" in place of "<". HTH, Raymond 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.