Skip to content

Instantly share code, notes, and snippets.

@pgolay
Created May 26, 2022 21:23
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save pgolay/2bf0f4cb6add43d2db4ccede0d30cb10 to your computer and use it in GitHub Desktop.
Find and mark the slope of a curve from the world XY plane.
import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
import System.Drawing.Color
def CurveSlope():
line_color = Rhino.ApplicationSettings.AppearanceSettings.FeedbackColor
dot_color = Rhino.ApplicationSettings.AppearanceSettings.TrackingColor
oref = rs.GetObject('Select a curve', 4, preselect=True, subobjects=True)
if not oref: return
idx =oref.GeometryComponentIndex.Index
if idx == -1:
crv = oref.Geometry()
else:
crv = oref.Geometry().ToNurbsCurve()
vecScale = 10
def ProjectVectorToPlane(vecDir, plane):
pt = plane.ClosestPoint(plane.Origin + vecDir)
vecTemp = pt-plane.Origin
vecTemp.Unitize()
return vecTemp
def GetPointDynamicDrawFunc( sender, args ):
pt = args.CurrentPoint
#draw a line from the first picked point to the current mouse point
args.Display.DrawPoint( pt)
tan = crv.TangentAt(crv.ClosestPoint(pt)[1])
tan *= vecScale
proj = ProjectVectorToPlane(tan, Rhino.Geometry.Plane.WorldXY)
ang = Rhino.Geometry.Vector3d.VectorAngle(tan,proj)
ang = Rhino.RhinoMath.ToDegrees(ang)
args.Display.DrawLine(pt, pt+tan, line_color, 2)
args.Display.DrawDot((pt + (pt+tan))/2, str(round(ang , 3))+ chr(176), dot_color, line_color)
while True:
vecScale = 1
if sc.sticky.has_key('CRV_SLOPE_SCALE'):
vecScale = sc.sticky['CRV_SLOPE_SCALE']
label = False
if sc.sticky.has_key('CRV_SLOPE_LABEL'):
label = sc.sticky['CRV_SLOPE_LABEL']
line = False
if sc.sticky.has_key('CRV_SLOPE_LINE'):
line = sc.sticky['CRV_SLOPE_LINE']
gp = Rhino.Input.Custom.GetPoint()
gp.Constrain(crv,False)
gp.DynamicDraw += GetPointDynamicDrawFunc
gp.AcceptNumber(True,False)
opScale = Rhino.Input.Custom.OptionDouble(vecScale)
gp.AddOptionDouble('LineScale', opScale)
opLabel = Rhino.Input.Custom.OptionToggle(label, 'No', 'Yes')
gp.AddOptionToggle('AddLabels', opLabel)
opLine = Rhino.Input.Custom.OptionToggle(line, 'No', 'Yes')
gp.AddOptionToggle('TangentLines', opLine)
rc = gp.Get()
if gp.CommandResult()!=Rhino.Commands.Result.Success:
return gp.CommandResult()
if rc==Rhino.Input.GetResult.Option:
vecScale = opScale.CurrentValue
sc.sticky['CRV_SLOPE_SCALE'] = vecScale
label = opLabel.CurrentValue
sc.sticky['CRV_SLOPE_LABEL'] = label
line = opLine.CurrentValue
sc.sticky['CRV_SLOPE_LINE'] = line
continue
elif rc==Rhino.Input.GetResult.Number:
vecScale = gp.Number()
sc.sticky['CRV_SLOPE_SCALE'] = vecScale
continue
elif rc==Rhino.Input.GetResult.Point:
pt = gp.Point()
tan = crv.TangentAt(crv.ClosestPoint(pt)[1])
tan *= vecScale
proj = ProjectVectorToPlane(tan, Rhino.Geometry.Plane.WorldXY)
ang = Rhino.Geometry.Vector3d.VectorAngle(tan,proj)
ang = Rhino.RhinoMath.ToDegrees(ang)
angStr = 'Curve slope angle from WorldXY = ' + str(str(round(ang , 3))+ chr(176)) +' at the pick location.'
print angStr
if label:
rs.AddTextDot(str(str(round(ang , 3))+ chr(176)), pt)
if line:
rs.AddLine(pt, pt + tan)
continue
if __name__ == '__main__':CurveSlope()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment