[Search tip detail and code files using keywords, tip number, author name, etc ]
 
    For tip to function correctly, you must ensure that the downloaded file name matches the file name
    displayed in the Rename File To field. Please rename downloaded files when necessary.
Rotate AutoCAD's UCS
Tip# 3466 By Tony Hotchkiss On 01-May-2001
4
Rated By 1 users Downloaded : 549
Categories : CUI (Customize User Interface)
Software type : AutoCAD
Rename File To : UCS-ROT.lsp
Automatically rotate the UCS after you pick a single object.

Rowen Delaforce e-mailed a request to rotate the UCS (user coordinate system) by selecting an object even if that object is part of a block or xref. He wanted to include polyline segments and lines that may or may not be part of a block. The UCS rotation lets you place dimensions with the text facing from left to right. My solution is UCS-ROT.LSP, which automatically rotates the UCS after you pick a single object. The object must be a line, polyline, or lwpolyline. Any of these objects can be part of a block or xref, regardless of how deeply the object is nested in the block. I tested the program in AutoCAD 2000, but it should work in all versions back to Release 12 because I used only AutoLISP functions that appear in Release 12.

How to use UCS-ROT.LSP

Figure 1. UCS-ROT.LSP asks you to select an object.

Download the file and save it in your support directory for AutoCAD 2000. Load the program with AutoCAD's Tools|Application menu.

AutoCAD prompts you to enter UCR to start the program. Next, the prompt shown in figure 1 appears: Select a line or polyline.

The object snap is set automatically to Nearest for the selection. You should pick a line or polyline segment (even if it is part of a block); otherwise the routine displays: You must select a line or polyline, try again.


Figure 2. Then the routine rotates the UCS icon.

Once you select a suitable object, the UCS icon rotates as shown in figure 2.

If you select an arc segment of a polyline or lwpolyline, an alert box appears (figure 3), but the UCS still rotates to line up with the start and end points of the arc segment.

Programming notes
Rowen Delaforce had already discovered that it's relatively simple to do this job if you make two picks. Just pick the endpoints of any line or poly-line segment, then find the angle between those points. This works regardless of whether a block reference is involved.

Figure 3. The routine alerts you if you select an arc segment.

To solve the problem with only one user pick is considerably more involved, especially if you select lwpolylines. The old-style polylines are easy to handle if you use (nentselp) for the selection, because (nentselp) returns the entity type VERTEX.

The function (do-vertex) takes the selected vertex entity and uses (entnext) to find the next vertex. The required angle is simply the angle between these two vertices. If the selected vertex is the last one in the polyline, the next entity is the (sequend) entity. It's a simple matter to extract the name of the header polyline and use (entnext) on it to find the first vertex of the polyline. The code to do this is:
(setq en1 (nth 0 edata) ; search for next vertex

v1 (dxf 10 en1)
en2 (entnext en1)
en2typ (dxf 0 en2)
) ;_ setq
(if (= en2typ "SEQEND")

(progn

(setq pname (dxf -2 en2)

v2 (dxf 10 (entnext pname))

) ;_ setq

) ;_ progn

(setq v2 (dxf 10 en2))

) ;_ if
(setq bulg (dxf 42 en1))
(if (/= 0.0 bulg)

(alert "POLYLINE segment is an arc")

 

) ;_ if
(setq ang (angle v1 v2))

Note that this code also checks for arc segments and notifies you of any found.

If the selected entity is part of a block, the routine finds the combined angle of all of the nested blocks and adds it to the entity angle. The (do-block) function finds this angle as follows:

(defun do-block (edat / bnlist blen i insname ang)
(setq bnlist (nth 3 edat)

blen (length bnlist)

inspoint (dxf 10 (nth (1-blen) bnlist))

i 0

angtot 0.0

) ;_ setq
(repeat blen

(setq insname (nth i bnlist)

ang (dxf 50 insname)

angtot (+ angtot ang)

i (1+ i)

) ;_ setq

) ;_ repeat
angtot
) ;_ do-block


The data returned by (nentselp) contains a list of all nested blocks that include the selected entity. That list is used in the above repeat loop to produce the total angle.

An lwpolyline is complicated to deal with in this context because the routine can't identify any single vertex as an entity. You must obtain a list of vertices and test each pair to determine that the pick point lies on the segment. This is further compli cated if the entity is part of a block. The data returned by (nentselp) contains the pick point and the matrix that relates the position and orientation of the nested lwpolyline entity with respect to the WCS (world coordinate system).

Use of that matrix is somewhat lengthy, so I used a simple translation and rotation to relate the picked point of the nested entity to that of the block table definition of the entity. The base point of blocks in the block table is at zero, so the translation distance is simply the distance between the block reference insertion point and zero. The picked point is at some angle alpha with respect to the block reference insertion point. The routine subtracts the block rotation angle from the alpha angle to place the picked point on the correct segment of the lwpolyline as defined in the block table.

 

Average Rating:
4


User comments