https://www.theswamp.org/index.php?topic=45305.15
原帖第29楼,有ymg大神贴的源码可下载。
下面为转贴的源码,楼主可以依需求修改。
- ;;; Cut & Fill by ymg ;
- ;;; ;
-
-
-
- (defun c:cf (/ ** *acdoc* a are b bnd c cutcol d dir dl1 dl2 e fillcol hcol
- intl len1 len2 p p0 p1 p2 pm pol1 pol2 sp1 sp2 spe ss1
- ss2 totcut totfill txt txtlayer varl)
-
- (vl-load-com)
-
- (defun *error* (msg)
- (mapcar 'eval varl)
- (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")))
- (princ (strcat "\nError: " msg))
- )
- (and *acdoc* (vla-endundomark *acdoc*))
- (princ)
- )
-
- (setq varl '("OSMODE" "CMDECHO" "DIMZIN" "PEDITACCEPT")
- varl (mapcar (function (lambda (a) (list 'setvar a (getvar a)))) varl)
- )
-
- (or *acdoc* (setq *acdoc* (vla-get-activedocument (vlax-get-acad-object))))
-
- (vla-startundomark *acdoc*)
-
- (setvar 'CMDECHO 0)
- (setvar 'DIMZIN 0)
- (setvar 'OSMODE 0)
-
-
- (setq cutcol 1 fillcol 3 ; Cut is Red, Fill is Green ;
- totcut 0 totfill 0 ; Total Cut and Total Fill ;
- txtlayer "Text" ; Name of Layer for Cut and Fill Values ;
-
- )
- (while (not (setq ** (princ "\nSelect Reference Polyline:")
- ss1 (ssget "_+.:L:S" '((0 . "LWPOLYLINE")))
- )
- )
- (princ "\nYou Must Select a Polyline:")
- )
- (while (not (setq ** (princ "\nSelect Proposed Polyline:")
- ss2 (ssget "_+.:L:S" '((0 . "LWPOLYLINE")))
- )
- )
- (princ "\nYou Must Select a Polyline:")
- )
-
-
- (setq pol1 (ssname ss1 0)
- len1 (vlax-curve-getDistAtParam pol1 (vlax-curve-getEndParam pol1))
- pol2 (ssname ss2 0)
- len2 (vlax-curve-getDistAtParam pol2 (vlax-curve-getEndParam pol2))
- sp1 (vlax-curve-getstartpoint pol1)
- spe (vlax-curve-getendpoint pol1)
- sp2 (if (vlax-curve-isClosed pol2)
- (setq lst2 (listpol pol2)
- disl (mapcar '(lambda (a) (distance sp1 a)) lst2)
- ** (plineorg pol2 (nth (vl-position (apply 'min disl) disl) lst2))
- )
- (vlax-curve-getstartpoint pol2)
- )
- dir (if (< (/ pi 2) (angle sp1 spe) (/ (* 3 pi) 2)) -1 1)
- )
-
-
- ; Getting all the intersections between poly. ;
-
- (setq intl (intersections pol1 pol2))
-
- (if (> (length intl) 1)
- (progn
-
- ; Computing distance of intersections on each polyline ;
-
- (setq dl1 (mapcar '(lambda (a) (getdistoncurve pol1 a)) intl)
- dl2 (mapcar '(lambda (a) (getdistoncurve pol2 a)) intl)
- )
-
- ; If both polyline are closed add first Intersection to end of list ;
- ; We also add a distance to each distances list ;
-
- (if (and (vlax-curve-isClosed pol1) (vlax-curve-isClosed pol2))
- (setq dl1 (append dl1 (list (+ (car dl1) len1)))
- dl2 (append dl2 (list (+ (car dl2) len2)))
- intl (append intl (list (car intl)))
- dir (if (iscw_p (listpol pol1)) -1 1)
- )
- )
-
-
- ; Finding points at mid-distance between intersections on each polyline ;
- ; Calculating midpoint between mid-distance points to get an internal point;
- ; Creating a list of all these points plus the intersection points ;
-
- (setq pm
- (mapcar
- '(lambda (a b c d e)
- (list (midpoint
- (setq p1 (getptoncurve pol1 (rem (* (+ a b) 0.5) len1)))
- (setq p2 (getptoncurve pol2 (rem (* (+ c d) 0.5) len2)))
- )
- p1 p2 e
- )
- )
- dl1 (cdr dl1) dl2 (cdr dl2) intl
- )
- )
-
-
-
- (foreach i pm
- (setq p (car i) ; Midpoint between p1 p2 ;
- p0 (cadddr i) ; Intersection Point ;
- p1 (cadr i) ; Midpoint of Intersections on Reference Polyline ;
- p2 (caddr i) ; Midpoint of Intersections on Proposed Polyline ;
- )
- (if (> (abs (onside p2 p0 p1)) 1e-3) ; Not Colinear ;
- (progn
- (vl-cmdf "._-BOUNDARY" p "")
- (setq are (vla-get-area (vlax-ename->vla-object (entlast)))
- bnd (entlast)
- )
-
- (if (minusp (* (onside p2 p0 p1) dir))
- (setq totfill (+ totfill are) hcol fillcol)
- (setq totcut (+ totcut are) hcol cutcol)
- )
-
- (vl-cmdf "._-HATCH" "_CO" hcol "." "_P" "SOLID" "_S" bnd "" "")
- (entdel bnd)
- )
- )
- )
- (setq p (cadr (grread nil 13 0))
- txt (strcat "{\\C3;Fill: " (rtos totfill 2 2) " m2\\P\\C1;Cut: " (rtos totcut 2 2) " m2}")
- )
- (entmakex (list
- (cons 0 "MTEXT")
- (cons 100 "AcDbEntity")
- (cons 8 txtlayer)
- (cons 100 "AcDbMText")
- (cons 10 p)
- (cons 40 3.0)
- (cons 1 txt)
- )
- )
-
- (command "_MOVE" (entlast) "" p pause)
- )
- (Alert "Not Enough Intersections To Process !")
- )
-
- (*error* nil)
-
- )
-
- (princ "\nCalculates Cut & Fill Between Two Intersecting Polylines")
- (princ "\nCF to start...")
-
-
-
- (defun midpoint (p1 p2)
- (mapcar '(lambda (a b) (* (+ a b) 0.5)) p1 p2)
- )
-
- ; onside by ymg ;
- ; Negative return, point is on left of v1->v2 ;
- ; Positive return, point is on right of v1->v2 ;
- ; 0 return, point is smack on the vector. ;
- ; ;
-
- (defun onside (p v1 v2 / x y)
- (setq x (car p) y (cadr p))
- (- (* (- (cadr v1) y) (- (car v2) x)) (* (- (car v1) x) (- (cadr v2) y)))
- )
-
- ; ;
- ; Is Polyline Clockwise by LeeMac ;
- ; ;
- ; Argument: l, Point List ;
- ; Returns: t, Polyline is ClockWise ;
- ; nil, Polyline is CounterClockWise ;
- ; ;
-
- (defun iscw_p (l)
- (if (equal (car l) (last l) 1e-8) (setq l (cdr l)))
- (minusp
- (apply '+
- (mapcar
- (function
- (lambda (a b) (- (* (car b) (cadr a)) (* (car a) (cadr b))))
- )
- l (cons (last l) l)
- )
- )
- )
- )
-
- ;; ;
- ;; Return list of intersection(s) between two VLA-Object or two ENAME ;
- ;; obj1 - first VLA-Object ;
- ;; obj2 - second VLA-Object ;
- ;; mode - intersection mode (acExtendNone acExtendThisEntity ;
- ;; acExtendOtherEntity acExtendBoth) ;
- ;; Requires triplet ;
- ;; ;
-
- (defun Intersections (obj1 obj2)
- (or (= (type obj1) 'VLA-OBJECT) (setq obj1 (vlax-ename->vla-object obj1)))
- (or (= (type obj2) 'VLA-OBJECT) (setq obj2 (vlax-ename->vla-object obj2)))
-
- (triplet (vlax-invoke obj1 'intersectwith obj2 acExtendNone))
- )
-
- ;; ;
- ;; triplet, Separates a list into triplets of items. ;
- ;; ;
-
- (defun triplet (l)
- (if l (cons (list (car l) (cadr l) (caddr l))(triplet (cdddr l))))
- )
-
-
- (defun getdistoncurve (e p)
- (vlax-curve-getDistatParam e
- (vlax-curve-getparamatpoint e
- (vlax-curve-getclosestpointto e p)
- )
- )
- )
-
- (defun getptoncurve (e d)
- (vlax-curve-getpointatparam e (vlax-curve-getparamatdist e d))
- )
-
- ;; ;
- ;; listpol by ymg (Simplified a Routine by Gile Chanteau ;
- ;; ;
- ;; Parameter: en, Entity Name or Object Name of Any Type of Polyline ;
- ;; ;
- ;; Returns: List of Points in Current UCS ;
- ;; ;
- ;; Notes: On Closed Polyline the Last Vertex is Same as First) ;
- ;; ;
-
- (defun listpol (en / i l)
- (repeat (setq i (fix (1+ (vlax-curve-getEndParam en))))
- (setq l (cons (trans (vlax-curve-getPointAtParam en (setq i (1- i))) 0 1) l))
- )
- )
-
-
- ;; plineorg by (gile) (Modified into a function by ymg) ;
- ;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/ ;
- ;; change-polyline-start-point/td-p/2154331 ;
- ;; ;
- ;; Function to modify origin of a closed polyline ;
- ;; ;
- ;; Arguments: ;
- ;; en : Ename or VLA-Object of a Closed Polyline. ;
- ;; pt : Point ;
- ;; ;
- ;; Returns: Point of Origin if successful, else nil. ;
- ;; ;
-
- (defun plineorg (en pt / blst d1 d2 d3 n norm obj pa plst)
- (if (= (type en) 'ENAME)
- (setq obj (vlax-ename->vla-object en))
- (setq obj en en (vlax-vla-object->ename obj))
- )
-
- ;; bulgratio by (gile) ;
- ;; Returns a bulge which is proportional to a reference ;
- ;; Arguments : ;
- ;; b : the reference bulge ;
- ;; k : the ratio (between angles or arcs length) ;
-
- (defun bulgratio (b k / a)
- (setq a (atan b))
- (/ (sin (* k a)) (cos (* k a)))
- )
-
- ;; Sublist by (gile) ;
- ;; Returns a sublist similar to substr function. ;
- ;; lst : List from which sublist is to be extracted ;
- ;; idx : Index of Item at Start of sublist ;
- ;; len : Length of sublist or nil to return all items. ;
-
- (defun sublist (lst n len / rtn)
- (if (or (not len) (< (- (length lst) n) len))
- (setq len (- (length lst) n))
- )
- (setq n (+ n len))
- (repeat len
- (setq rtn (cons (nth (setq n (1- n)) lst) rtn))
- )
- )
-
- (if (and (= (vla-get-closed obj) :vlax-true)
- (= (vla-get-objectname obj) "AcDbPolyline")
- )
- (progn
- (setq plst (vlax-get obj 'coordinates)
- norm (vlax-get obj 'normal)
- pt (vlax-curve-getClosestPointTo en (trans pt 1 0))
- pa (vlax-curve-getparamatpoint obj pt)
- n (/ (length plst) 2)
- )
- (repeat n
- (setq blst (cons (vla-getbulge obj (setq n (1- n))) blst))
- )
- (if (= pa (fix pa))
- (setq n (fix pa)
- plst (append (sublist plst (* 2 n) nil)
- (sublist plst 0 (* 2 n))
- )
- blst (append (sublist blst n nil) (sublist blst 0 n))
- )
- (setq n (1+ (fix pa))
- d3 (vlax-curve-getdistatparam en n)
- d2 (- d3 (vlax-curve-getdistatpoint en pt))
- d3 (- d3 (vlax-curve-getdistatparam en (1- n)))
- d1 (- d3 d2)
- pt (trans pt 0 (vlax-get obj 'normal))
- plst (append (list (car pt) (cadr pt))
- (sublist plst (* 2 n) nil)
- (sublist plst 0 (* 2 n))
- )
- blst (append (list (bulgratio (nth (1- n) blst) (/ d2 d3)))
- (sublist blst n nil)
- (sublist blst 0 (1- n))
- (list (bulgratio (nth (1- n) blst) (/ d1 d3)))
- )
- )
- )
- (vlax-put obj 'coordinates plst)
- (repeat (setq n (length blst))
- (vla-setbulge obj (setq n (1- n)) (nth n blst))
- )
- (trans pt 0 1)
- )
- nil
- )
- )
-
|