arrangement of rectangles from two points

arrangement of rectangles from two points

Anonymous
Not applicable
2,316 Views
14 Replies
Message 1 of 15

arrangement of rectangles from two points

Anonymous
Not applicable

This has probably already been answered but I haven't found it anywhere in the polls.
I'm trying to create an array from two points.
the objective is to set the corners of the rectangle and return the list with the insertion coordinates of each block.

in my role I can calculate the number of columns and rows, but I am having trouble doing the calculation to define the number of blocks to be inserted so that they never overlap, can someone help me ???
want to thank you.

in the image is the result waiting. I'm attaching a preview of the function I'm creating.

 

 

 

(
 (lambda ( / pt1 pt2 )
   (setq lst_ nil)
   (setq pt1 (getpoint) pt2 (getcorner pt1))
   (setq cols 2 rows 2) ;;How to calculate the number of columns and rows ??
   (setq x (/ (- (nth 0 pt2) (nth 0 pt1)) cols))
   (setq y (/ (- (nth 1 pt2) (nth 1 pt1)) rows))
   (setq xl 0 yl 0 )
   (repeat rows
     (setq pA (+ (nth 0 pt1) (/ x 2 ) (* x xl )))
     (setq PB (+ (nth 1 pt1) (/ y 2 ) (* y yl )))
    ;  (insert_block "teste" pA pB) ;just to view
     (setq c (append (list (list pA pB 0.00)) lst))
     (setq yl (+ yl 1))
   )
   (setq xl (+ xl 1))
 )
)

 

 

Frjuniornogueira_1-1609262999857.png

 

0 Likes
Accepted solutions (1)
2,317 Views
14 Replies
Replies (14)
Message 2 of 15

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

....
the objective is to set the corners of the rectangle and return the list with the insertion coordinates of each block.

... I am having trouble doing the calculation to define the number of blocks to be inserted so that they never overlap....


Are the Blocks always the same Block, and always the same size, as in the sample drawing?  Or would there be other Blocks, and/or might the User be asked for the size?

Kent Cooper, AIA
0 Likes
Message 3 of 15

Anonymous
Not applicable

Hi @Kent1Cooper 
The blocks will not always be the same size.
It is interesting that I have a variable that defines the length and width.

0 Likes
Message 4 of 15

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

... I have a variable that defines the length and width.


And how is that variable [or those variables] set?  If earlier in a larger routine, what are those variables called?  Or should this part of the routine ask the User for them?

 

The Blocks in the sample drawing are 190 units square, Inserted at scale factors of 1.  If the size varies, shouldn't the Block be defined at a size of 1, and the Inserted size be controlled by the scale factors?

Kent Cooper, AIA
0 Likes
Message 5 of 15

Anonymous
Not applicable
(setq block_height 190.00  block_width 190.00)
The scale factor will not change, it will always be 1.
 
0 Likes
Message 6 of 15

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:
(setq block_height 190.00  block_width 190.00)
The scale factor will not change, it will always be 1.

Does that mean you have a different Block definition for every possible combination of height and width a User might want?  Do the height and width become part of determining the Block name to Insert?

Kent Cooper, AIA
0 Likes
Message 7 of 15

Anonymous
Not applicable

Exactly!! however, they will always be rectangles or squares.

0 Likes
Message 8 of 15

Kent1Cooper
Consultant
Consultant
Accepted solution

Here's how I would do it [minimally tested in your sample drawing].  I don't have your (insert_block) function, so I used a regular Insert command.  Nor do I have whatever determines the Block name based on the width and height -- be sure to replace my fake name.  And I used preset values for the Block width and height to suit the Block in your drawing.

