How to get the ange between two XYZ points

i was trying to calculate the angle of a inclined duct. I used AngleTo method. i am not getting an exact angle. below is my code. anybody can explain me what is wrong in my code.

Version:0.9 StartHTML:00000097 EndHTML:00003914 StartFragment:00000199 EndFragment:00003876 # import libraries
import clr
clr.AddReference(‘RevitServices’)
clr.AddReference(‘RevitAPI’)
clr.AddReference(‘RevitAPIUI’)
from RevitServices import *
from RevitServices.Persistence import DocumentManager
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import *
doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

def itof(inc):
ft = (inc / 12.00)
return ft

def dtor(d):
rad = (d * 0.017453292519943295)
return rad

def rtod®:
deg = (r * 57.2958)
return deg

obj = uidoc.Selection.PickObject(ObjectType.Element, “Select duct or pipe”)
objid = obj.ElementId
pt1 = obj.GlobalPoint
sel = doc.GetElement(obj)
loc = sel.Location.Curve
st_point = loc.GetEndPoint(0)
end_point = loc.GetEndPoint(1)
ang = st_point.AngleTo(end_point)

ang1 = end_point.AngleTo(st_point)

de = rtod(ang)

OUT = de

isn’t this just the ‘slope’ parameter of the duct ?

no, i was looking for the angle of ducts or pipes from xy plane. no relation with slopes

I’m not sure how Revit is calculating the angle, but you can do it manually like this:

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI.Selection import *
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager

import math

doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

obj = uidoc.Selection.PickObject(ObjectType.Element, 'Select duct or pipe')
sel = doc.GetElement(obj.ElementId)
loc = sel.Location.Curve
pt0 = loc.GetEndPoint(0)
pt1 = loc.GetEndPoint(1)

x0 = pt0.X
y0 = pt0.Y
z0 = pt0.Z
x1 = pt1.X
y1 = pt1.Y
z1 = pt1.Z

z_diff = z1-z0
dist = math.sqrt((x1-x0)**2 + (y1-y0)**2)

rads = math.atan(z_diff/dist)
degs = math.degrees(rads)

OUT = degs

i think your code is to calculate the slope. i was looking for angle of a duct or pipe.

image

Is this in plan or elevation view? Here is an example in elevation view using the above code:

it is in plan view

there is a method AngleTo. but when i do, i am not getting exact angle.
image

If I understand correctly, you are trying to get the angle between your duct and an X vector (which is the reference line in your screenshot). I think the issue is that XYZ is used both for points and vectors. The AngleTo method is calculating the angle between two vectors. In this case, the vector for each point starts at the project’s origin (0,0,0). Here’s a very poorly illustrated graphic to explain further:

I would recommend doing a manual calculation in this case rather than using one of the API’s methods.

I tried trigonometric equations. but i got wrong value

This should work:

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI.Selection import *
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager

import math

def dist(p1, p2):
	"""Calculates the distance between two points in 2D (XY) space"""
	x1 = p1.X
	y1 = p1.Y
	x2 = p2.X
	y2 = p2.Y
	return math.sqrt((x2-x1)**2 + (y2-y1)**2)

doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

obj = uidoc.Selection.PickObject(ObjectType.Element, 'Select duct or pipe')
sel = doc.GetElement(obj.ElementId)
loc = sel.Location.Curve
pt0 = loc.GetEndPoint(0)
pt1 = loc.GetEndPoint(1)

diff_x = abs(pt1.X - pt0.X)
dist_xy = dist(pt0, pt1)

rads = math.acos(diff_x/dist_xy)
degs = math.degrees(rads)

OUT = degs

This uses the X coordinate of each point as the first vector and the line between both points as the second vector. Using these, we calculate the arc cosine, which is given in radians, and convert that to degrees.

2 Likes

you could use the Clockwork node Vector.AltitudeAndAzimuth

you are measuring the azimuth (the angle from the xy plane is slope)

1 Like

or using OOTB nodes

Nice solution @Andrew_Hannell. I always get caught up in “ask a question about python, answer it in python”. OOTB nodes are certainly a viable solution here.