lisp for rectangle by sides

lisp for rectangle by sides

nacho_korn
Participant Participant
6,794 Views
21 Replies
Message 1 of 22

lisp for rectangle by sides

nacho_korn
Participant
Participant

Hi, I need a lisp with which I can make a rectangle by choosing the center point and 2 points of the centers of the sides

 

This would be to make 3D planes based on cross-shaped 2d views.

Maybe you can do it by selecting the middle of the 2 sides, since it will always be in cross and you could calculate the center automatically.

 

Thanks and excuse the translation.

 

 

0 Likes
6,795 Views
21 Replies
Replies (21)
Message 2 of 22

john.uhden
Mentor
Mentor

Seems to me that if starting with the midpoints of two adjacent sides that there are two solutions.

Might there be additional information such as would indicate whether a point is on a side vs. a top or bottom?

John F. Uhden

0 Likes
Message 3 of 22

rkmcswain
Mentor
Mentor
You could use the POLYGON command. I know it will only draw a square to begin with, but then it's easy to stretch one side out to make a rectangle without equal sides.
R.K. McSwain     | CADpanacea | on twitter
0 Likes
Message 4 of 22

john.uhden
Mentor
Mentor
That sounds like the equivalent of a 2 point circle.

John F. Uhden

0 Likes
Message 5 of 22

john.uhden
Mentor
Mentor
That sounds like the equivalent of a 2 point circle.

John F. Uhden

0 Likes
Message 6 of 22

marko_ribar
Advisor
Advisor

Here try this :

 

 

(defun c:2prec ( / mp1 mp2 p1 p3 )
  (setq mp1 (getpoint "\nPick or specify first middle edge point : "))
  (setq mp2 (getpoint "\nPick or specify second middle edge point : "))
  (cond
    ( (and (< (car mp1) (car mp2)) (< (cadr mp1) (cadr mp2)))
      (setq p1 (polar mp1 pi (- (car mp2) (car mp1))))
      (setq p3 (polar mp2 (* 0.5 pi) (- (cadr mp2) (cadr mp1))))
    )
    ( (and (< (car mp1) (car mp2)) (> (cadr mp1) (cadr mp2)))
      (setq p1 (polar mp1 pi (- (car mp2) (car mp1))))
      (setq p3 (polar mp2 (* -0.5 pi) (- (cadr mp1) (cadr mp2))))
    )
    ( (and (> (car mp1) (car mp2)) (< (cadr mp1) (cadr mp2)))
      (setq p1 (polar mp1 0.0 (- (car mp1) (car mp2))))
      (setq p3 (polar mp2 (* 0.5 pi) (- (cadr mp2) (cadr mp1))))
    )
    ( (and (> (car mp1) (car mp2)) (> (cadr mp1) (cadr mp2)))
      (setq p1 (polar mp1 0.0 (- (car mp1) (car mp2))))
      (setq p3 (polar mp2 (* -0.5 pi) (- (cadr mp1) (cadr mp2))))
    )
  )
  (command "_.RECTANGLE" "_non" p1 "_non" p3)
  (princ)
)

HTH, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 7 of 22

Kent1Cooper
Consultant
Consultant

@nacho_korn wrote:

Hi, I need a lisp with which I can make a rectangle by choosing the center point and 2 points of the centers of the sides

 

This would be to make 3D planes based on cross-shaped 2d views.

Maybe you can do it by selecting the middle of the 2 sides, since it will always be in cross and you could calculate the center automatically.

.... 


I'm not quite sure I understand what you're describing, but if you mean something like this:

 

RectCross.PNG

 

then can you just use the regular RECTangle command, with two APParent-intersection picks for the corners?

 

If I misunderstood, post a drawing or image.

Kent Cooper, AIA
Message 8 of 22

Kent1Cooper
Consultant
Consultant

@marko_ribar wrote:

Here try this :

 

 

....
(setq mp1 (getpoint "\nPick or specify first middle edge point : ")) (setq mp2 (getpoint "\nPick or specify second middle edge point : ")) ....

HTH, M.R.


If that's the kind of thing they're after, and regular RECTangle with APParent intersections won't do, I would suggest at least a change in the prompts, since the order matters:

 

....
  (setq mp1 (getpoint "\nPick middle of horizontal edge: "))
  (setq mp2 (getpoint "\nPick middle of vertical edge: "))
....

 

 

But another question for the OP:  Might the cross shapes ever be asymmetrical?  That is, with one arm not the same length as the opposite arm, so that the middle of some end-of-arm edges would not be the middle of the desired end result?

Kent Cooper, AIA
0 Likes
Message 9 of 22

marko_ribar
Advisor
Advisor

Hi Kent...

 

The order doesn't matter... Try the code and pick any 2 points...

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

Kent1Cooper
Consultant
Consultant

@marko_ribar wrote:

... 

The order doesn't matter... Try the code and pick any 2 points...


Yes it does -- I did:

 

RectCross2.PNG

Kent Cooper, AIA
0 Likes
Message 11 of 22

marko_ribar
Advisor
Advisor

But of course that order does matter, but it's up on user to choose that, so your remark ab my prompt specifications for picking points is wrong... Simply there is first middle point and second middle point... Computer will calculate from picked order correct rectangle...

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

john.uhden
Mentor
Mentor

As I had said, there are two possible solutions.

Using your program, if mp1 is to the right of mp2 then it draws a rectangle with mp2 being on the left side of the rectangle.

But if mp1 is to the left of mp2 then it draws a rectangle with mp2 being on the right side of the rectangle.

