Get PTMin, PTMax, Length, and width from Rotated Rectangular

Get PTMin, PTMax, Length, and width from Rotated Rectangular

abilabib
Advocate Advocate
524 Views
9 Replies
Message 1 of 10

Get PTMin, PTMax, Length, and width from Rotated Rectangular

abilabib
Advocate
Advocate

How to get PTMin, PTMax, Length, and width from Rotated Rectangular?

Rotating Rectangular.jpg

0 Likes
525 Views
9 Replies
Replies (9)
Message 2 of 10

Kent1Cooper
Consultant
Consultant

Is the PtMin common point the starting vertex of each Polyline?

Kent Cooper, AIA
Message 3 of 10

abilabib
Advocate
Advocate

@Kent1Cooper , 

 

I tried to get PtMin at the bottom left position because I wanna insert a block at that position. 

 

0 Likes
Message 4 of 10

pbejse
Mentor
Mentor

@abilabib wrote:

I tried to get PtMin at the bottom left position because I wanna insert a block at that position. 


 The current bottom left of the rotated rectangle?  That is not what is shown on the image at post # 1, hence the question from Kent

 

0 Likes
Message 5 of 10

abilabib
Advocate
Advocate

Hi @pbejse 

 

Yes, the current bottom is the base point for rotating rectangular. 

I tried to modify this code for my purpose. The original source from Lee Mac. 

I use this code to get PtMin for 90 degrees.

(setq ptmin (car (vl-sort PointList (function (lambda (e1 e2) (and (> (car e1) (car e2)) (< (cadr e1) (cadr e2))))))))

For some conditions work well. But at any condition (red rectangle) the minpoint is wrong. 

How to solve this one?
Missing loop point.jpg

 

(defun c:test ( / ent )
  (setq ss (ssget '((0 . "LWPOLYLINE")(8 . "RoofMat"))))
  (setq i 0)
  ;(setq InsPoint ())
  (repeat (sslength ss)
    ;mengambil data polyline
    (setq ent (ssname ss i))
    ;membuat rectangle dari data polyline
    (entmake
            (append
               '(
                    (000 . "LWPOLYLINE")
                    (100 . "AcDbEntity")
                    (100 . "AcDbPolyline")
                    (090 . 4)
                    (070 . 1)
                )
                (mapcar '(lambda ( x ) (cons 10 x)) (bbrotate ent))
            )
        )
    (setq el (entlast))
    (setq PointList
	 (mapcar 'cdr (vl-remove-if-not
			'(lambda (x) (= (car x) 10)) (entget el))
		 ))
    
    (setq ptmin (car (vl-sort PointList (function (lambda (e1 e2) (and (> (car e1) (car e2)) (< (cadr e1) (cadr e2))))))))	   
    (command "POINT" ptmin)
    (setq i (1+ i))
     );repeat
  (princ)
)
 
(defun bbrotate ( ent / ang dis enx itm len tmp )
    (setq enx (entget ent))
    (if (= 1 (logand 1 (cdr (assoc 70 enx))))
        (setq lst (list (cdr (assoc 10 (reverse enx)))))
    )
    (while (setq itm (assoc 10 enx))
        (setq lst (cons (cdr itm) lst)
              enx (cdr (member itm enx))
        )
    )
    (setq tmp lst
          len 0.0
    )
    (while (cadr tmp)
        (if (< len (setq dis (distance (car tmp) (cadr tmp))))
            (setq len dis
                  ang (angle (car tmp) (cadr tmp))
            )
        )
        (setq tmp (cdr tmp))
    )
    (setq lst (rotatepoints lst (- ang))
          lst (mapcar '(lambda ( a ) (apply 'mapcar (cons a lst))) '(min max))
          lst (list (car lst) (list (caadr lst) (cadar lst)) (cadr lst) (list (caar lst) (cadadr lst)))
    )
    (rotatepoints lst ang)
)
 
(defun rotatepoints ( lst ang )
    (   (lambda ( m ) (mapcar '(lambda ( p ) (mapcar '(lambda ( r ) (apply '+ (mapcar '* r p))) m)) lst))
        (list
            (list (cos ang) (sin (- ang)))
            (list (sin ang) (cos ang))
        )
    )
)
 