(
  (lambda ( / pt1 pt2 LL UR boxsize cols rows insX leftX insY)
;;;;; (setq block_width 190 block_height 190); [for testing]
    (setq
      lst nil
      pt1 (getpoint) pt2 (getcorner pt1)
      LL (mapcar 'min pt1 pt2); Lower Left corner
      UR (mapcar 'max pt1 pt2); Upper Right corner
      boxsize (mapcar '- UR LL)
      cols
        (+
          (fix (/ (car boxsize) block_width)); rounds down
          (if (= (rem (car boxsize) block_width) 0) 0 1)
            ; if divides exactly, leave it, otherwise add 1
        ); +
      rows
        (+
          (fix (/ (cadr boxsize) block_height))
          (if (= (rem (cadr boxsize) block_height) 0) 0 1)
        ); +
      insX (+ (car LL) (/ (- (car boxsize) (* block_width (1- cols))) 2))
      leftX insX ; for starting subsequent rows
      insY (+ (cadr LL) (/ (- (cadr boxsize) (* block_height (1- rows))) 2))
    ); setq
    (repeat rows
      (repeat cols
        (insert_block "BlockNameBasedOnWidthAndHeight" insX insY)
;;;;;        (command "_.insert" "BlockName" "_non" (list insX insY) 1 1 0); [for testing]
        (setq lst (append (list (list insX insY 0)) lst))
        (setq insX (+ insX block_width))
      ); repeat [cols]
      (setq insX leftX insY (+ insY block_height)); for next row
    ); repeat [rows]
  )
)

I also fixed the fact that you had a variable called lst_ in one place, but just lst in another, and used lst in place of your c variable so each would be appended to a cumulative list.

Kent Cooper, AIA
Message 9 of 15

Anonymous
Not applicable

Thanks, it works great !!!

0 Likes
Message 10 of 15

marko_ribar
Advisor
Advisor

What ab this case... Do you really want to put +1 ... Maybe you need +2 ...

 

      cols
        (+
          (fix (/ (car boxsize) block_width)); rounds down
          (if (= (rem (car boxsize) block_width) 0) 0 2)
            ; if divides exactly, leave it, otherwise add 2
        ); +
      rows
        (+
          (fix (/ (cadr boxsize) block_height))
          (if (= (rem (cadr boxsize) block_height) 0) 0 2)
        ); +

 

EXP.png

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 11 of 15

Kent1Cooper
Consultant
Consultant

@marko_ribar wrote:

.... Do you really want to put +1 ... Maybe you need +2 ...


@Anonymous would need to rule on the question.  In their original image and sample drawing, the insertion points of all Blocks are inside the rectangle defined by the two points.  Adding 1 is sufficient to completely cover the area of the rectangle with the minimum number of Blocks [I assumed that's the intent].  In your image, the insertion points of many of the Blocks are outside that rectangle, and more Blocks are used than are necessary to cover the area.  I won't assume whether that's desirable, or acceptable.  It happens that in both areas in their original, a Block insertion point falls at the center of the area, but that's not always the case, depending on the area's dimensions relative to the Block size -- the result can have, as in your image, a shared corner of 4 Blocks in the middle, or the midpoint of a shared edge of 2 Blocks.  Presumably, if the intent is that one of those relationships to the center is wanted, regardless of proportions or quantity of Blocks required, the code could be revised to make it come out that way.

Kent Cooper, AIA
0 Likes
Message 12 of 15

marko_ribar
Advisor
Advisor

I just wanted to say that OP should consider all situations that may occur... Depending on that number hardcoded there can be : (0 0) (1 0) (0 1) (1 1) (1 2) (2 1) (0 2) (2 0) (2 2) - 9 cases each situation is represented by number addons (row column)...

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 13 of 15

Kent1Cooper
Consultant
Consultant

It seems to me there would never be any reason to add more than 1 to the calculation of the number of columns or rows unless they want a particular relationship of Blocks at the middle of the area.  But it wouldn't be just a question of changing the 0-or-1 choice to 0-or-2, but rather a choice between 0, 1 and 2.

 

For example, let's say they always want a corner shared by 4 Blocks to fall at the middle, as in your image [they don't have that limitation, or they wouldn't have accepted my Solution, but just for argument's sake....].  That would mean they need even numbers of both rows and columns.

 

If the Block dimension divides exactly into the area dimension in a given direction, and the (fix)-rounded-down result is an even number, that will put a joint in the middle, so the number should be left alone [0 would be added to it].  But if it results in an odd number, then 1 should be added, to make it even.  2 would never be needed.

 

If it doesn't divide exactly, then something should always be added [0 would never be needed].  If the rounded result is odd, 1 should be added; if it's even, 2 should be added.

 

If they always want a Block insertion point at the middle of the area, similar reasoning would be used to ensure that the numbers of both rows and columns are always odd.

 

So @Anonymous, do you have any requirements different from my assumption of the minimum number of Blocks needed to completely cover the area [which never needs to add more than 1 to those numbers]?  Does the positioning of the Blocks in relation to the middle of the area matter?

Kent Cooper, AIA
0 Likes
Message 14 of 15

Anonymous
Not applicable

The Function @Kent1Cooper  created works perfectly for me. the intention of the program is not to insert blocks, but aerial images from google and OpenStreetMap.
I finished the program. there is the video in operation.

thank you very much for your help !!!

 

0 Likes
Message 15 of 15

emooreM7JMZ
Community Visitor
Community Visitor

 I have created a classic array of rectangles similar to this and have visibility differences set on them. My question is can you then reposition them all back to the starting point? So they would then overlap one another and I can then just have the visibility dropdown changes within the block to view the variations. I just want each of the degree changes to be selectable within my drawing.

0 Likes