Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Make polyline clockwise if counter clockwise

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
cummins600
2633 Views, 9 Replies

Make polyline clockwise if counter clockwise

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:of8 (/ ent dist obj)
(vl-load-com)
;(setq ent (car (entsel "\nSelect line to offset: "))
(setq ent (ssget "X" (list (cons 8 "GROS$")))
)
(setq dist 😎
;(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" "")
)

9 REPLIES 9
Message 2 of 10
hgasty1001
in reply to: cummins600

Hi,

 

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

 

Gaston Nunez

Message 3 of 10
Kent1Cooper
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, AIA
Message 4 of 10
cummins600
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.

Message 5 of 10
hgasty1001
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

Message 6 of 10
Kent1Cooper
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, AIA
Message 7 of 10
leipogs23
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.

Message 8 of 10
cummins600
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:PolyDir ( / @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)
)

Message 9 of 10
Kent1Cooper
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:of8 (/ ent dist obj)
(vl-load-com)
....

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

(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:OF8 (/ 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:OF8 (/ 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, AIA
Message 10 of 10
cummins600
in reply to: Kent1Cooper

Sweet. That works very well! Thanks.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost