View Full Version : How to Change elliptical arcs into Polylines
Lions60
2006-07-20, 06:20 PM
I have written a program to change elliptical arcs into plines, and you would think I could figure out how to trim the arc back to it's original state. Because when the PELLIPSE variable is set to 1 all elliptical arcs become full ellipses. I am trying to figure out a way to either break or trim the arc back to its original state in the drawing.
Here is the code:
(defun e2p( /
old new ;existent and new polyline
sav ;store system variables
cen ;center of ellipse
dep ;axis end point deplacement (relative to cen)
p1 p2 ;first axis enpoints
p3 ;sec. axis endpoint
)
(setvar "pellipse" 0)
(setq pellipse (getvar "pellipse"))
(setq old (car (entsel "\n select ellipse to change ")))
(while old
(if (= (cdr (assoc 0 (entget old))) "ELLIPSE")
(progn
(setq sav (mapcar 'getvar '("PELLIPSE" "OSMODE" "UCSICON"))
cen (cdr (assoc 10 (entget old)))
dep (cdr (assoc 11 (entget old))))
(mapcar 'setvar '("PELLIPSE" "OSMODE" "UCSICON") '(1 0 0))
(command "UCS" "e" old)
(setq p1 (trans (list (+ (car cen) (car dep))
(+ (cadr cen) (cadr dep))
(+ (caddr cen) (caddr dep)))
0 1)
p2 (trans (list (- (car cen) (car dep))
(- (cadr cen) (cadr dep))
(- (caddr cen) (caddr dep)))
0 1)
p3 (trans (polar cen
(+ (/ PI 2.0) (angle p1 p2))
(* 0.5 (cdr (assoc 40 (entget old))) (distance p1 p2)))
0 1)
)
(command "ellipse" p1 p2 p3)
(setq new (entget (entlast))
new (subst (cons 8 (cdr (assoc 8 (entget old)))) (assoc 8 new) new))
(entmod new)
(entdel old)
(command "ucs" "p")
(mapcar 'setvar '("PELLIPSE" "OSMODE" "UCSICON") sav)
)
(alert "This is not a spline ellipse!")
)
(setq old (car (entsel "\n next ellipse -or none for exit ")))
)
(princ)
(setvar "pellipse" pellipse)
);; end of program
All help is appreciated. Also if there is a way to make this more automated without having to actually select the ellipse. For example, have the program find all ellipses, mkae an exact copy of all ellipses as plines,erase original ellipse, and set them to layer "0". This is what i am trying to do just not quite all the way there yet
[ Moderator Action = ON ] What are [ CODE ] tags... (http://forums.augi.com/misc.php?do=bbcode#code) [ Moderator Action = OFF ]
abdulhuck
2006-07-22, 09:31 AM
... if there is a way to make this more automated without having to actually select the ellipse. For example, have the program find all ellipses,....Please have a look at this code slightly updated to scan for all the ellipse entities in the drawing and apply your logic.
(defun e2p( /
old new ;existent and new polyline
sav ;store system variables
cen ;center of ellipse
dep ;axis end point deplacement (relative to cen)
p1 p2 ;first axis enpoints
p3 ;sec. axis endpoint
ellObjs ; added
numObjs ; added
count ; added
)
;;; Existing code commented out from here
;;;_______________________________________________________________
;;; (setvar "pellipse" 0)
;;; (setq pellipse (getvar "pellipse"))
;;; (setq old (car (entsel "\n select ellipse to change ")))
;;; (while old
;;; (if (= (cdr (assoc 0 (entget old))) "ELLIPSE")
;;; (progn
;;;
;;; Commented out till here
;;;________________________________________________________________
;;;
;;; New code added to filter the selection
;;;
(setq ellObjs (ssget "x" '((0 . "ELLIPSE"))))
(if ellObjs
(progn
(setq numOjbs (sslength ellObjs)
count 0
)
(while (> numOjbs count)
(setq old (cdr (assoc -1 (entget (ssname ellObjs count)))))
;;;________________________________________________________________
;;; End of new code
(setq sav (mapcar 'getvar '("PELLIPSE" "OSMODE" "UCSICON"))
cen (cdr (assoc 10 (entget old)))
dep (cdr (assoc 11 (entget old))))
(mapcar 'setvar '("PELLIPSE" "OSMODE" "UCSICON") '(1 0 0))
(command "UCS" "e" old)
(setq p1 (trans (list (+ (car cen) (car dep))
(+ (cadr cen) (cadr dep))
(+ (caddr cen) (caddr dep)))
0 1)
p2 (trans (list (- (car cen) (car dep))
(- (cadr cen) (cadr dep))
(- (caddr cen) (caddr dep)))
0 1)
p3 (trans (polar cen
(+ (/ PI 2.0) (angle p1 p2))
(* 0.5 (cdr (assoc 40 (entget old))) (distance p1 p2)))
0 1)
)
(command "ellipse" p1 p2 p3)
(setq new (entget (entlast))
new (subst (cons 8 (cdr (assoc 8 (entget old)))) (assoc 8 new) new))
(entmod new)
(entdel old)
(command "ucs" "p")
(mapcar 'setvar '("PELLIPSE" "OSMODE" "UCSICON") sav)
;;; New code starts
;;;________________________________________________________________
(setq count (1+ count))
); while
); progn
); if
;;;________________________________________________________________
;;; End of new code
;;; Existing code commented out from here
;;; ) progn
;;; (alert "This is not a spline ellipse!")
;;; )
;;; (setq old (car (entsel "\n next ellipse -or none for exit ")))
;;; )
;;;(setvar "pellipse" pellipse)
;;; Commented out till here
;;;________________________________________________________________
(princ)
);; end of program
Regards,
Abdul Huck
Lions60
2006-07-25, 02:25 PM
Yes, this works to automate the ellipse being converted, but now i need a way to take an existing elliptical arc and convert it to a polyline and still having it look like an arc and not a full ellipse.
Lions60
2006-07-27, 05:37 PM
Any suggestions
Lions60
2006-07-27, 07:48 PM
What i have to figure out is how to extract the start and end angle of the existing elliptical arc and then draw either actual lines and delete them at the end of the program or imaginary lines and trim the ellipse back to these lines. Thus making an elliptical arc into a pline that looks like the original arc.
Tom Beauford
2006-07-28, 08:21 PM
This works on one at least, but needs cleaning up:(defun e2p( /
old new ;existent and new polyline
sav ;store system variables
cen ;center of ellipse
dep ;axis end point deplacement (relative to cen)
p1 p2 ;first axis enpoints
p3 ;sec. axis endpoint
)
(setq old (car (entsel "\n select ellipse to change "))
ellipseObj (vlax-ename->vla-object old)
Center (vlax-safearray->list (vlax-variant-value (vla-get-Center ellipseObj)))
StartPoint (vlax-safearray->list (vlax-variant-value (vla-get-StartPoint ellipseObj)))
EndPoint (vlax-safearray->list (vlax-variant-value (vla-get-EndPoint ellipseObj)))
StartAngle (vla-get-StartAngle ellipseObj)
EndAngle (vla-get-EndAngle ellipseObj)
dist1 (vlax-curve-getDistAtPoint ellipseObj StartPoint)
dist2 (vlax-curve-getDistAtPoint ellipseObj EndPoint)
dist (/ (+ dist1 dist2) 2)
emidpt (vlax-curve-getPointAtDist ellipseObj dist)
ang (+ EndAngle (/ (+ StartAngle EndAngle) 2))
dist (*(distance emidpt Center)1.1)
fpt (polar Center ang dist)
)
(setq sav (mapcar 'getvar '("PELLIPSE" "OSMODE" "UCSICON"))
cen (cdr (assoc 10 (entget old)))
dep (cdr (assoc 11 (entget old))))
(while old
(if (= (cdr (assoc 0 (entget old))) "ELLIPSE")
(progn
(mapcar 'setvar '("PELLIPSE" "OSMODE" "UCSICON") '(1 0 0))
(command "UCS" "e" old)
(setq p1 (trans (list (+ (car cen) (car dep))
(+ (cadr cen) (cadr dep))
(+ (caddr cen) (caddr dep)))
0 1)
p2 (trans (list (- (car cen) (car dep))
(- (cadr cen) (cadr dep))
(- (caddr cen) (caddr dep)))
0 1)
p3 (trans (polar cen
(+ (/ PI 2.0) (angle p1 p2))
(* 0.5 (cdr (assoc 40 (entget old))) (distance p1 p2)))
0 1)
)
(if (= (- EndAngle (* pi 2)) StartAngle)
(command "ellipse" p1 p2 p3)
(progn
(command "ellipse" p1 p2 p3)
(setq new (entget (entlast))
new (subst (cons 8 (cdr (assoc 8 (entget old)))) (assoc 8 new) new)
)
(entmod new)
(setq ptrim (list
'(0 . "LWPOLYLINE")
'(100 . "AcDbEntity")
(cons 8 (cdr (assoc 8 (entget old)))) ; layer
'(6 . "CONTINUOUS") ;linetype
'(100 . "AcDbPolyline")
'(90 . 2) ;# of vertices
'(39 . 0.0)
(list 10(car StartPoint)(cadr StartPoint)) ;vertex
(list 10(car EndPoint)(cadr EndPoint)) ;vertex
'(210 0.0 0.0 1.0) ;extrusion direction
)
)
(entmake ptrim)
(setq AX (entlast))
(VL-CMDF "._trim" AX "" "f" fpt Center "" "")
(entdel AX)
); progn
); if
; (entdel old)
(command "ucs" "p")
(mapcar 'setvar '("PELLIPSE" "OSMODE" "UCSICON") sav)
)
(alert "This is not a spline ellipse!")
)
(setq old (car (entsel "\n next ellipse -or none for exit ")))
)
(princ)
);; end of program What i have to figure out is how to extract the start and end angle of the existing elliptical arc and then draw either actual lines and delete them at the end of the program or imaginary lines and trim the ellipse back to these lines. Thus making an elliptical arc into a pline that looks like the original arc.
Lions60
2006-07-31, 12:54 PM
Ok, I have tried running your program and get what it is trying to do but after it draws the line to trim back to it doesn't trim. Not sure if i am doing anything wrong. Or if maybe it just needs a little work.
Tom Beauford
2006-07-31, 01:08 PM
Ok, I have tried running your program and get what it is trying to do but after it draws the line to trim back to it doesn't trim. Not sure if i am doing anything wrong. Or if maybe it just needs a little work.Needs a lot of work, but I got the start and end angles you wanted. While I got it to work once using StartPoint and EndPoint those points will only fall on the polyline approximation at the vertices. Hope it helps you. I would recomend when you finish to leave the origional ellipse since your polyline version will be on top anyway. You may need to examine it someday and the polyline wont be much help.
Lions60
2006-07-31, 01:50 PM
Ok, then I'll see what I can do. Thanks for the code.
peter
2006-08-01, 05:40 PM
Another version
(defun C:El2p ()
(if (setq lstSelection (entsel "\nSelect Ellipse: "))
(el2p (car lstSelection))
)
(princ)
)
(defun El2p (objEllipse)
(if (= (type objEllipse) 'ENAME)
(setq objEllipse (vlax-ename->vla-object objEllipse)))
(setq sngIncrement (/ (vlax-curve-getdistatparam objEllipse (vlax-curve-getendparam objEllipse)) 100.0)
sngPosition 0.0
)
(command "ortho" "off" "pline")
(repeat 101
(command (vlax-curve-getpointatdist objEllipse sngPosition))
(setq sngPosition (+ sngPosition sngIncrement))
)
(command "")
(vla-delete objEllipse)
(princ)
)
Tom Beauford
2006-08-01, 06:05 PM
Perfect Peter, I've already added it to my list of "Jamtgaard" routines and deleted all that ugly code I played with above. I'd just decided it wasn't possible.
Lions60
2006-08-01, 07:56 PM
Here is an update to have the program select all ellipses for you.
(defun e2p ()
(if (setq lstSelection (ssget "X" '((0 . "ELLIPSE"))))
(progn
(setq i -1)
(while (setq ename (ssname lstSelection (setq i (1+ i))))
(el2p ename)
)
)
)
(princ)
)
(defun El2p (objEllipse)
(if (= (type objEllipse) 'ENAME)
(setq objEllipse (vlax-ename->vla-object objEllipse)))
(setq sngIncrement (/ (vlax-curve-getdistatparam objEllipse (vlax-curve-getendparam objEllipse)) 100.0)
sngPosition 0.0
)
(command "ortho" "off" "pline")
(repeat 101
(command (vlax-curve-getpointatdist objEllipse sngPosition))
(setq sngPosition (+ sngPosition sngIncrement))
)
(command "")
(vla-delete objEllipse)
(princ)
)
vBulletin® v3.6.7, Copyright ©2000-2010, Jelsoft Enterprises Ltd.