Search the FAQ Archives

3 - A - B - C - D - E - F - G - H - I - J - K - L - M
N - O - P - Q - R - S - T - U - V - W - X - Y - Z
faqs.org - Internet FAQ Archives

comp.cad.autocad AutoLISP FAQ (part 2/2) - samples, code
Section - [23] Polylines

( Part1 - Part2 - Single Page )
[ Usenet FAQs | Web FAQs | Documents | RFC Index | Restaurant inspections ]


Top Document: comp.cad.autocad AutoLISP FAQ (part 2/2) - samples, code
Previous Document: [22] Block Attributes
Next Document: [24] Circle/Arc Geometry: BULGE conversion, some trigonometry
See reader questions & answers on this topic! - Help others by sharing your knowledge
  Since R14 LWPOLYLINE's store the vertices in one entity as multiple 10
  groups. So (assoc) will not work.

[23.1] How to access polyline VERTICES?  [updated for R14]

  A polyline VERTEX is a subentity of a POLYLINE (same as an ATTRIBUTE
  is a subentity of an INSERT element or a ATTDEF of a BLOCK).
  Therefore the same functions as in [22.1]-[22.3] can be used.

  ;;; return only some assoc values in the list (for LWPOLYLINE)
  (defun GROUP-ONLY (grp lst)
    (mapcar 'cdr (remove-if-not '(lambda(pair)(= grp (car pair))) lst)))

  ;;; return the vertex list of a polyline or of any other element
  ;;; Note that with edlgetent mentioned in [22.1] it's a one-liner
  (defun GETPTS (ele / pts)
    (setq ele (entity ele))		;force type ENAME
    (cond
      ((istypep ele "POLYLINE")
        (while (istypep (setq ele (entnext ele)) "VERTEX")
          ;; omit fit and spline points  (conservative style)
          (if (not (or (flagsetp 1 ele) (flagsetp 8 ele))) ;bugfix!
            (setq pts (cons (trans (getpt ele) ele 0) pts)))
          (reverse pts)))
      ;; Special case: you have to map it, assoc finds only the first.
      ;; Fix a LWPOLYLINE bug in R14: internally stored as 2d point,
      ;;   (entget) returns fantasy z-values.
      ((istypep ele "LWPOLYLINE")
        (mapcar '(lambda(pt)(trans (list (car pt)(cadr pt) 0.0) ele 0))
                 (group-only 10 (entget ele))))
      ;; insert here possible other types, such as
      ((istypep ele '("TEXT" "CIRCLE")) (list (getpt ele)))
      ;; more like this (serge's style)
      (T (apply 'append (mapcar
        '(lambda (n / p) (if (setq p (getval n ele)) (list p)))
        '(10 11 12 13)))
      )
      ;; or like this (conservative style)
      ;;(T (foreach n '(10 11 12 13)
      ;;     (if (setq p (getval n ele)) (setq pts (cons p pts))))
      ;;  pts
      ;;)
    )
  )

  Suggestions by Vladimir Nesteroswky for a different vertex structure:
  (defun VERTICES-AND-BULGES (pline-ename)
    (mapcar 'cdr
      (remove-if-not '(lambda (ele) (bitsetp 9 x))
        (get '(70 10 42) (cdr (edlgetent pline-ename))
  => list of (10 42) pairs of the pline

  See also [23.5] for a different edge structure (segments) of plines.

------------------------------

[23.2] How to JOIN multiple lines to polylines?

  Simply try to join each element with all selected, but beware that
  an entity already joined cannot be entget'ed anymore, because it's
  deleted.

  ;;; This sample converts all selected elements to polylines and
  ;;;  tries to join as much as possible.
  (defun C:JOINPOLY (/ ele ss)
    (foreach ele (sslist (setq ss (ssget)))     ;better process lists
      (if (entget ele)                          ;not already joined
        (cond                                   ;(then it would be nil)
          ((istypep ele '("ARC" "LINE"))
            ;; in fact you should check Z of lines and UCS here too
            (command "_PEDIT" ele "_Y" "_J" ss "" ""); convert and JOIN
          )
          ((and (istypep ele '("POLYLINE" "LWPOLYLINE")) ;bugfix
                (not (flagsetp 1 ele))          ;not closed
                (< (rem (getflag ele) 128) 8))  ;ignore meshes and such
            (command "_PEDIT" ele "_J" ss "" "");ucs check omitted
          )
        )
      )
    )
  )

------------------------------

[23.3] Change WIDTH of multiple polylines

  With the help of the above defined helper function it's a short one:

  (defun C:POLYWID (/ wid ele)
    (initget 5)(setq wid (getdist "New Polyline Width: ")) ;not negative
    (foreach ele (sslist (ssget '((0 . "*POLYLINE"))))     ;only PLINES
      (command "_PEDIT" ele "_W" wid "")))

------------------------------

[23.4] Create a polyline or spline: with (ENTMAKE) or (COMMAND)

  1. You can create a script-file with a LISP-program and then run it.
  It seems to be the simpliest way, but I/O errors may occur when
  reading/writing the script. If your soft is commercial, it must handle
  such errors.

  2. The second way is to create the entities list and use ENTMAKE.
  Advantage: fast, in WCS, independent of actual osnaps.
  See http://xarch.tu-graz.ac.at/autocad/stdlib/ENTMAKE.LSP

  3. The third solution is based on command and mapcar. It works with
  Polylines, Splines or Lines. Disadvantage: UCS, Osnaps

  ;;; Draws a POLYLINE entity from a list of points (same with SPLINE,
  ;;;  or LINE), on the actual UCS, with actual OSNAP settings
  (defun DRAW-PLINE (pts)
    (command "_PLINE")
    (mapcar 'command pts)
    (command ""))
  (defun DRAW-SPLINE (pts)
    (command "_SPLINE")
    (mapcar 'command pts)   ; the pts must be the fitpoints then
    (command "" "" ""))

------------------------------

[23.5] How to calculate the LENGTH of polylines?

  There are two ways:
  1. the obvious, using the AREA command which is quite "noisy"
    (prints the result), but works even with splines.

  ;;; add up the LENGTH of all selected objects, NOISY, you can do the
  ;;; same with AREAs: simply change the last line to (getvar "AREA")
  (defun C:LEN-OF ()
    (command "_AREA" "_A" "_E")           ;add up objects (for R12+13)
    (ssmap 'command (ssget))            ;pass all elements to AutoCAD
    (command "" "")                       ;two returns
    (getvar "PERIMETER"))                 ;this is the length

  2. Doing some math, but only for simple entities. Here it is best to
    define some helper functions again. This is also an introduction for
    the next chapter [24], some bulge trigonometry for curved segments.

  ;;; calculates length of a pline, quiet
  (defun POLY-LENGTH (poly / seg)
    (apply '+             ; the sum of all single segment lengths
      (mapcar
       '(lambda (seg)                         ;length of one segment
          (if (zerop (car seg))               ;is it straight?
            (distance (cadr seg) (caddr seg)) ; line segment or
            (abs (arclen seg))))              ; curved: -> [24]
        (pline-segs poly))))        ;segment list (bulge p1 p2)

  ;;; returns all group codes of the complex element
  ;;; (vertices, attributes) as list, similar to (edlgetent)
  (defun CPLX-LIST (grp ele / lst)
    (if (= 1 (getval 66 ele))
      (progn (setq ele (entnext (entity ele)))
        (while (and ele (not (istypep ele "SEQEND")))
          (setq lst (cons (getval grp ele) lst)
  	      ele (entnext ele)))
        (reverse lst))))

  ;;; Creates a segment list for the polyline pname
  ;;;   as a list of '(bulge p1 p2). A straight line has bulge 0.0
  ;;; Compute pts in ECS of pname. Accepts LWPOLYLINE's
  (defun PLINE-SEGS (pname / pts segs)
    (setq segs
      (mapcar 'list
        (if (istypep pname "LWPOLYLINE")
          (group-only 42 (entget pname))
          (cplx-list 42 pname))
        (setq pts (getpts pname))       ; ->[23.1]
        (rot1 pts)))                    ; ->[20.1]
    (if (flagsetp 1 pname)
      segs		;closed
      (butlast segs))) 	;open: without the last segment, ->[20.1]

  ;;; Example:   (a bit optimized for brevity :)
  ;;; Add up all the lengths of all selected polylines, quiet
  ;;; To accept also other entities, add those to pline-segs
  (defun C:POLYLEN ()
    (apply '+ (ssmap 'poly-length (ssget '((0 . "*POLYLINE"))))))

For the sum of areas use either the noisy AREA command or implement
Heron's formula for polygon areas (just for simple closed polygons).

------------------------------

[23.6] How to REVERT a polyline direction?

  Sergei Komarov submitted a REVPOLY.LSP which takes care of
  bulges and widths too.
  http://xarch.tu-graz.ac.at/autocad/news/lisp_progs/revpoly.lsp

  A short stdlib version is this:
  ;;; ignoring any width information
  (defun POLY-REVERSE (segs)
    (reverse (mapcar '(lambda (seg) (std-make-seg (std-seg-p2 seg)
		                      (std-seg-p1 seg)
 		                      (- (std-seg-bulge-num seg))))
	       segs)))
  (defun C:POLYREV (/ ele)
    (std-require "ENTMAKE")
    (if (setq ele (car (entsel "\nRevert Poly: ")))
      (std-entmake-pline (entget ele '("*")) ; keep EED information
	                 (poly-reverse (std-pline-segs ele)))))

------------------------------

[23.7] How to get the CENTER of a polyline?

The centroid of SOLID's has to be extracted with MASSPROP. 
You can let it write to a file and analyse this then.
The centroid of polylines is different to the mean vector. 
The 2D geometric mean of some pts is simply:

  (setq n (float (length pts)))
  (list (/ (apply '+ (mapcar 'car pts)) n)
        (/ (apply '+ (mapcar 'cadr pts)) n))

The true centriod is more difficult. The stdlib version is at
http://xarch.tu-graz.ac.at/autocad/stdlib/STDPOINT.LSP STD-CENTROID-2D
In the stdlib.arx or at www.manusoft.com (under freebies) are also a 
better massprop lisp function for solids. Then you do 
(command "_REGION" ele)...(massprop entlast)...(command "_UNDO" 1)
For VLA there's also a massprop property for Acis objects.

User Contributions:

1
Mar 17, 2023 @ 5:17 pm
Regardless if you believe in God or not, read this message!!!

Throughout time, we can see how we have been carefully conditioned to come to this point where we are on the verge of a cashless society. Did you know that the Bible foretold of this event almost 2,000 years ago?

In the book of Revelation 13:16-18, we read,

"He (the false prophet who deceives many by his miracles--Revelation 19:20) causes all, both small and great, rich and poor, free and slave, to receive a mark on their right hand or on their foreheads, and that no one may buy or sell except one who has the mark or the name of the beast, or the number of his name.

Here is wisdom. Let him who has understanding calculate the number of the beast, for it is the number of a man: His number is 666."

Referring to the last generation, this could only be speaking of a cashless society. Why so? Revelation 13:17 states that we cannot buy or sell unless we receive the mark of the beast. If physical money was still in use, we could buy or sell with one another without receiving the mark. This would contradict scripture that states we need the mark to buy or sell!

These verses could not be referring to something purely spiritual as scripture references two physical locations (our right hand or forehead) stating the mark will be on one "OR" the other. If this mark was purely spiritual, it would indicate both places, or one--not one OR the other!

This is where it comes together. It is amazing how accurate the Bible is concerning the implantable RFID microchip. Here is information from a man named Carl Sanders who worked with a team of engineers to help develop this RFID chip:

"Carl Sanders sat in seventeen New World Order meetings with heads-of-state officials such as Henry Kissinger and Bob Gates of the C.I.A. to discuss plans on how to bring about this one-world system. The government commissioned Carl Sanders to design a microchip for identifying and controlling the peoples of the world—a microchip that could be inserted under the skin with a hypodermic needle (a quick, convenient method that would be gradually accepted by society).

Carl Sanders, with a team of engineers behind him, with U.S. grant monies supplied by tax dollars, took on this project and designed a microchip that is powered by a lithium battery, rechargeable through the temperature changes in our skin. Without the knowledge of the Bible (Brother Sanders was not a Christian at the time), these engineers spent one-and-a-half-million dollars doing research on the best and most convenient place to have the microchip inserted.

Guess what? These researchers found that the forehead and the back of the hand (the two places the Bible says the mark will go) are not just the most convenient places, but are also the only viable places for rapid, consistent temperature changes in the skin to recharge the lithium battery. The microchip is approximately seven millimeters in length, .75 millimeters in diameter, about the size of a grain of rice. It is capable of storing pages upon pages of information about you. All your general history, work history, criminal record, health history, and financial data can be stored on this chip.

Brother Sanders believes that this microchip, which he regretfully helped design, is the “mark” spoken about in Revelation 13:16–18. The original Greek word for “mark” is “charagma,” which means a “scratch or etching.” It is also interesting to note that the number 666 is actually a word in the original Greek. The word is “chi xi stigma,” with the last part, “stigma,” also meaning “to stick or prick.” Carl believes this is referring to a hypodermic needle when they poke into the skin to inject the microchip."

Mr. Sanders asked a doctor what would happen if the lithium contained within the RFID microchip leaked into the body. The doctor replied by saying a terrible sore would appea (...)

Comment about this article, ask questions, or add new information about this topic:




Top Document: comp.cad.autocad AutoLISP FAQ (part 2/2) - samples, code
Previous Document: [22] Block Attributes
Next Document: [24] Circle/Arc Geometry: BULGE conversion, some trigonometry

Part1 - Part2 - Single Page

[ Usenet FAQs | Web FAQs | Documents | RFC Index ]

Send corrections/additions to the FAQ Maintainer:
rurban@xarch.tu-graz.ac.at (Reini Urban)





Last Update March 27 2014 @ 02:11 PM