(princ)

 

0 Likes
Message 6 of 10

pbejse
Mentor
Mentor

@abilabib wrote:

For some conditions work well. But at any condition (red rectangle) the minpoint is wrong. 

How to solve this one


Based on the image you posted, the "bottom" for you is the right most as for the red rectangles the minpoint is bottom left.
If thats the case, you need to change the predicate function to this:

 

(setq ptmin (car (vl-sort PointList (function (lambda (e1 e2)
    (cond
    	((< (cadr e1) (cadr e2))	)
	((eq (cadr e1) (cadr e2))(> (car e1) (car e2)))	
	)))))
)

 

If Y value is the same, use the one on the right most. This will deal with the "How to solve this one?" issue.

 

I'm still not sure if that is what you require for your request on psot #1

(setq ptmin (car (vl-sort PointList (function (lambda (e1 e2)
    (cond
    	((< (cadr e1) (cadr e2))	)
	((eq (cadr e1) (cadr e2))(> (car e1) (car e2)))	;<-- for bottom left, use "<" 
	)))))
)

 

HTH

 

0 Likes
Message 7 of 10

abilabib
Advocate
Advocate

@Kent1Cooper

 

Thanks for your code. But the predicate function gives the same result. There's some missing PtMin in any position. 
The point result with code is in the red box and the target point is in the yellow box.

Missing Point.png

0 Likes
Message 8 of 10

pbejse
Mentor
Mentor

@abilabib wrote:

The point result with code is in the red box and the target point is in the yellow box.


It can also mean the reactangle point at the bottom doesnt have the same Y value and it defaults to the lowest. or even the osnap current value is getting in the way. It can be any other things.

 

If you dont mind, post that sample drawing and if possible also include a screnario with the rotated rectangles and its intended results.

 

(defun c:test ( / ss i ent PointList  ptmin    )
(if (setq ss (ssget '((0 . "LWPOLYLINE")(8 . "RoofMat"))))
  (repeat (setq i (sslength ss)
    (setq ent (ssname ss (setq i (1- i))))
	(setq PointList
	 	(mapcar 'cdr (vl-remove-if-not
			'(lambda (x) (= (car x) 10)) (entget ent))
		 ))
	(setq PointList  (vl-sort PointList (function (lambda (e1 e2)
	    (cond
	    	((< (cadr e1) (cadr e2))	)
		((equal (cadr e1) (cadr e2) 1e-8)(> (car e1) (car e2)))	
			))))
		)
	(setq  ptmin    (if ( < (caadr PointList)(caar PointList))
		  (car PointList) (cadr PointList ))
	       )
	(entmakex (list (cons 0 "POINT") (cons 10 ptmin)))
    	)
     )
  )
  (princ)
)
0 Likes
Message 9 of 10

Kent1Cooper
Consultant
Consultant

@abilabib wrote:

@Kent1Cooper

Thanks for your code. ....


[It wasn't my code.]  But in any case, for your orthogonally oriented rectangles in later images, if you don't know that they will always be drawn starting at the same corner and in the same direction, I would use their bounding boxes, rather than vertex-point lists.

 

But that won't work with the ones at non-orthogonal angles in Message 1.  Can you explain in more detail what you want in that arrangement?  The common corner marked PtMin is actually PtMax for one of them, and for the diagonal ones, which end of a lower-leftward edge is really its minimum point?, etc.

Kent Cooper, AIA
0 Likes
Message 10 of 10

abilabib
Advocate
Advocate

@Kent1Cooper,

 

Here's the algorithm program. 

1. Choose a close boundary and make it segmented with a hatch in any direction

2. Change segmented become polyline

3. change/get a segment to become rectangular and get the points. 

4. Determent the lowest point (PtMin) at the bottom right (correction from bottom left)

5. Insert Dynamic Block at the lowest point (PtMin)

6. Done

Program Seq.jpg

0 Likes