AutoLISP Solutions: Aligning Objects12 Jan, 2006 By: Tony Hotchkiss Cadalyst
An updated solution for aligning objects in AutoCAD 2006.
This month's request came from Mr. Ronald Getz of Baltimore, Maryland. Getz was using the alignment routine ALIGNIT from 1996, and it no longer works in AutoCAD 2006, so he asked if I could update it.
The AutoLISP Solution is ALIGNIT.LSP and ALIGNIT.DCL, which allows the user to align any number of objects to a selected object datum in a single command. ALIGNIT is enhanced to include all of the AutoCAD drawing objects, including those that have appeared in the last ten years. In the last decade, lightweight polylines, ellipses (they used to be polylines), splines (formerly a type of polyline) and multiple line text all have appeared. AutoLISP became Visual LISP with object-oriented ActiveX objects, so the changes are significant.
Get the Code
Download the ALIGNIT.LSP and ALIGNIT.DCL files from Cadalyst's CAD Tips site and save them in AutoCAD's Support directory. Use the Appload facility by selecting Tools / Load Application, and then select the ALIGNIT.LSP program from where you stored it.
Some of you have emailed me recently because you could not find the code from the AutoLISP Solutions online. Many of the more recent routines are available in the AutoLISP Solutions link on the Get the Code page of our Web site. The older routines are still available as a general download for the months of the earlier years, although there is no specific mention of AutoLISP Solutions or its predecessor, the CAD Cookbook, in the listings. If you still can't find what you want, please contact me using the links at the end of this column.
How to Use the ALIGNIT Code
I have tested the code in AutoCAD 2006 using a variety of drawing objects (figure 1). These objects include lines, arcs, circles, polylines, ellipses, splines and block references, and the code should work for all of the drawing objects that AutoCAD has to offer.
Figure 1. A variety of drawing objects ready for alignment.
After you load the code, the system prompts you to enter ALI to start the program. To see this prompt, you may need to set your Command window size to three lines by dragging the Command window splitter bar appropriately. If you are using AutoCAD 2006, and you are not using the Command line area, you can still just enter ALI to start. After you enter ALI, you will see the Entity Alignment dialog box (figure 2).
Figure 2. The Entity Alignment dialog box.
The dialog box has choices for top, bottom, left and right. After you make your selection, you are prompted to select a single fixed entity, followed by a prompt to select the entities you want to align to the fixed entity. For example, if your selection was top, then all of the entities selected will have their y coordinates changed to match that of the topmost point of the fixed entity. Figure 3 shows the result of aligning some of the entities with the right point of a spline entity.
Figure 3. The result of selecting the right alignment choice.
The dialog box is displayed again so that you may make any other alignments. To terminate the alignment session, click the OK button in the dialog box.
Note that the multiline text objects are contained in a rectangular frame that may extend beyond the boundaries of the actual text, and the alignment of these objects uses the extremities of the rectangular frame. For example, if the bounding rectangle has some space to the right of the text, it may appear that the text is not aligned correctly on the right side.
The program was written in AutoCAD 2006, and it was tested only in AutoCAD 2006, although it should work in versions back to 2002. ALIGNIT.LSP starts as usual with my error handler and system variable functions. The function ALIGNIT is the dialog box driver function that provides the choices for top, bottom, left and right. This function is similar to the original 1996 code but with the addition of a call to the DRAW-IMAGE function which creates the image of a series of circles and lines in figure 2. This image replaces the use of a slide. The function AL_MOVE is called with a status code indicating which alignment option was selected.
AL_MOVE uses an object oriented approach to initialize selection sets before calling the AL_SELECT function that returns a list of the selected fixed entity and a set of objects to be aligned. I retained the use of the CAR-FUNC variable from the previous code to select the appropriate move direction top, bottom, left or right, as shown in the following code segment.
((= carnum 3) car)
((= carnum 4) cadr)
((= carnum 5) caddr)
((= carnum 6) cadddr)
) ; cond
) ; setq
The CAR-FUNC variable is subsequently used to substitute for any of the four functions: CAR, CADR, CADDR or CADDDR in the following.
(setq flevel (car-func (xyval obj)))
(repeat (vla-get-count ssobj)
(setq obj (vla-item ssobj (setq j (1+ j))))
(setq enxy (car-func (xyval obj)))
(setq dist (- flevel enxy)
base-pt '(0 0 0)
) ;_ end of setq
The two instances of CAR-FUNC in the above return the x or y coordinates of the fixed and the movable objects that correspond to their respective top, bottom, left or right orientations. The first line in the segment of code above obtains the fixed object coordinate, and the movable object coordinates are acquired in the repeat loop. The list of top, bottom, left and right coordinates is returned by the function XYVAL for each object in turn as indicated in the calls to CAR-FUNC above.
The AL_SELECT function returns a list containing the fixed entity name and a selection set of objects to align with the fixed entity. The fixed entity is selected with the traditional ENTSEL function, but the movable entities are selected using the object oriented SelectOnScreen method as in the following code segment.
(prompt "\nSelect the entities to be aligned ")
(setq ssobj (vla-add ssets "selection1"))
(while (= (vla-get-count ssobj) 0)
(if (= (vla-get-count ssobj) 0)
(prompt "\nNo entities were selected ")
) ;_ end of if
) ; while
Here, a while loop is used, and a test for a zero count of objects ensures that objects are selected.
The 1996 version of this routine included individual functions for each of the drawing object types so that the program could calculate the extreme positions of top, bottom, left and right for each of the entities. The more modern Visual LISP has a wonderful method GetBoundingBox that, as its name implies, produces the lower left and upper right corners of a bounding box for any of the AutoCAD drawing objects, so in one line of code, the single function XYVAL obtains these values. The function is shown here in just a few lines of code that replace more than three pages of code from the earlier version of ALIGNIT.
(defun xyval (obj / minpt maxpt topy bottmy leftx rightx)
(vla-GetBoundingBox obj 'minpt 'maxpt)
(setq pt1 (vlax-safearray->list minpt)
pt2 (vlax-safearray->list maxpt)
topy (cadr pt2)
bottmy (cadr pt1)
leftx (car pt1)
rightx (car pt2)
) ;_ end of setq
(list topy bottmy leftx rightx)
) ;_ end of xyval
Not only is this much shorter, but every drawing object is included with no exception. That is what I call progress!
As always, I look forward to receiving your requests for AutoLISP Solutions. Contact me using the links below.