Hello All,
Due to modeling purposes, I need to convert a 3D polyline to a spline. What I have been doing is:
- change polyline fit/smooth to cubic from properties
- convert polyline to spline by typing spline -> object
- method -> fit from properties
You can see the original 3D polyline (green) and the resulting spline (magenta) in the attached drawing.
When I zoom in and measure the distance between the two entities at different points along them, at some points the perpendicular distance exceeds 5 millimeters, and I want to ensure the deviation remains under 1 millimeter or even less.
I know I can change the knot parameterization of the spline, and this does help at some locations, but the difference increases at others.
Why is there a 5.6 mm difference between the spline fit point and 3D polyline vertex, as measure in the attached drawing?
Now, I can go and manually stretch the fit point to coincide with the vertex. Also, I can add fit points between existing ones to drag the spline closer to the original 3D poly.
However, some of my polys are really long, and it is very time-consuming to do this manually while measuring points along the entities to make sure the distance stays small enough.
Does anyone have ideas how to automate this process? For example a lisp that would maybe take the original vertex points, add say maybe 3 (not too many) new ones between them, and then generate a spline while making sure the deviation is less than the set value of 1mm?
I am using AutoCAD 2013. Any help is greatly appreciated! 🙂
Thanks in advance and have a great weekend,
Samu
Solved! Go to Solution.
Solved by phanaem. Go to Solution.
Thanks for your reply !I found this this old CadTutor thread
http://www.cadtutor.net/forum/archive/index.php/t-26982.html
in which Lee Mac writes in response to Ritchy:
"I have a request do. Is it possible to write the points out to file from a 3D poly not only from the vertexes but from points with a certain distance along the 3dpolyline?
This is not directly possible with the current program ( http://lee-mac.com/ptmanager.html ), though, as an alternative indirect method, you could use the AutoCAD Measure command to generate points at specific distances along your object, then use my Point Manager program (or AutoCAD's Data Extraction) to extract the coordinates of these points to file."
What I am thinking of doing is:
1. Adding points to the existing vertices of the 3D poly
2. Using to measure to add new points at a reasonable interval along the poly
3. Extracting the points coordinates
4. Using the coordinates to create a new spline
I think this method should work pretty well. Still curious to hear of any other more streamlined ways that anyone can think of though!
Thanks,
Samu
This should give you exact correct result...
If you're satisfied with result mark this topic as solved...
(defun c:3p2spl ( / *error* line2spl loop pl e s ss sss ) (vl-load-com) (defun *error* ( msg ) (vla-endundomark (vla-get-activedocument (vlax-get-acad-object))) ) (defun line2spl ( e / sp ep d ) (setq sp (cdr (assoc 10 (entget e))) ep (cdr (assoc 11 (entget e))) d (distance sp ep) ) (entdel e) (entmakex (list '(0 . "SPLINE") '(100 . "AcDbEntity") '(100 . "AcDbSpline") '(210 0.0 0.0 1.0) '(71 . 1) '(73 . 2) '(42 . 1.0e-010) '(43 . 1.0e-010) '(40 . 0.0) '(40 . 0.0) (cons 40 d) (cons 40 d) (cons 10 sp) (cons 10 ep) ) ) ) (vla-startundomark (vla-get-activedocument (vlax-get-acad-object))) (setq loop T) (setq sss (ssget "_I")) (if (and sss (eq (cdr (assoc 0 (entget (setq pl (ssname sss 0))))) "POLYLINE") (< 7 (cdr (assoc 70 (entget pl))) 14)) (setq loop nil)) (while loop (setq pl (car (entsel "\nPick 3DPOLYLINE to convert it to SPLINE"))) (if (and (eq (cdr (assoc 0 (entget pl))) "POLYLINE") (< 7 (cdr (assoc 70 (entget pl))) 14)) (setq loop nil)) ) (setq e (entlast)) (command "_.explode" pl "") (setq ss (ssadd)) (while (setq e (entnext e)) (if (eq (cdr (assoc 0 (entget e))) "LINE") (progn (setq s (line2spl e)) (ssadd s ss) ) ) ) (command "_.join" (ssname ss 0) ss "") (*error* nil) (princ) )
M.R.
Hello
IMO, a tolerance of 5.6mm to a +38000 distance is pretty fair... But I remember a time when it wasn't enugh for me too...:)
Anyway, here is a lisp that will draw a spline thru a polyline vertices, adding more points (3 exactly) when a segmet of polyline is longer than, say, 5% of total length.
That doesn't assure you a tolerance less than 1mm, but is closer to polyline than in your sample.
(defun C:PL2SPL ( / ss i) (if (setq ss (ssget '((0 . "*POLYLINE")))) (repeat (setq i (sslength ss)) (make_spline (pl_list (ssname ss (setq i (1- i)))) ) ) ) (princ) ) (defun pl_list (e / r i j lg) (setq lg (* 0.05 (vlax-curve-getdistatparam e (vlax-curve-getendparam e)))) (repeat (setq i (1+ (fix (vlax-curve-getEndParam e)))) (setq r (cons (cons 11 (vlax-curve-GetPointAtParam e (setq i (1- i)))) r)) (if (and (> i 0) (> (- (vlax-curve-getdistatparam e i) (vlax-curve-getdistatparam e (1- i))) lg) ) (repeat (setq j 3) (setq r (cons (cons 11 (vlax-curve-GetPointAtParam e (+ (1- i) (* 0.25 j)))) r) j (1- j) ) ) ) ) r ) (defun make_spline (l) (entmake (append (list '(0 . "SPLINE") '(100 . "AcDbEntity") '(100 . "AcDbSpline") '(70 . 1) '(71 . 3) (cons 74 (length l)) '(44 . 1.0e-005) ) l ) ) )
You guys are incredible! This is exactly what I was looking for!
Marko, I don't know how your code accomplishes what so many other lisps and methods I have tried fail at doing... To get the spline *exactly* like the 3D polyline. If you would not mind elaborating on the code, that'd be great!
Thanks so much - I really appreciate it 🙂
Samu
very usefull lisp for surveyor or survey firms for genrating imagenary points with profile of road, drain, river etc.
thanks.....
Can't find what you're looking for? Ask the community or share your knowledge.