Jump to content

Select walls with same angle


Recommended Posts

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 by arcobaleno
Link to comment
  • arcobaleno changed the title to Select walls with same angle

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.

Link to comment

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)

 

 

 

 

Link to comment

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

 

Link to comment

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

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