Search code examples
lispautocadautolisp

Creating a rectangle from center point with existing height and width size


Im trying to create a 10 x 10 rectangle from its center point. I found existing code that creates a rectangle by its center point, but the user has to give size by picking the opposite corner. I want to replace the manual part with known dimensions of 10 x 10. The user picks a point and a 10 x 10 rectangle is created off of that center point.

Here is the existing code that I found:

(defun C:CENRECT ( / pt1 ptc vec)

    (setq pt1 (getpoint "\nSpecify the center point: "))
    (setq ptc (getpoint pt1 "\nSpecify the corner point: "))
    (setq vec (mapcar '- ptc pt1))

    (entmake
        (list
            '(000 . "LWPOLYLINE")
            '(100 . "AcDbEntity")
            '(100 . "AcDbPolyline")
            '(090 . 4)
            '(070 . 1)
            (cons 010 (trans (mapcar '+ pt1 (list (-(car vec))(+(cadr vec))(caddr vec))) 1 0))
            (cons 010 (trans (mapcar '+ pt1 (list (+(car vec))(cadr vec)(caddr vec))) 1 0))
            (cons 010 (trans (mapcar '+ pt1 (list (+(car vec))(-(cadr vec))(caddr vec))) 1 0))
            (cons 010 (trans (mapcar '+ pt1 (list (-(car vec))(-(cadr vec))(caddr vec))) 1 0))
            (cons 210 (trans '(0.0 0.0 1.0) 1 0 T))
        )
    )

    (redraw)
    (princ)
)

Here I am trying to add the known dimensions of 10 x 10 instead of having the user pick the size manually.

(defun C:test ( / pt1 ptc vec len wid)
    (setq pt1 (getpoint "\nSpecify the center point: "))
    **(setq len 10)
    (setq wid 10)**
    (setq ptc (getpoint pt1 **len wid**))
    (setq vec (mapcar '- ptc pt1))

    (entmake
        (list
            '(000 . "LWPOLYLINE")
            '(100 . "AcDbEntity")
            '(100 . "AcDbPolyline")
            '(090 . 4)
            '(070 . 1)
            (cons 010 (trans (mapcar '+ pt1 (list (-(car vec))(+(cadr vec))(caddr vec))) 1 0))
            (cons 010 (trans (mapcar '+ pt1 (list (+(car vec))(cadr vec)(caddr vec))) 1 0))
            (cons 010 (trans (mapcar '+ pt1 (list (+(car vec))(-(cadr vec))(caddr vec))) 1 0))
            (cons 010 (trans (mapcar '+ pt1 (list (-(car vec))(-(cadr vec))(caddr vec))) 1 0))
            (cons 210 (trans '(0.0 0.0 1.0) 1 0 T))
        )
    )

    (redraw)
    (princ)
)

I get an error of too many arguments. Need to figure how to give the opposite corner of 10 x 10 instead of the user doing.


Solution

  • Since you know the fixed dimensions of the resulting rectangle ahead of time, the code can be reduced to the following:

    (defun c:cenrect ( / c z )
        (setq z (trans '(0 0 1) 1 0 t))
        (if (setq c (getpoint "\nSpecify center: "))
            (entmake
                (list
                   '(000 . "LWPOLYLINE")
                   '(100 . "AcDbEntity")
                   '(100 . "AcDbPolyline")
                   '(090 . 4)
                   '(070 . 1)
                    (cons 010 (trans (mapcar '+ c '(-5 -5)) 1 z))
                    (cons 010 (trans (mapcar '+ c '( 5 -5)) 1 z))
                    (cons 010 (trans (mapcar '+ c '( 5  5)) 1 z))
                    (cons 010 (trans (mapcar '+ c '(-5  5)) 1 z))
                    (cons 210 z)
                )
            )
        )
        (princ)
    )
    

    Here, the polyline vertices are calculated relative to the supplied center point (with respect to the active UCS), and such vertices are then transformed relative to the Object Coordinate System (OCS).