Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Valued Contributor
cummins600
Posts: 97
Registered: ‎03-24-2004
Message 1 of 10 (1,090 Views)
Accepted Solution

Make polyline clockwise if counter clockwise

1090 Views, 9 Replies
06-07-2012 07:19 AM

Is it possible to make a ployline clockwise if it is currently counter clockwise? My issues is the routine below that I use is based on the pline beining consitant and they are not from dwg to dwg. Any help is welcome. Thanks.

 

;;;gross p-line offset tool

(defun c:smileysurprised:f8 (/ ent dist obj)
(vl-load-com)
;(setq ent (car (entsel "\nSelect line to offset: "))
(setq ent (ssget "X" (list (cons 8 "GROS$")))
)
(setq dist 8)
;(initget (+ 1 2 4 64))
;(setq dist (getdist "\nEnter offset distance: "))
;(initget (+ 2 4) "Yes No")
;;; (setq obj (vlax-ename->vla-object ent))
(setq obj (vlax-ename->vla-object (ssname ent 0)))
;(vla-offset obj dist)
(vla-offset obj (* dist -1));outside
;(vla-offset obj (* dist 1));inside
;;change-up the offset layer
(command "-layer" "m" "GROS-EXT" "")
(command "change" "l" "" "p" "la" "gros-ext" "")
)


cummins600 wrote:

Is it possible to make a ployline clockwise if it is currently counter clockwise? My issues is the routine below that I use is based on the pline beining consitant and they are not from dwg to dwg. Any help is welcome. Thanks.

 

;;;gross p-line offset tool

(defun c:smileysurprised:f8 (/ ent dist obj)
(vl-load-com)
....

(setq ent (ssget "X" (list (cons 8 "GROS$")))
)
(setq dist 8)
....

(setq obj (vlax-ename->vla-object (ssname ent 0)))
....

(vla-offset obj (* dist -1));outside
....
(command "-layer" "m" "GROS-EXT" "")
(command "change" "l" "" "p" "la" "gros-ext" "")
)


If the purpose of reversing a Polyline that goes the wrong way is merely so that you can Offset it and ensure the result will be outboard of the original, and you don't actually need the original to run in a particular direction for any other reason, then there are simpler ways to go about it.  For instance, you can just Offset it, compare the area of the result to the area of the original, and if it's smaller, get rid of that result and Offset the original in the other direction instead.  This does that, and is otherwise equivalent to your routine:

 

;;;gross p-line offset tool
(defun C:smileysurprised:F8 (/ ent obj objarea)
  (vl-load-com)
  (setq
    ent (ssget "X" (list (cons 8 "GROS$")))
    obj (vlax-ename->vla-object (ssname ent 0))
  )
  (command "_.area" "_o" ent)
  (setq objarea (getvar 'area)); area of original
  (vla-offset obj 8); to right
  (command "_.area" "_o" (entlast))
  (if (> objarea (getvar 'area)); it went inboard [result's area is smaller]
    (progn
      (entdel (entlast))
      (vla-offset obj -8) to left instead, for outboard result
    ); progn
  ); if
  (command "-layer" "m" "GROS-EXT" "")
  (command "change" "l" "" "p" "la" "gros-ext" "")
)

 

Another way would be to Offset it using a to-which-side point that you know will be outboard of the original:

 

;;;gross p-line offset tool
(defun C:smileysurprised:F8 (/ ent obj LL UR)
  (vl-load-com)
  (setq
    ent (ssget "X" (list (cons 8 "GROS$")))
    obj (vlax-ename->vla-object (ssname ent 0))
  )
  (vla-getboundingbox obj 'minpt 'maxpt)
  (setq
    LL (vlax-safearray->list minpt)
    UR (vlax-safearray->list maxpt)
  )
  (command
    "_.offset" 8 ent (polar UR (angle LL UR) 1) "" ; guaranteed outside [to upper right]
    "-layer" "m" "GROS-EXT" ""
    "chprop" "l" "" "la" "gros-ext" ""
  )
)

Distinguished Mentor
gasty1001
Posts: 582
Registered: ‎04-11-2010
Message 2 of 10 (1,083 Views)

Re: Make polyline clockwise if counter clockwise

06-07-2012 09:29 AM in reply to: cummins600

Hi,

 

The command "PEDIT" has a reverse option since 2010 if I recall correctly.

 

Gaston Nunez

*Expert Elite*
Kent1Cooper
Posts: 5,879
Registered: ‎09-13-2004
Message 3 of 10 (1,076 Views)

Re: Make polyline clockwise if counter clockwise

06-07-2012 10:25 AM in reply to: cummins600

cummins600 wrote:

Is it possible to make a ployline clockwise if it is currently counter clockwise? ....


Put something like "Reverse Polyline" into the Search window -- lots of threads on this topic.

Kent Cooper
Valued Contributor
cummins600
Posts: 97
Registered: ‎03-24-2004
Message 4 of 10 (1,073 Views)

Re: Make polyline clockwise if counter clockwise

06-07-2012 10:39 AM in reply to: cummins600

I should note that I need it to do it automatically w/o user input. If possible, i'd like for it to make any p-line of choice clockwise if it was counter-clock. Can't fid that code for some reason.

Distinguished Mentor
gasty1001
Posts: 582
Registered: ‎04-11-2010
Message 5 of 10 (1,068 Views)

Re: Make polyline clockwise if counter clockwise

06-07-2012 10:58 AM in reply to: cummins600

Hi,

 

It seems what you need it's  the algorithm to check if a polyline is CW or CCW, this can be checked with the signed area algorithm, very easy to implement, see here:http://demonstrations.wolfram.com/SignedAreaOfAPolygon/,  (note that you only need the sign in that formula) and then you can proceed to reverse or not the polyline with something like (command "pedit" MyPolyEnt "r" "").

 

Gaston Nunez

*Expert Elite*
Kent1Cooper
Posts: 5,879
Registered: ‎09-13-2004
Message 6 of 10 (1,061 Views)

Re: Make polyline clockwise if counter clockwise

06-07-2012 11:13 AM in reply to: cummins600

cummins600 wrote:

I should note that I need it to do it automatically w/o user input. If possible, i'd like for it to make any p-line of choice clockwise if it was counter-clock. Can't fid that code for some reason.


There are also a number of threads you can Search for here on determining whether a closed Polyline runs CW or CCW.

Kent Cooper
Active Contributor
leipogs23
Posts: 34
Registered: ‎08-15-2008
Message 7 of 10 (1,043 Views)

Re: Make polyline clockwise if counter clockwise

06-08-2012 02:51 AM in reply to: cummins600

I think the easiest algorithm is to use the formula for getting area from polygon coordinates.

It gives positive area if clockwise and negative if counter if I'm not mistaken.

 

Then just issue the pedit reverse.

Valued Contributor
cummins600
Posts: 97
Registered: ‎03-24-2004
Message 8 of 10 (1,033 Views)

Re: Make polyline clockwise if counter clockwise

06-08-2012 07:22 AM in reply to: cummins600

Here is a sweet bit of code to give CW or CCW. Now if I can harness this somehow.

 

(defun C:smileytongue:olyDir ( / @delta @cv_parse_list @polydir 2pi e ans)
;;-----------------------------------------------------------------------
;; This function returns the deflection angle (in radians) of two angles:
;;
(defun @delta (a1 a2)
(cond
((> a1 (+ a2 pi))
(setq a2 (+ a2 2pi))
)
((> a2 (+ a1 pi))
(setq a1 (+ a1 2pi))
)
)
(- a2 a1)
)
;;-------------------------------------------------------------
;; Function returns a list of 3D points from a continuous list
;; as returned by (vlax-safearray->list (vlax-variant-value X))
;;
(defun @cv_parse_list (data n / item new)
(foreach element (reverse data)
(setq item (cons element item))
(if (= (length item) n)
(setq new (cons item new) item nil)
)
)
new
)
(defun @polydir (e / ent etype object coords flag i p1 p2 p3 sum)
(cond
((/= (type e) 'ENAME) nil)
((not (vl-position (setq etype (cdr (assoc 0 (setq ent (entget e)))))
'("AECC_CONTOUR" "LWPOLYLINE" "POLYLINE")))
(prompt (strcat " Object selected is a(n) " etype))
)
((and (setq flag (cdr (assoc 70 ent)))(> (boole 1 16 flag) 0))
(prompt " Object selected is a 3DMESH")
)
(1 (setq object (vlax-ename->vla-object e)
coords (vlax-get object "Coordinates")
coords (@cv_parse_list coords (if (= etype "LWPOLYLINE") 2 3))
i 1
sum 0.0
)
(and
flag
(= (logand 1 flag) 1) ; closed
(setq coords (reverse (cons (car coords)(reverse coords))))
)
(repeat (- (length coords) 2)
(setq p1 (nth (1- i) coords)
p2 (nth i coords)
i (1+ i)
p3 (nth i coords)
sum (+ sum (@delta (angle p1 p2)(angle p2 p3)))
)
)
(if (minusp sum) "CW" "CCW")
)
)
)
(setvar "errno" 0)
(setq 2pi (* pi 2))
(while (/= (getvar "errno") 52)
(if (setq ans (@polydir (setq e (car (entsel "\nSelect a polyline: ")))))
(princ ans)
)
)
(princ)
)

*Expert Elite*
Kent1Cooper
Posts: 5,879
Registered: ‎09-13-2004
Message 9 of 10 (1,020 Views)

Re: Make polyline clockwise if counter clockwise

06-08-2012 11:32 AM in reply to: cummins600

cummins600 wrote:

Is it possible to make a ployline clockwise if it is currently counter clockwise? My issues is the routine below that I use is based on the pline beining consitant and they are not from dwg to dwg. Any help is welcome. Thanks.

 

;;;gross p-line offset tool

(defun c:smileysurprised:f8 (/ ent dist obj)
(vl-load-com)
....

(setq ent (ssget "X" (list (cons 8 "GROS$")))
)
(setq dist 8)
....

(setq obj (vlax-ename->vla-object (ssname ent 0)))
....

(vla-offset obj (* dist -1));outside
....
(command "-layer" "m" "GROS-EXT" "")
(command "change" "l" "" "p" "la" "gros-ext" "")
)


If the purpose of reversing a Polyline that goes the wrong way is merely so that you can Offset it and ensure the result will be outboard of the original, and you don't actually need the original to run in a particular direction for any other reason, then there are simpler ways to go about it.  For instance, you can just Offset it, compare the area of the result to the area of the original, and if it's smaller, get rid of that result and Offset the original in the other direction instead.  This does that, and is otherwise equivalent to your routine:

 

;;;gross p-line offset tool
(defun C:smileysurprised:F8 (/ ent obj objarea)
  (vl-load-com)
  (setq
    ent (ssget "X" (list (cons 8 "GROS$")))
    obj (vlax-ename->vla-object (ssname ent 0))
  )
  (command "_.area" "_o" ent)
  (setq objarea (getvar 'area)); area of original
  (vla-offset obj 8); to right
  (command "_.area" "_o" (entlast))
  (if (> objarea (getvar 'area)); it went inboard [result's area is smaller]
    (progn
      (entdel (entlast))
      (vla-offset obj -8) to left instead, for outboard result
    ); progn
  ); if
  (command "-layer" "m" "GROS-EXT" "")
  (command "change" "l" "" "p" "la" "gros-ext" "")
)

 

Another way would be to Offset it using a to-which-side point that you know will be outboard of the original:

 

;;;gross p-line offset tool
(defun C:smileysurprised:F8 (/ ent obj LL UR)
  (vl-load-com)
  (setq
    ent (ssget "X" (list (cons 8 "GROS$")))
    obj (vlax-ename->vla-object (ssname ent 0))
  )
  (vla-getboundingbox obj 'minpt 'maxpt)
  (setq
    LL (vlax-safearray->list minpt)
    UR (vlax-safearray->list maxpt)
  )
  (command
    "_.offset" 8 ent (polar UR (angle LL UR) 1) "" ; guaranteed outside [to upper right]
    "-layer" "m" "GROS-EXT" ""
    "chprop" "l" "" "la" "gros-ext" ""
  )
)

Kent Cooper
Valued Contributor
cummins600
Posts: 97
Registered: ‎03-24-2004
Message 10 of 10 (1,009 Views)

Re: Make polyline clockwise if counter clockwise

06-08-2012 02:19 PM in reply to: Kent1Cooper

Sweet. That works very well! Thanks.

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.