Normal vector Revit API

Hi All,

How to get Normal curve with Revit API if I have the following code?

St_pt = XYZ(2,2,0)
End_pt = XYZ(2,2,5)
line = Line.CreateBound(St_pt , End_pt )

Thanks.

You can use the ComputeDerivatives method from the Curve class, then interrogate the second derivative of the tangent vector by assessing the BasisY of the returned Transform object.

Hello,
here is what i tried
Dynamo makes our job easier all the same

import sys
import clr
clr.AddReference("RevitAPI")
import Autodesk 
from Autodesk.Revit.DB import *
St_pt = XYZ(2,2,0)
End_pt = XYZ(2,2,5)
vec_a=XYZ(2,2,0)
line = Line.CreateBound(St_pt , End_pt)
a=XYZ(line.ComputeDerivatives(0.0,True))
vec_tang=a.BasisX
vec_norm=a.BasisY
vec_binorm=a.BasisZ
d=line.Direction
my_dico={"Point Revit-->":St_pt,
"Vector Revit-->":vec_a
,"Line Revit-->":line,
"vec_tang-->":vec_tang,
"vec_norm-->":vec_norm,
"vec_binorm-->":vec_binorm,
"line_direction-->":d}
OUT = my_dico

Cordially
christian.stan

Lines don’t have plane, so it’s not works correctly with ComputeDerivatives() (return a Zero Vector)

a solution with the crossproduct (with BasisZ vector)

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry  as DS 

clr.AddReference("RevitAPI")
import Autodesk 
from Autodesk.Revit.DB import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion) 

st_pt = XYZ(2,2,0)
end_pt = XYZ(5,9,1)

line = Line.CreateBound(st_pt , end_pt)
vectorL = line.Direction
vectorN = vectorL.CrossProduct(XYZ.BasisZ)

OUT = line.ToProtoType(), vectorN.ToVector()

@christian.stan

I’ve run your script and I got this error!!??

image

Thanks.

hello, I have to read the small lines with a rested head, I think the 2nd script is more correct than the first, even if not adapted to the lines

import sys
import clr
clr.AddReference("RevitAPI")
import Autodesk 
from Autodesk.Revit.DB import *
St_pt= XYZ(1,1,1)
End_pt= XYZ(5,5,5)

line = Line.CreateBound(St_pt,End_pt)
a=line.ComputeDerivatives(0.0,True)
vec_tang=a.BasisX
vec_norm=a.BasisY
vec_binorm=a.BasisZ
d=line.Direction
my_dico={"Point Revit-->":St_pt,
"Line Revit-->":line,
"vec_tang-->":vec_tang,
"vec_norm-->":vec_norm,
"vec_binorm-->":vec_binorm,
"line_direction-->":d}
OUT = my_dico,a.Origin

Cordially
christian.stan

@c.poupin

We can’t got a normal vector if the curve is straight??

st_pt = XYZ(2,2,0)
end_pt = XYZ(2,2,5)

line = Line.CreateBound(st_pt , end_pt)
vectorL = line.Direction
vectorN = vectorL.CrossProduct(XYZ.BasisZ)

OUT = vectorN

image

So how the normal vector is obtained in the case of straight rebar? (ex: column rebar)

Thanks.

it seems to me that as your direction vector is in fact your tangent vector as you make a cross product of vector Z and itself is carried by vector Z, they are therefore collinear this is how you demonstrate from my old memories of math, you have to select another XYZ.BasisX or Y will do I think, I’m testing…
edit:

Cordially
christian.stan

the Normal of a vertical line could be any vector based on the XY plane

@c.poupin

but how we can extract it from the curve itself if ths Cross Product give 0 ??

Thanks.

There isn’t a consistent normal for a line; as @c.poupin noted, it could be anything without a Z component, and the Tangent would be any vector perpendicular to that.

Gather the normal from the work plane which defined the element, it’s sketch, or the host.

I think that as dynamo provides one, it is possible via the api
looking at the dynamo nodes or maybe using them


edit:but it’s true that when you have a face it’s better to define a normal
Cordially
christian.stan

Yeah - the Dynamo geometry engine makes some assumptions about what the normal is; however that geometry library isn’t in the Revit API, and the assumed normal os often incorrect (in particular with vertical curves).

Line has a Direction property so:

St_pt = XYZ(2,2,0)
End_pt = XYZ(2,2,5)
line = Line.CreateBound(St_pt , End_pt )
direction = line.Direction.Normalize();

For a more general purpose use, i.e. any curve, do what’s being suggested above:

  1. Compute the derivatives.
  2. Get the BasisX of the returned transform.

Wouldn’t this be the tangent, not the normal?

Yep, I made the wrong assumption re the OP! @c.poupin is the solution in that case: @REDO10 you need to know your up-vector (or plane normal) to be able to compute a normal from a line.

Hello,

1.- Create a plane: CreateByNormalAndOrigin(CurveDirection, Origin)
2.- Get the XVec property of the plane.
3.- Get the cross product: XVec.CrossProduct(CurveDirection)

Regards,