Author Topic: Check polyline for square/rectangle  (Read 22669 times)

0 Members and 2 Guests are viewing this topic.

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Check polyline for square/rectangle
« Reply #45 on: January 11, 2013, 02:05:43 AM »
Uh oh. Bad programmer, bad!

http://otb.manusoft.com/2013/01/quirkypolyline-exposing-foolish-programmers.htm

Your polyline, easily returned to the default status.
If Autodesk will use only QuirkyPolyline, I will not be difficult to replace the library function vlax-curve* its eea-curve*...

Code - Auto/Visual Lisp: [Select]
  1. (defun eea-normalise-param-lwpoly (/ s)
  2.   (if (setq s (ssget "_x" '((0 . "lwpolyline"))))
  3.     (foreach a (ssnamex s) (entmakex (entget (cadr a))) (entdel (cadr a)))
  4.   )
  5.   (princ)
  6. )

ps. I would not assess the programmers of the parameter polylines!

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Check polyline for square/rectangle
« Reply #46 on: January 11, 2013, 05:14:43 AM »
Had mistake with old heavy pline - code now updated...

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Check polyline for square/rectangle
« Reply #47 on: January 11, 2013, 06:56:15 AM »
I fixed it till now... There was case with it was failing... See picture...

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

LE3

  • Guest
Re: Check polyline for square/rectangle
« Reply #48 on: January 11, 2013, 09:52:51 AM »
been a while of not doing lisp, so just trying to add something:
a simple routine to test on lwpolylines - no error control - guess that some progn's usage are not required, but.... have fun!
Code: [Select]
(vl-load-com)
(defun rtd (a /) (* (/ a pi) 180.0))
(defun C:TST (/ e shape coords sides isShape p1 p2 p3 p4)
(setq e (car (entsel)))
(setq shape (vlax-ename->vla-object e))
(setq coords (vlax-get shape 'coordinates))
(setq sides (/ (length coords) 2))
(setq isShape "Undefined")
(if (and (eq sides 4) (vl-every 'zerop (mapcar '(lambda (i) (vla-getBulge shape i)) (list 0 1 2 3))))
  (progn
    (setq p1 (list (nth 0 coords) (nth 1 coords)))
    (setq p2 (list (nth 2 coords) (nth 3 coords)))
    (setq p3 (list (nth 4 coords) (nth 5 coords)))
    (setq p4 (list (nth 6 coords) (nth 7 coords)))
    (if (and (and (eq (angle p1 p2) (angle p4 p3)) (eq (angle p1 p4) (angle p2 p3)))
     (or (equal (abs (rtd (- (angle p2 p3) (angle p1 p2)))) 90.0 0.001)
(equal (abs (rtd (- (angle p2 p3) (angle p1 p2)))) 270.0 0.001))) ;; is rectangle test
      (progn
(setq isShape "Rectangle")
(if (equal (distance p2 p3) (distance p1 p2) 0.001) ;; test for square
  (progn
    (setq isShape "Square")))))))
  (princ isShape) (princ))

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Check polyline for square/rectangle
« Reply #49 on: January 11, 2013, 10:49:51 AM »
Your polyline, easily returned to the default status.

Very clever, however this will not work for custom classes derived from AcDbPolyline.

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Check polyline for square/rectangle
« Reply #50 on: January 12, 2013, 05:00:51 PM »
I'd rethink it with a simple test:


Are the mid points of the diagonals equal

Code: [Select]
;;;TEST FOR 4 POINTS CREATING A RECTANGLE ( or Square )
;;;ARG -> 4 POINTS in EITHER CW or CCW ORDER & Fuzz
;;;RET -> T nil
(defun is_pt_lst_rect (p1 p2 p3 p4 fuzz)
  (equal (mapcar '(lambda (a b) (* (+ a b) 0.5)) p1 p3)
         (mapcar '(lambda (a b) (* (+ a b) 0.5)) p2 p4)
         fuzz))


Filtering out bulges, entity type etc would be up to the user but this should work regardless of UCS

-David

R12 Dos - A2K

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Check polyline for square/rectangle
« Reply #51 on: January 12, 2013, 06:13:46 PM »
Are the mid points of the diagonals equal

You also have to test whether the diagonals are the same length, otherwise a parallelogram creates a false positive.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Check polyline for square/rectangle
« Reply #52 on: January 12, 2013, 06:38:28 PM »
Not quite David.
Code: [Select]
(entmakex
'(
(0 . "LWPOLYLINE")
(100 . "AcDbEntity")
(67 . 0)
(62 . 7)
(100 . "AcDbPolyline")
(90 . 4)
(70 . 1)
(43 . 0.0)
(38 . 0.0)
(39 . 0.0)
(10 56.8437 167.707)
(40 . 0.0)
(41 . 0.0)
(42 . 0.0)
(10 68.8437 -1.2646e-014)
(40 . 0.0)
(41 . 0.0)
(42 . 0.0)
(10 0.0 0.0)
(40 . 0.0)
(41 . 0.0)
(42 . 0.0)
(10 12.0 167.707)
(40 . 0.0)
(41 . 0.0)
(42 . 0.0)
(210 0.0 0.0 1.0)))
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Check polyline for square/rectangle
« Reply #53 on: January 12, 2013, 08:37:34 PM »
More code.  8-)
Code - Auto/Visual Lisp: [Select]
  1. (defun rectangle-p      (ename fuzz / el pts bul)
  2.   (and (eq (type ename) 'ename)
  3.        (eq (cdr (assoc 0 (setq el (entget ename)))) "LWPOLYLINE")
  4.        (mapcar (function (lambda (x) (cond ((= (car x) 10)(setq pts (cons (cdr x) pts)))
  5.                                            ((= (car x) 42)(setq bul (cons (cdr x) bul))))))
  6.                el)
  7.        (= (length pts) 4)
  8.        (vl-every 'zerop bul)
  9.        (equal (distance (car pts) (caddr pts)) (distance (cadr pts) (cadddr pts)) fuzz)
  10.        (equal (polar (car pts)(angle (car pts) (caddr pts)) (/ (distance (car pts) (caddr pts)) 2))
  11.               (polar (cadr pts)(angle (cadr pts) (cadddr pts)) (/ (distance (cadr pts) (cadddr pts)) 2))
  12.          fuzz)
  13.   )
  14. )
« Last Edit: January 13, 2013, 12:08:39 PM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Check polyline for square/rectangle
« Reply #54 on: January 13, 2013, 06:59:06 AM »
OK  I'll buy that.  -David
R12 Dos - A2K

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Check polyline for square/rectangle
« Reply #55 on: January 13, 2013, 10:17:59 AM »
Back to the vlax-curve idea - but for regular polygons and rectangles:
Code - Auto/Visual Lisp: [Select]
  1.  
  2. (defun RegularPolygon-p (obj fuzz / n i half V1s V1m V1e V2s V2m V2e stillTrue)
  3.   (if (and (vlax-curve-isClosed obj) (= (rem (setq n (vlax-curve-getEndParam obj)) 2) 0.0))
  4.     (progn (setq i (1+ n) half (/ (fix n) 2) stillTrue t)
  5.       (while (and stillTrue (> (setq i (1- i)) half))
  6.         ;; Get the opposing vectors' start mid & end points
  7.         (mapcar '(lambda (var par) (set var (vlax-curve-getPointAtParam obj par)))
  8.                 '(V1s V1m V1e V2s V2m V2e)
  9.                 (list (- i half 1) (- i half 0.5) (- i half) (- i 1) (- i 0.5) i))
  10.         (setq stillTrue (and (equal (angle V1s V1m) (angle V1m V1e) fuzz) ;Check 1st vector bulge
  11.                              (equal (angle V2s V2m) (angle V2m V2e) fuzz) ;Check 2nd vector bulge
  12.                              (equal (distance V1s V1e) (distance V2s V2e) fuzz) ;Check vectors equal length
  13.                              (equal (distance V1s V2e) (distance V2s V1e) fuzz)))) ;Check diagonals equal length
  14.       (if stillTrue (fix n))))) ;Return number of vectors or nil if not regular
Now: I'm unsure what to do since the function name clearly states it should be regular polygons, but a rectangle is strictly speaking not "regular". So should consecutive vectors' lengths also be checked? That's not actually what the OP asked for is it?
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

pBe

  • Bull Frog
  • Posts: 402
Re: Check polyline for square/rectangle
« Reply #56 on: January 13, 2013, 10:48:59 AM »
I thought just by checking all corner angles are perpendicular would be enough to say "by george it is indeed a rectangle!!"   ;D 


I'll start digging thru them wonderful codes and try to figure out what i'm missing.  :)


dig...dig...dig...
« Last Edit: January 13, 2013, 11:02:15 AM by pBe »

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Check polyline for square/rectangle
« Reply #57 on: January 14, 2013, 06:56:58 AM »
I thought just by checking all corner angles are perpendicular would be enough to say "by george it is indeed a rectangle!!"   ;D 

Indeed it is  :-)

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Check polyline for square/rectangle
« Reply #58 on: January 14, 2013, 07:01:45 AM »
Back to the vlax-curve idea - but for regular polygons and rectangles

What about equilateral triangles / pentagons / heptagons / nonagons ...  :wink:

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Check polyline for square/rectangle
« Reply #59 on: January 14, 2013, 07:33:51 AM »
Yes I noticed the mistake after I posted the code yesterday. Just didn't have the time to fix it yet. Maybe later tonight. I'm thinking: "Just use the normal definition of regular polygons". I.e. all sides equal and all inner angles equal. Of course there should be at least 3 vectors (a 2 vector closed polyline wouldeffectively pass that test, but is it a polygon?)

In any case the OP simply wanted to know if rectangular. I think somewhere I say "Regular Polygon" and went a bit wonky - by implementing something neither here nor there.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.