Angle of rotation around a link element

Angle of rotation around a link element

dean.hayton
Participant Participant
463 Views
2 Replies
Message 1 of 3

Angle of rotation around a link element

dean.hayton
Participant
Participant

Hi All,

 

I'm trying to find the rotation of linked service elements so I can rotate a family to align with them. I'm struggling with the logic of getting the rotation as it seems in some cases the family wants to be rotated anti-clockwise and others clockwise. The image bellow is 2 vertical cable ladders demonstrating these situations. I also need to consider the transform of the link model but again, I'm not sure of the approach here. 

 

Thanks

0 Likes
464 Views
2 Replies
Replies (2)
Message 2 of 3

jeremy_tammik
Alumni
Alumni

Yes, whoever creates the family definition can also define its coordinate system, so that may vary from one definition to another. I am not sure whether best practices are defined for cable ladders; I would suggest researching and following those. However, generally, rotations are always calculated in the same direction for all Revit BIM elements. It is hard to say more without seeing more exactly how you are measuring the angles you display, and what you are trying to achieve. A code snippet or two might help clarify.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 3

dean.hayton
Participant
Participant

Hi Jeremy, thanks for your reply. I have been using a couple different approaches for different types of vertical cable trays (standard family and MEP Fabrication families). In both cases there is the problem of how do I know if an angle needs to be negative or positive, or perhaps add 360° to an angle to rotate it in the correct direction. 

 

#method 1 for fabrication elements
def GetSignedAngleOnXY(basis, vec):
	angle = math.atan2(vec.Y,vec.X) - math.atan2(basis.Y,basis.X)
	return angle * (180/math.pi)

def GetTransformRotation(fabrication):
	vector = fabrication.GetTransform().BasisZ
	return GetSignedAngleOnXY(XYZ.BasisY, vector)
	

#method 2 for standard families
def get_service_rotation(serviceelement, link_trans):
	elem_location = serviceelement.Location
	options = Options()
	options.DetailLevel = ViewDetailLevel.Medium
	result = serviceelement.get_Geometry(options).GetTransformed(link_trans)
	solids = [s for s in result]
	solid = solids[0]
	
	matchingFace = None
	for face in solid.Faces:
		if face.FaceNormal.IsAlmostEqualTo(elem_location.Curve.Direction):
			matchingFace = face
	
	vector = matchingFace.FaceNormal
	origin = matchingFace.Origin
	
	#direction = origin + vector
	direction = XYZ(origin.X + vector.X, origin.Y + vector.Y, origin.Z + vector.Z)
	
	min = 1e12
	max = -1e12
	max_edge = None
	for edgeArrays in matchingFace.EdgeLoops:
		for edge in edgeArrays:
			si_length = edge.ApproximateLength * 304.8
			if si_length > max:
				max = si_length
				max_edge = edge
			if si_length < min:
				min = si_length

	is_north = XYZ.BasisY.DotProduct(max_edge.AsCurve().Direction) > 0
	rotation = int(max_edge.AsCurve().Direction.AngleTo(XYZ.BasisY) * 180 / 3.14)
	rotation = rotation if is_north else abs(rotation - 180)
	return rotation


#get rotation angle with either method
angle_rads = #get angle with method 1 or 2

#create axis to rotate around
axis = Line.CreateBound(pnt_xyz, XYZ(pnt_xyz.X, pnt_xyz.Y, pnt_xyz.Z + 1))

#rotate the element
ElementTransformUtils.RotateElement(doc, horizfam.Id, axis, angle_rads)

 

 

0 Likes