Autocad Draw a Perpendicular Line

This Lisp was found at http://paulbourke.net/geometry/pointlineplane/int2.lsp and has been a great help in 3D and sometimes being off by a little bit can be very frustrating. You can always us the distance command and then look for the specific X distance or Y distance, but what if the objects are not aligned with your UCS?… That's where this tool really helps. I've tried using the Perpendicular OSNAP from one object and then tried to snap to the second object with perpendicular but it wont work (for me) and like I said, what if the lines are not in a perpendicular plane

Shown below are 3 lines that are not parallel, yet I want to find the apparent intersection with a line that represents the distance between the 2 lines.

3D View of Lines

3D View of Lines

Here's how to use INT2

INT2 [enter]

Pick 2 points to define the first line

Pick 2 points to define the second line

Lines Between Angled lines

As long as there is a possible intersection, a line will be created.

Thanks to Paul Bourke's website with many mathematical approaches to solving geometrical scenarios: http://paulbourke.net/

~enjoy

                                    ;;;   int2.lsp                                      ;;;   http://paulbourke.net/geometry/pointlineplane/int2.lsp                                      ;;;   Finds the intersection of two non-parallel lines in 2D or 3D, OR the                                      ;;;   closest points between the two non-intersecting lines in 3D.                                      ;;;                                      ;;;   Based on Algorithm by Paul Bourke / Autolisp version by Andrew Bennett.                                      ;;;                                      ;;;   See Paul Bourke's discussion at:                                      ;;;   http://local.wasp.uawa.edu.au/~pbourke/geometry/lineline3d/                                      ;;;   Uses algorithm derived from the fact that the closest point between two                                      ;;;   lines is a new line perpendicular to both.                                      ;;;                                      ;;;   On the XY plane of Autocad's current UCS, two non-parallel vectors will                                      ;;;   always intersect, therefore the various object snaps (osnap) or                                      ;;;   Autolisp's (inters) function are all you need.                                      ;;;                                      ;;;   Outside the UCS plane in the 3D environment however, these intersection                                      ;;;   functions are over precise and can easily fail (see Paul Bourke's                                      ;;;   discussion) leaving you with no further information.                                      ;;;                                      ;;;   Int2.lsp addresses this problem by working as follows:                                      ;;;                                      ;;;   As with Autocad/Autolisp, the program will find the intersection point                                      ;;;   between two (non-parallel) lines in 2D, or if it exists, in 3D.                                      ;;;                                      ;;;   In 3D, where there may not be a precise intersection, it finds the                                      ;;;   closest points between the two lines and draws a new line between them.                                      ;;;                                      ;;;   In both cases, the resultant point(s) are set by invoking the                                      ;;;   Autocad 'Line' command which draws a rubber-band line from the last                                      ;;;   point set to the current cursor position. This feature allows the                                      ;;;   intersection/closest point(s) to be clearly visible on screen even if the                                      ;;;   point(s) have been set outside the current drawing window.                                      ;;;                                      ;;;   If the two lines are parallel, then they are also equidistant, so there                                      ;;;   is no intersection, and no specific closest point, and so the program                                      ;;;   will end by giving an appropriate informative message.                                      (            defun            c:int2            (            /                          ; local variables used in defun                        acad_err                          ; temporary error handler                        oldsnap                          ; saved snap settings                        nearzero                          ; a very small number                        currentP                          ; list containing 3 reals                        checkP                retn_val                          ; value returned after defun call                        getPt_msg                          ; message string                        P1 P2 P3 P4                          ; xyz coordinate lists (reals)                        X1 X2 X3 X4 X5 X6                          ; x value (real)                        Y1 Y2 Y3 Y4 Y5 Y6                          ; y value (real)                        Z1 Z2 Z3 Z4 Z5 Z6                          ; z value (real)                        RelX21 RelY21 RelZ21                          ; relative x, y, and z values of P2-P1                        RelX43 RelY43 RelZ43              ;                                    P4-P3                        RelX13 RelY13 RelZ13              ;                                    P1-P3                        dot1343 dot4321                          ; dot products of Relative xyz values                        dot1321 dot4343 dot2121                          ; dot products of Relative xyz values                        denom numer                          ; denominator & numerator of equation                        closedist                          ; closest distance between two lines                        u21 u43                          ; scale factors line21 or line43 length                        )            (            init_err            )                          ; set up temporary error handler and save previous system settings                        (            setq            transp_cmd            (            getvar            "cmdactive"            ))                          ; Test value                        (            if            (            >            transp_cmd            0            )                          ; if Autocad commands running                        (            princ            "Program cannot not be run as a transparent command"            )                          ;Then END                        (            progn                          ; Else continue with the program                        (            setvar            "cmdecho"            0            )                          ; Turn off command prompt                        (            setq            nearzero            0.00001            )                          ; a very small number                        (            setq            P1            (            getpt            nil            "\nLINE From Point: "            )                          ;call getpt function                        P2            (            getpt            P1            "\nTo Point: "            )            P3            (            getpt            nil            "\nLINE From Point: "            )            P4            (            getpt            P3            "\nTo Point: "            )            )                          ;setq                        (            setq            oldsnap            (            getvar            "osmode"            ))                          ; check & save current osnap settings                        (            setvar            "osmode"            0            )                          ; before clearing all osnaps                        (            setq                          ;; Strip xyz coordinates from lists P1, P2, P3 and P4, assign to variables                        X1            (            car            P1)            X2            (            car            P2)            X3            (            car            P3)            X4            (            car            P4)                          ; x value                        Y1            (            cadr            P1)            Y2            (            cadr            P2)            Y3            (            cadr            P3)            Y4            (            cadr            P4)                          ; y value                        Z1            (            caddr            P1)            Z2            (            caddr            P2)            Z3            (            caddr            P3)            Z4            (            caddr            P4)                          ; z value                                      ;; Calculate Relative coordinates of XYZ21, XYZ13 and XYZ43                        RelX21            (            -            X2 X1)            RelX43            (            -            X4 X3)            RelX13            (            -            X1 X3)                          ; rx value                        RelY21            (            -            Y2 Y1)            RelY43            (            -            Y4 Y3)            RelY13            (            -            Y1 Y3)                          ; ry value                        RelZ21            (            -            Z2 Z1)            RelZ43            (            -            Z4 Z3)            RelZ13            (            -            Z1 Z3)                          ; rz value                                      ;; Calculate the various dot products and denominator                        dot1343            (            +            (            *            RelX13 RelX43)            (            *            RelY13 RelY43)            (            *            RelZ13 RelZ43))            dot4321            (            +            (            *            RelX43 RelX21)            (            *            RelY43 RelY21)            (            *            RelZ43 RelZ21))            dot1321            (            +            (            *            RelX13 RelX21)            (            *            RelY13 RelY21)            (            *            RelZ13 RelZ21))            dot4343            (            +            (            *            RelX43 RelX43)            (            *            RelY43 RelY43)            (            *            RelZ43 RelZ43))            dot2121            (            +            (            *            RelX21 RelX21)            (            *            RelY21 RelY21)            (            *            RelZ21 RelZ21))            denom            (            -            (            *            dot2121 dot4343)            (            *            dot4321 dot4321))            )                          ;setq                        (            if            (            <            (            abs            denom)            nearzero)                          ; are lines parallel?                                      ;; Display message, exit loop, program ends                        (            princ            "\nLines Parallel and Equidistant, No intersection point exists"            )            (            progn            (            setq            numer            (            -            (            *            dot1343 dot4321)            (            *            dot1321 dot4343))                          ;; u21 scale factor up line 1 to closest point to line21                                      ;; if 0 > u21 < 1 closest point is within line section                                      ;; if u21 < 0 closest point is beyond P1 end                                      ;; or u21 > 1 closest point is beyond P2 end                        u21            (            /            numer denom)                          ;; u43 is the scale factor up Line43 and works in the same way as u21                        u43            (            /            (            +            dot1343            (            *            dot4321 u21))            dot4343)            X5            (            +            X1            (            *            u21 RelX21))            Y5            (            +            Y1            (            *            u21 RelY21))            Z5            (            +            Z1            (            *            u21 RelZ21))            X6            (            +            X3            (            *            u43 RelX43))            Y6            (            +            Y3            (            *            u43 RelY43))            Z6            (            +            Z3            (            *            u43 RelZ43))                          ; Calculate the distance between the points                        closedist            (            distance            (            list            X5 Y5 Z5)            (            list            X6 Y6 Z6))            )                          ;setq                        (            if            (            <            closedist nearzero)                          ; are points nearly touching?                        (            progn                          ;; intersection point found                        (            princ            "\nIntersection, Point set"            )                          ; print message                        (            princ            )                          ; suppress return nil                        (            command            "line"            (            list            X5 Y5 Z5))                          ; set point                        )                          ;progn                        (            progn                          ;; No intersection point found,                                      ;; new line will be drawn at closest point to both lines                                      ; Print message and length of line section                        (            princ            (            strcat            "\nNo intersection, Line drawn at closest point, Length: "            (            rtos            closedist)))            (            princ            )                          ; suppress return nil                        (            command            "line"            (            list            X5 Y5 Z5)            (            list            X6 Y6 Z6))                          ; set a line section                        )                          ;progn                        )                          ;if                        )                          ;progn                        )                          ;if                        (            reset_err            )                          ; Restore standard handler and previous system settings                        )                          ;progn                        )                          ;if (Transparent command message)                        (            princ            )                          ; suppress return value                        )                          ;defun                                      ;; Uses (getpoint) function to get valid lists of coordinates                                      ;; Uses (initget) function to prevent ENTER being pressed accidently                                      ;;                                      ;; Syntax (getpt checkP/nil getpt_msg)                                      ;; Parameter list (checkP getpt_msg currentP retn_val nearzero)                                      ;;                                      ;;   (checkP)    Coincidence check with previous point                                                    ;;   (nil)       No coincidence check with previous point                                      ;;   (getpt_msg) Message to display at the Command prompt                                      ;;                                                    ;; Returns retn_val to calling function as list of reals                                      ;;                                      ;;   example:                                      ;;                                      ;;   (setq P1 (getpt nil "\nPoint: ") ; returns P1, no coincidence check                                      ;;         P2 (getpt P1 "\nLINE From Point: ") ; returns P2, check with P1                                      ;;         P3 (getpt P2 "\nTo point: ")) ; returns P3, check with P2                        (            defun            getpt            (checkP getpt_msg)            (            setq            currentP nil)                          ; initialise currentP                        (            while            (            null            currentP)                          ; start loop                        (            initget            1            )                          ; disallows null input                        (            setq            currentP            (            getpoint            getpt_msg))                          ; Type/set a valid coordinate                        (            if            (            null            checkP)                          ; Do/Don't compare with previous point                        (            setq            retn_val currentP)                          ; return currentP to calling function                        (            progn            (            if            (            equal            checkP currentP nearzero)                          ; compare with check point                        (            progn            (            princ            "\nPoints touch, Do again"            )                          ; both points set in same place                        (            setq            currentP nil)                          ; nil currentP to repeat loop                        )                          ; progn                        (            setq            retn_val currentP)                          ; return currentP to calling function                        )                          ;if                              ; currentP nil, repeat loop                        )                          ;progn                        )                          ;if                        )                          ; while                            ; currentP boundp, get out of loop                        )                          ;defun                                      ;;;************************** error trap functions ****************************                                      ;; Function sets up temporary error handler and saves previous system settings                        (            defun            init_err            ()            (setq acad_err *error*)                          ; save standard error handler                        (            setq            *error* temp_err)                          ; redirect error call to temporary error handler                        (            setq            oldsnap            (            getvar            "osmode"            ))                          ; save osnaps, keep them on                        (            setvar            "cmdecho"            0            )                          ; turn off command echoing                        (            princ            )            )                          ;defun                                      ;; Function invokes temporary error handler                                      ;; Restores standard handler and previous system settings                        (            defun            temp_err            (msg)            (            setq            transp_cmd            (            getvar            "cmdactive"            ))                          ; Test value                        (            if            (            >            transp_cmd            0            )                          ; if Autocad commands running                        (            command            )                          ; then cancel them                        )                          ;if                        (            if            (            or            (            /=            msg            "Function cancelled"            )                          ; if user cancelled                        (            =            msg            "quit / exit abort"            )                          ; or program aborted                        )                          ;or                        (            princ            )                          ; then exit quietly                        (            princ            (            strcat            "\nError: "            msg))                          ; else report error message                        )                          ;if                        (            setq            *error* acad_err)                          ; restore standard error handler                        (            setvar            "osmode"            oldsnap)                          ; restore object snaps                        (            setvar            "cmdecho"            1            )                          ; restore command echoing                        (            princ            )            )                          ;defun                                      ;; Function restores standard handler and previous settings                        (            defun            reset_err            ()            (setq *error* acad_err)                          ; restore standard error handler                        (            setvar            "osmode"            oldsnap)                          ; restore previous osnap settings                        (            setvar            "cmdecho"            1            )                          ; restore command echoing                        (            princ            )            )                          ;defun                                      ;***********************************************************************                        (            princ            "int2.lsp loaded. Type INT2 to run program"            )            (            princ            )                  

About AutoCAD Tips

This blog serves as a knowledge base for myself (and anyone else) so that I can reference tips & tricks that I have learned and also refer others to it as well. I hope that this blog helps you learn at least one tip to make your drafting/design experience better.

johnstonwonviody.blogspot.com

Source: https://autocadtips1.com/2014/12/18/autolisp-make-perpendicular-line-between-two-3d-angles/

0 Response to "Autocad Draw a Perpendicular Line"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel