Irregular room

Irregular room

Anonymous
Not applicable
2,245 Views
18 Replies
Message 1 of 19

Irregular room

Anonymous
Not applicable

Is there a lisp that creates an irregular room (closed polyline) based on the four dimensional wall and two diagonal entries?

0 Likes
Accepted solutions (2)
2,246 Views
18 Replies
Replies (18)
Message 2 of 19

stevor
Collaborator
Collaborator

Could be, if there is a sequence order to the 6 distances,

and the orientation might be if two sides were constrained.

So, show your data format.

S
0 Likes
Message 3 of 19

Kent1Cooper
Consultant
Consultant

@stevor wrote:

... if there is a sequence order to the 6 distances, and the orientation might be if two sides were constrained.

....


Yes, because without some kind of particulars like those, there are an infinite number of solutions to the same set of "raw" distances:

 

Irregular.PNG

 

And that's just if you know which two are the diagonals [yellow].  If the list of distances doesn't differentiate those from the edges, it might be possible for a routine to figure out which they need to be for a viable solution, but I expect it would be a real challenge.

Kent Cooper, AIA
0 Likes
Message 4 of 19

CADaSchtroumpf
Advisor
Advisor
Accepted solution

I use this for draw polygon with diagonal (diagonal is the segment base in my lisp)

Run twice for draw polyligne with 4 edge

 

(defun 2xderr (ch)
  (cond
    ((eq ch "Function cancelled") nil)
    ((eq ch "quit / exit abort") nil)
    ((eq ch "console break") nil)
    (T (princ ch))
  )
  (setvar "cmdecho" v1)
  (setvar "orthomode" v2)
  (setvar "osmode" v3)
  (setvar "blipmode" v4)
  (setvar "plinewid" v5)
  (setq *error* olderr)
  (princ)
)
(defun c:2xd ( / v1 v2 v3 v4 v5 cc1 r1 cc2 r2 dce xi yi i cr1 cr2 vi xt yt h1 h2 h i1 i2 ss1 ss2 key olderr)
  (setq
    v1 (getvar "cmdecho")
    v2 (getvar "orthomode")
    v3 (getvar "osmode")
    v4 (getvar "blipmode")
    v5 (getvar "plinewid")
  )
  (setvar "cmdecho" 0)
  (setvar "orthomode" 0)
  (setvar "blipmode" 0)
  (setvar "plinewid" 0)
  (setq olderr *error* *error* 2xderr)  
  (initget 9)
  (setq cc1 (getpoint "\nFirst base point ?: "))
  (initget 9)
  (setq cc2 (getpoint cc1 "\nSecond base point ?: "))
  (grdraw cc1 cc2 1)
  (initget 39)
  (setq r1 (getdist cc1 "\nGive the first radius length : "))
  (initget 39)
  (setq r2 (getdist cc2 "\nGive the second radius length : "))
  (grdraw cc1 cc2 0)
  (setvar "osmode" 0)
  (setq dce (distance cc1 cc2))
  (if (equal (/ dce (+ r1 r2)) (1+ 0E-12))
    (setq
      xi (/ (+ (* r2 (car cc1)) (* r1 (car cc2))) dce)
      yi (/ (+ (* r2 (cadr cc1)) (* r1 (cadr cc2))) dce)
      i (cons xi (cons yi '(0.0)))
    )
    (if (and (not (zerop (- r1 r2))) (equal (/ dce (abs (- r1 r2))) (1+ 0E-12)))
      (progn
        (if (= r1 (max r1 r2))
          (setq cr1 cc1 cr2 cc2)
          (setq cr1 cc2 cr2 cc1)
        )
        (setq
          xi (/ (- (* (max r1 r2) (car cr2)) (* (min r1 r2) (car cr1))) dce)
          yi (/ (- (* (max r1 r2) (cadr cr2)) (* (min r1 r2) (cadr cr1))) dce)
          i (cons xi (cons yi '(0.0)))
        )
      )
      (progn
        (if (or (> dce (+ r1 r2)) (< (+ (min r1 r2) dce) (max r1 r2)))
          (princ "\nNot intersection !...")
          (progn
            (setq vi (angle cc1 cc2))
            (if (> r1 r2)
              (setq
                xt (- (/ (* (+ r1 dce r2) (- (+ r1 dce) r2)) (* 2 dce)) r1)
                yt (- dce xt)
                h1 (sqrt (- (expt r1 2) (expt xt 2)))
                h2 (sqrt (- (expt r2 2) (expt yt 2)))
                xi (/ (+ (* yt (car cc1)) (* xt (car cc2))) dce)
                yi (/ (+ (* yt (cadr cc1)) (* xt (cadr cc2))) dce)
              )
              (setq
                xt (- (/ (* (+ r2 dce r1) (- (+ r2 dce) r1)) (* 2 dce)) r2)
                yt (- dce xt)
                h1 (sqrt (- (expt r2 2) (expt xt 2)))
                h2 (sqrt (- (expt r1 2) (expt yt 2)))
                xi (/ (+ (* xt (car cc1)) (* yt (car cc2))) dce)
                yi (/ (+ (* xt (cadr cc1)) (* yt (cadr cc2))) dce)
              )
            )
            (setq
              h (/ (+ h1 h2) 2)
              i1 (polar (cons xi (cons yi '(0.0))) (+ vi (/ pi 2)) h)
              i2 (polar (cons xi (cons yi '(0.0))) (- vi (/ pi 2)) h)
            )
            (if (zerop (getvar "PICKFIRST")) (setvar "PICKFIRST" 1))
            (command "_.pline" cc1 i1 cc2 "")
            (setq ss1 (ssget "_L"))
            (command "_.pline" cc1 i2 cc2 "")
            (setq ss2 (ssget "_L"))
            (if (and ss1 ss2 (= 0 (getvar "CMDACTIVE"))) 
              (progn
                (sssetfirst nil ss2)
                (princ "\n<Move cursor> for choice; <Enter>/[Space]/Rigth-click for end!.")
                (while (and (not (member (setq key (grread T 4 2)) '((2 13) (2 32)))) (/= (car key) 25))
                  (cond
                    ((eq (car key) 5)
                      (if (< (distance i1 (cadr key)) (distance i2 (cadr key)))
                        (sssetfirst nil ss1)
                        (sssetfirst nil ss2)
                      )
                    )
                  )
                )
              )
            )
            (command "_.erase")
          )
        )
      )
    )
  )
  (setvar "cmdecho" v1)
  (setvar "orthomode" v2)
  (setvar "osmode" v3)
  (setvar "blipmode" v4)
  (setvar "plinewid" v5)
  (setq *error* olderr)
  (prin1)
)
0 Likes
Message 5 of 19

SeeMSixty7
Advisor
Advisor

I would just draw your room (rectangle) then use the CHAMFER command to drop in your angled sides. It looks like there is confusion on what exactly you are looking for.

 

I took your request to mean you had a rectangular room with two angled entries on two of the corners, making it irregular. If that's the case CHAMFER will work great for you.

 

Good luck,

 

0 Likes
Message 6 of 19

stevor
Collaborator
Collaborator

This seems to produce a quad polygon, and the mirror of it, based on:

the 1st leg pts, 2nd dist, its diagonal dist, 4th dist, and its diagonal.

 

; Arc Cosine
 (defun A_Cos (X) (cond ((not (numberp X)) niL )
    ((= x 1.) 0.)  ((= X -1.) pi)
    (T (- (/ pi 2.) (atan (/ X (sqrt (abs (- 1. (* X X)))))))) ));

    ; a^=b^+c^-2bc cos A,  A = arccos ((b^ + c^ - a^) / 2bc)
 (defun A_Cos3 (A B C) ; Angle A is opposite side A
  (if (and (/= 0 B) (/= 0 C))
   (A_Cos (/ (- (+ (* B B) (* C C )) (* A A) ) (* 2 B C) ))) )

  ; P4           P3  
  ;    D24    D13
  ;             D23  
  ;      a   b
  ;    P1      P2     
  ; quadrilaterals by seg.1-2, Dists to CCW pts 3,4
  (Defun Quad_Diag (P1 P2 D23 D13 D24 D41 / A1 ) ; ETC
   ; (GRAPHSCR) (redraw) (gr_ddc P1 1 7) (grdraw p1 p2 7)  
   (setq D12 (distance P1 P2)  A12 (angle P1 P2)  AQ (/ pi 2)
         A1 (A_Cos3 D23 D12 D13) ; oppo A1, stbd side, port
         P3db (* D13 (cos A1))    P3dh (* D13 (sin A1))
         P3P12 (polar P1 A12 P3db) ; P3 perp on P1-P2 ray
         P3P (polar P3P12 (+ A12 AQ) P3dh) ; turn port +
         P3S (polar P3P12 (- A12 AQ) P3dh) ; starboard -
         A2 (A_Cos3 D41 D24 D12) z(PN_"a2")
         P4db (* D24 (cos A2))    P4dh (* D24 (sin A2))
         P4P12 (polar P2 (- A12 pi) P4db) ; P4 perp on P1-P2 ray
         P4P (polar P4P12 (+ A12 AQ) P4dh) ; turn port +
         P4S (polar P4P12 (- A12 AQ) P4dh) ; starboard -
    )   (list P3P P4P  P3S P4S) ) ; 

 

 P3P P4P  are the pts to one quad,  P3S P4S  the mirror.

S
0 Likes
Message 7 of 19

Anonymous
Not applicable

This looks like a good solution. Over the intersection of the circles are obtained pages.

0 Likes
Message 8 of 19

Anonymous
Not applicable

These dimensions give shape to the same polygon that if we look rotated.

0 Likes
Message 9 of 19

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

These dimensions give shape to the same polygon that if we look rotated.


Post a drawing or an image.  I'm having a hard time understanding what you are trying to do, and obviously people are interpreting it in different ways.

Kent Cooper, AIA
0 Likes
Message 10 of 19

SeeMSixty7
Advisor
Advisor

You are not alone. LOL

0 Likes
Message 11 of 19

Kent1Cooper
Consultant
Consultant

In case perhaps what you mean is something like this [a room that's regular in overall rectangular shape, but with the irregularity of diagonal chamfered corners]:

IrregularRoom.png

 

then I have a routine that will Chamfer a corner when what you know is the desired width of the resulting new edge [the "diagonal" in your description?], rather than the distance back from the intersection [or apparent intersection] of two selected edges.  ChamferWidth.lsp with its CW command is available here.  But be aware that it works only on Lines, not on corners of Polylines -- something could probably be developed to do the latter, but it would be more complicated.

Kent Cooper, AIA
0 Likes
Message 12 of 19

Anonymous
Not applicable

I need to draw a field that was measured in the terrain or draw an apartment using the measured dimensions of the rooms.
In reality there is no perfect (90°) rectang field or room. The goal is to transfer the existing state to the computer.

0 Likes
Message 13 of 19

Anonymous
Not applicable

With CHAMFER command I get more and more pages. The goal is to bring all measured pages into a relationship.

0 Likes
Message 14 of 19

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

I need to draw a field that was measured in the terrain or draw an apartment using the measured dimensions of the rooms.
In reality there is no perfect (90°) rectang field or room. The goal is to transfer the existing state to the computer.


I don't think you will find an automated solution.  If there are more than three edges, and you know only their lengths [I am assuming that from Post 1, but maybe that's not what you meant], there are an infinite number of solutions, so even if an AutoLisp routine could somehow be made to find one of them, it is not likely to be the correct one.  You would need a survey that includes angles as well as lengths.

Kent Cooper, AIA
0 Likes
Message 15 of 19

Ranjit_Singh
Advisor
Advisor

Do we know the sequence/order of the sides? And also which corner has the diagonal? It's a lot more easier to do in LISP if we know the sequence and where the diagonal is placed. Lets say if you can provide input like lengths are 20 9 11 8 (in that order) and diagonal is for the 9 11 corner. Then it's a lot easier. Otherwise there are quite a few iterations.

I believe you should have the info I requested. If so can you confirm and maybe provide a sample input of 4 sides and one diagonal and its corner.

0 Likes
Message 16 of 19

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

@Anonymous wrote:

These dimensions give shape to the same polygon that if we look rotated.


Post a drawing or an image.  I'm having a hard time understanding what you are trying to do, and obviously people are interpreting it in different ways.


I repeat -- post something specific as an example, preferably an image or drawing file showing the distances and how they relate to each other, even if it's only approximate.  I'm not sure what you meant in Post 1 by "diagonal entries" -- are they entrances [e.g. doorways] into the room that are in diagonal walls at the corners of the room, as some are obviously thinking?  Or are they diagonal measurements between opposite corners of the room ["entries" in a list of measurements, not into a room]?  Post 12 suggests that, and that's what I was thinking in Post 3.  Also, I don't think "pages" [Posts 7 and 13] is the right English word for whatever you are talking about, but I can't figure out what the right word should be.  Is there someone more fluent in English who can word it differently for you?

Kent Cooper, AIA
Message 17 of 19

Ranjit_Singh
Advisor
Advisor
Accepted solution

Try below code. It assumes you have 4 sides and 2 diagonals. Minimal testing and no error trap included.

;;creates closed polygon given 4 sides and 2 diagonals.
;;Ranjit Singh
;;4/28/2017
(defun somefunc5 (a b) (vlax-invoke a 'intersectwith b 0))
(defun somefunc4  (x)
 (cond ((null x) ())
       (t (cons (list (car x) (cadr x) (caddr x)) (somefunc4 (cdddr x))))))
(defun somefunc3  (a b)
 (vlax-ename->vla-object (entmakex (list '(0 . "CIRCLE") (cons 10 a) (cons 40 b)))))
(defun somefunc2  (a b c d e f / adoc lst)
 (cond ((and (< e (+ a d)) (< a (+ e f)) (< a (+ b c d)))
        (vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
        (mapcar '(lambda (x)
                  (mapcar '(lambda (y)
                            (mapcar '(lambda (z1 z2)
                                      (mapcar '(lambda (x) (setq lst (cons (list '(0 0) (list a 0 0) y x) lst)))
                                              (vl-remove-if '(lambda (x) (< (cadr x) 0))
                                                            (somefunc4 (somefunc5 (somefunc3 y z2) (somefunc3 '(0 0 0) z1))))))
                                    (vl-remove x (list b c d))
                                    (reverse (vl-remove x (list b c d)))))
                          (vl-remove-if '(lambda (x) (< (cadr x) 0))
                                        (somefunc4 (somefunc5 (somefunc3 '(0 0 0) e) (somefunc3 (list a 0 0) x))))))
                (list b c d))
        (vla-endundomark adoc)
        (vl-cmdf "._undo" "")
        (and lst
        (entmakex
         (append '((0 . "LWPOLYLINE") (100 . "AcDbEntity") (100 . "AcDbPolyline") (90 . 4) (70 . 1))
                 (mapcar '(lambda (x) (cons 10 x))
                         (mapcar '(lambda (x)
                                   (if (< (length x) 3)
                                    (reverse (cons 0 (reverse x)))
                                    x))
                                 (cdar (vl-sort (mapcar '(lambda (x) (cons (abs (- f (distance (cadr x) (cadddr x)))) x)) lst)
                                                '(lambda (x y) (< (car x) (car y)))))))))
        (command-s "._move" (entlast) "" '(0 0 0) (getpoint "\nSelect insertion point")))
        (princ))
       (print "Solution not possible. Check data!")))
(defun c:somefunc  (/ lst)
 (eval
  (append (list somefunc2)
          (mapcar '(lambda (x) (nth x lst))
                  (vl-sort-i (setq lst (mapcar '(lambda (x) (getreal (strcat "\nEnter " x " side:"))) '("1st" "2nd" "3rd" "4th")))
                             '>))
          (mapcar '(lambda (x) (nth x lst))
                  (vl-sort-i (setq lst (mapcar '(lambda (x) (getreal (strcat "\nEnter " x " diagonal:"))) '("1st" "2nd")))
                             '<)))))
0 Likes
Message 18 of 19

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:
... are they diagonal measurements between opposite corners of the room ...?  .....

On the assumption that that's the idea, here's another way to do it:

(defun Quad42 ; = Quadrilateral given lengths of 4 edges & 2 diagonals
  ; First 4 arguments are edge lengths, 5th & 6th are diagonal lengths;
  ;   5th must be diagonal from 1st to 3rd point [start of 1st edge to end of 2nd].
  ; Draws roughly centered in screen, 1st edge [AB] horiz. left-to-right as base;
  ;   A is lower left, B lower right, C upper right, D upper left.
  ; Move/Rotate/Mirror result as appropriate.
  ; If any inaccuracy in measurements, diagonal BD will not meet D exactly. 
  (AB BC CD AD AC BD / osm A B c1 c2 intC C intD D)
  (setq
    osm (getvar 'osmode)
    A (mapcar '- (getvar 'viewctr) (list (/ AB 2.0) (/ AD 2.0) 0))
    B (polar A 0 AB)
  ); setq
  (setvar 'osmode 0)
  (command "_.circle" A AC) (setq c1 (vlax-ename->vla-object (entlast)))
  (command "_.circle" B BC) (setq c2 (vlax-ename->vla-object (entlast)))
  (setq
    intC (vlax-invoke c1 'intersectwith c2 acExtendNone)
    C
    (if (> (nth 1 intC) (nth 4 intC)); first Y coordinate higher
      (reverse (cdddr (reverse intC))); then -- first 3
      (cdddr intC); else -- last 3
    ); if & C
  ); setq
  (command "_.erase" "_last" "" "_.erase" "_last" "")
  (command "_.circle" C CD) (setq c1 (vlax-ename->vla-object (entlast)))
  (command "_.circle" A AD) (setq c2 (vlax-ename->vla-object (entlast)))
  (setq
    intD (vlax-invoke c1 'intersectwith c2 acExtendNone)
    D
    (if (> (nth 1 intD) (nth 4 intD)); first Y coordinate higher
      (reverse (cdddr (reverse intD))); then -- first 3
      (cdddr intD); else -- last 3
    ); if & D
  ); setq
  (command
    "_.erase" "_last" "" "_.erase" "_last" ""
    "_.line" A B C D A C ""
    "_.line" B (polar B (angle B D) BD) ""
  ); command
  (setvar 'osmode osm)
  (princ)
); defun
(vl-load-com)
Kent Cooper, AIA
0 Likes
Message 19 of 19

Anonymous
Not applicable

There was an error writing.

Instead of the "pages" should write a "wall" or "site".

0 Likes