John F. Uhden

0 Likes
Message 13 of 22

Kent1Cooper
Consultant
Consultant

@marko_ribar wrote:

But of course that order does matter, but it's up on user to choose that, so your remark ab my prompt specifications for picking points is wrong... Simply there is first middle point and second middle point... Computer will calculate from picked order correct rectangle...


It clearly did not calculate the correct rectangle in the right part of the image in my previous Reply.  From the prompts as you have them worded, there is no way of knowing that in order to get the result I want, I must pick the middle of the horizontal edge first.  In that case I happened to pick the vertical-edge midpoint first, and it calculated the incorrect rectangle.  Appropriate wording in the prompts would eliminate that problem.

Kent Cooper, AIA
0 Likes
Message 14 of 22

marko_ribar
Advisor
Advisor

@Kent1Cooper wrote:

@marko_ribar wrote:

Here try this :

 

 

....
(setq mp1 (getpoint "\nPick or specify first middle edge point : ")) (setq mp2 (getpoint "\nPick or specify second middle edge point : ")) ....

HTH, M.R.


If that's the kind of thing they're after, and regular RECTangle with APParent intersections won't do, I would suggest at least a change in the prompts, since the order matters:

 

....
  (setq mp1 (getpoint "\nPick middle of horizontal edge: "))
  (setq mp2 (getpoint "\nPick middle of vertical edge: "))
....

 

 

But another question for the OP:  Might the cross shapes ever be asymmetrical?  That is, with one arm not the same length as the opposite arm, so that the middle of some end-of-arm edges would not be the middle of the desired end result?


I see now, you are right Kent, but I programmed it like it doesn't matter... But it surely does...

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

Kent1Cooper
Consultant
Consultant

@nacho_korn wrote:

.... 

This would be to make 3D planes based on cross-shaped 2d views.

.... it will always be in cross .... 


Again, assuming some things about what you really want to do, here's an even better way.  Load it up, type DBB for the command, and with one pick, anywhere on the cross [or any other] shape, it will draw the rectangle that encloses it, whether the arms are symmetrical or not, and without the need to hit midpoints or even the end-edges of the cross arms [you can pick it at a nowhere-in-particular location even near an inside corner, for example].

 

(defun C:DBB (/ minpt maxpt); = Draw Bounding Box
  (vla-getboundingbox
(vlax-ename->vla-object (car (entsel "\nSelect object to draw its Bounding Box: ")))
'minpt 'maxpt
); ...getbound... (command "_.rectangle" "_none" (vlax-safearray->list minpt) "_none" (vlax-safearray->list maxpt))
(princ) ); defun (vl-load-com) (prompt "\nType DBB to Draw the Bounding Box of a selected object.")

 

It could easily be made to verify that you actually picked something before trying to draw around it, if you think that's needed.

Kent Cooper, AIA
0 Likes
Message 16 of 22

nacho_korn
Participant
Participant

this is pretty close to what I need. But the rectangle need to focus on the cross

 

Thanks!

0 Likes
Message 17 of 22

marko_ribar
Advisor
Advisor

Hi Kent, a side question... I see that your avatar is fixed - still it's wrong when I click on you to see info... But then again, where are info data for members - do I have to step into everyone's page - they were always available before - you just had to point mouse over member name and data would be displayed - I mean posts, solutions, kudos and ideas...

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

nacho_korn
Participant
Participant

yes, that's what I need

 

 

0 Likes
Message 19 of 22

nacho_korn
Participant
Participant

now i understand

 

first I have to choose the point on the Y axis to solve that

0 Likes
Message 20 of 22

Kent1Cooper
Consultant
Consultant

So it appears I did misinterpret your need, since your cross looks like just a crossing of two Lines, not a cross shape in something like a Polyline.  I think I was interpreting your use of the word "middle" as meaning the midpoint of something that was already drawn, as well as of the resulting box edge.

 

In a cross of two Lines as in your latest image, the DrawBoundingBox routine would not do what you want.  But it gave me an idea:

 

;|
DrawBoundingBoxMult.lsp [command name: DBBM]
To Draw the Bounding Box around Multiple objects. Finds overall extent
of object(s) selected, and draws a Rectangle around that collective box.
Kent Cooper, 10 November 2016
|;
(defun C:DBBM (/ ss minpt maxpt eLL eUR LL UR); = Draw Bounding Box, Multiple
  (prompt "\nTo Draw the Bounding Box around Multiple objects,")
  (if (setq ss (ssget))
    (progn ; then
      (repeat (setq n (sslength ss))
        (vla-getboundingbox (vlax-ename->vla-object (ssname ss (setq n (1- n)))) 'minpt 'maxpt)
        (setq
          eLL (vlax-safearray->list minpt)
          eUR (vlax-safearray->list maxpt)
          LL (if LL (mapcar 'min eLL LL) eLL)
          UR (if UR (mapcar 'max eUR UR) eUR)
        ); setq
      ); repeat
      (command "_.rectangle" "_none" LL "_none" UR)
    ); progn
    (prompt "\nNothing selected."); else
  ); if
  (princ)
); defun
(vl-load-com)
(prompt "\nType DBBM to Draw the Bounding Box around Multiple objects.")

 

 

That will do what you are after with selection of the two Lines by any method, and at any location on them [or at no location, e.g. inside a window] -- no need to pick on their endpoints, nor to pick two points in any particular order, and it doesn't matter if the Lines do not cross at their midpoints, nor even whether they are perpendicular:

 

DBBM.PNG  DBBM2.PNG

Kent Cooper, AIA