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.

4 Likes

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

3 Likes

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()
6 Likes

@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

1 Like

@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

1 Like

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

3 Likes

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

4 Likes

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

1 Like

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

3 Likes

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.
3 Likes

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.

4 Likes

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,

2 Likes