Im trying to sweep a railing profile up a curved stair case, for a reason i cant figure out its twisting on me. My selections have been turning alignment off and making sure Twist Expression is at 0 and I use Basepoint. I attached the file so you can see what im talking about and then copied a test off to the side. If anyone could help me i would appreciate it.
Thank you,
Paul
Solved! Go to Solution.
Solved by leeminardi. Go to Solution.
Would it make any difference if you defined the path as a HELIX rather than a SPLINE? I imagine that would be more accurate as a path, anyway.
Helixes can be a little tricky to define, but first of all there would need to be a known center point. I tried OSNAPping to the CENter of something to find such a place, but there are a whole passel of 'em. Can you tie that down, as a start?
So i believe i developed the radius of the sections of rail.
Background history, this stair was scanned and we imported it into autocad, thats why the lines are not smooth and the same radiuses
see attached
I wrote the attached vlisp program to give me a better feel for the curvature of a spline. It determines the instantaneous radius of curvature at a 100 points along a spline. In addition to numerical values the program will draw lines showing either lines from a point on the spline to the center of curvature for that point (e.g., short lines are small radii, flat sections long lines), or curvature (short lines indication near flat curvature). The latter option requires a scale factor to aid visualization.
I ran the program on your spline wth the following results.
Note that the area circled in red is fairly flat and the spline area circled in green has the smallest radii.
YOu may want to use the numerical values to determine an approximate radius to use.
(defun C:SplineCurvatue (/ path inc n osm par der1 der2 curva p perp normv p2 sf
curveType ans)
; = Degree Of Curvature - Lines
; Creates curvature lines or radius-of-curvature lines
; normal to a spline.
; LRM 8/18/2022 edited to place curvature vectors outside
(setq
path (car (entsel))
inc (/ (vlax-curve-getEndParam path) 100)
n 0
osm (getvar 'osmode)
)
(setvar 'osmode 0)
(setvar "cmdecho" 0)
(initget "y n")
(setq ans (getkword "Do you want radius-of-curvature instead of curvature? [y/n] <n>: "))
(if (= ans "y")
(setq curveType 1)
(setq curveType 2
sf (getdist "Enter scale factor.")
)
)
(repeat 100
(setq par (* inc n))
(setq der1 (vlax-curve-getfirstDeriv path par)
der2 (vlax-curve-getSecondDeriv path par)
)
; calculate curvature at point par
(setq d (distance '(0 0 0) (cross der1 der2)))
(if (> (abs d) 1.0e-15)
(progn
(setq curva (/ (expt (distance '(0 0 0) der1) 3) d))
(if (= curveType 2)
(setq curva (* -1. (* sf (/ 1. curva))))
)
(princ "\n") (princ n)
(princ " curvature = ") (princ curva)
(setq p (vlax-curve-getPointAtParam path par)
perp (unitv (cross der1 (cross der2 der1)))
normv (mapcar '* perp (list curva curva curva))
p2 (mapcar '+ p normv)
)
(command "_.line" p p2 "")
) ; end progn
)
(setq n (1+ n))
)
(setvar 'osmode osm)
(setvar "cmdecho" 1)
(princ)
)
;;; Compute the cross product of 2 vectors a and b
(defun cross (a b / crs)
(setq crs (list
(- (* (nth 1 a) (nth 2 b))
(* (nth 1 b) (nth 2 a))
)
(- (* (nth 0 b) (nth 2 a))
(* (nth 0 a) (nth 2 b))
)
(- (* (nth 0 a) (nth 1 b))
(* (nth 0 b) (nth 1 a))
)
) ;end list
) ;end setq c
) ;end cross
(defun unitV ( v / d)
(setq d (distance '(0 0 0) v)
d (mapcar '/ v (list d d d))))
On a related note, I have found that I would prefer to use loft rather than sweep for 2D shapes swept along a spline. Loft can provide better local control of twist. The following program is a work-in-progress and not ready for prime time but you may find it helpful.
Begin by defining a block with the profile (a polyline) you would like to sweep. Working in world coordinates make sure that the Z axis is perpendicular to the plane of th polyline.
Use the program to position multiple copies of the block along the spline. You can modify the twist of individual sections by setting the UVS to OBject. Then use the standard 2D rotate command to adjust the twist for that section. When you have the sections twisted as desirered explode all the section and use the loft command.
Here's the results I got bor a modified section of your railing. I had to simplify the top of the section to get results.
(defun C:test (/ nsec blockname twist tottwist path inc n osm par der1
der2 p p1 p2 vy vz vx p3)
; draft version
; Adds blocks along a spline. The user specifies the number of blocks and
; the total amount of twist over the length of the spline. The Z axis of the block
; is tangent to the spline.
; LRM 5/1/2023 revised 6/4/2024
(command "ucs" "w")
(setvar 'osmode 0)
(setq nsec (getint "\nEnter number of sections: "))
(setq nsec (- nsec 1))
(setq blockname (getstring "\nEnter block name: "))
(setq twist (getreal "\nEnter start twist angle: "))
(setq tottwist (getreal "\nENter total twist start to end: "))
(setq
path (car (entsel))
inc (/ (vlax-curve-getEndParam path) nsec)
n 0
osm (getvar 'osmode)
)
(setvar "cmdecho" 0)
(repeat (+ nsec 1)
(setq par (* inc n))
(setq der1 (vlax-curve-getfirstDeriv path par)
der2 (vlax-curve-getSecondDeriv path par)
p (vlax-curve-getPointAtParam path par)
)
(setq p1 (mapcar '+ p (unitv (cross der1 der2))))
(setq p2 (mapcar '+ p (unitv der1)))
(setq vy (unitv (mapcar '- p1 p)))
(setq vz (unitv (mapcar '- p2 p)))
(setq vx (unitv (cross vy vz)))
(setq p3 (mapcar '- p vx))
(command "_point" "_non" p)
(command "_point" "_non" p2)
(command "_point" "_non" p3)
(command "-insert" blockname '(0 0 0) 1 1 0)
(command "_align" "last" "" '(0 0 0) p '(1 0 0) p1 '(0 0 -1) p2 "n")
(if (> (abs twist) 0.00001)
(command "rotate3d" "last" "" "2" p p2 twist)
)
(setq twist (- twist (/ tottwist nsec)))
(setq n (1+ n))
) ; end repeat
(setvar 'osmode osm)
(setvar "cmdecho" 1)
(princ)
)
;;; Compute the cross product of 2 vectors a and b
(defun cross (a b / crs)
(setq crs (list
(- (* (nth 1 a) (nth 2 b))
(* (nth 1 b) (nth 2 a))
)
(- (* (nth 0 b) (nth 2 a))
(* (nth 0 a) (nth 2 b))
)
(- (* (nth 0 a) (nth 1 b))
(* (nth 0 b) (nth 1 a))
)
) ;end list
) ;end setq c
) ;end cross
(defun unitV (v / d)
(setq d (distance '(0 0 0) v)
d (mapcar '/ v (list d d d))
)
)
in the attached in top view a 3P circle fits the inner radius of the step.
QSELECT surfaces of the steps and delete leaving the regions which are the tops of the steps extruded down to solids
as in one step shown. UNION together for one solid. The bottom sloping surface I did not work with.
if you extruce the circle down and subtract from the step it makes a nice smooth cylindrical inner surface on the step solid.
a helix path for the railing will now be circular based on the circle radius and everything should fit together.
appears you have adequate data to redraw the steps.
Can't find what you're looking for? Ask the community or share your knowledge.