Author Topic: MakeSlot.lsp My first routine posting  (Read 4611 times)

0 Members and 1 Guest are viewing this topic.

trogg

  • Bull Frog
  • Posts: 255
MakeSlot.lsp My first routine posting
« on: December 27, 2010, 01:17:24 PM »
I've been lurking for a while and learning a lot.
This is my first routine posting (so go easy)
This was a project from this semester's Lisp class that I think may actually be useful for someone.
I updated it from when I turned it in. What I added was turning off the command echo and more importantly was saving the user's Osnaps then running the routine and then resetting the user's osnaps.
Type MS to start
It is a slot routine that lets the user pick two circle of any size and draws tangent lines connecting the circles and then trims the inner arcs of the circles to make a "slot"
Code: [Select]
;; Filename: MakeSlot.lsp
;; Programmer: Greg Battin
;; Date: 9/20/10
;;
;;
;; Purpose: Create a slot formation from two existing circles of any size and
;; trims away the inner arcs.
;;
;; Prompts: Pick a point anywhere on the first circle:
;;  Pick a point anywhere on the second circle:

(defun C:MS ()
  (setvar "CMDECHO" 0) ; turn off command echo
  (setq oldOs (getvar "osmode")) ; save user's osnaps
  (setvar "OSMODE" 512) ; set osnap to NEA
  (setq NP1 (getpoint "\nPick any point on first circle: ")
NP2 (getpoint "\nPick any point on second circle: ")
  )
  (setvar "OSMODE" 256) ; Set osnap to TAN
  (setq CP1   (osnap NP1 "CEN") ; Find center of circle 1
CP2   (osnap NP2 "CEN") ; Find center of circle 2
ANGL  (angle CP1 CP2) ; Angle lengthwise
ANGW  (+ (* 0.5 pi) ANGL) ; Angle lengthwise +90 degrees
ANGW2 (+ (* 1.5 pi) ANGL) ; Angle lengthwise +270 degrees
CRAD  (distance CP1 NP1) ; Radius circle 1
CRAD2 (distance CP2 NP2) ; Radius circle 2
LP1   (polar CP1 ANGW CRAD) ; First line start point 
LP2   (polar cP2 ANGw CRAD2) ; First line end point
LP3   (polar CP1 ANGW2 CRAD) ; Second line start point
LP4   (polar CP2 ANGW2 CRAD2) ; Second line end point
  )
  (command "line" LP1 LP2 "" "select" "last" ""
; Create Selection-set access to line
   "line" LP3 LP4 "")

  (setq TP1 (polar CP1 ANGL CRAD) ; Trim Point 1
TP2 (polar CP2 ANGL (- CRAD2)) ; Trim Point 2
  )
  (command "trim" "p" "last" "" TP1 TP2 "")
; Select lines for cut edges
  (prompt "\nDone.\n") ; Message when done
  (setvar "osmode" oldOs) ; restores the user's osnaps
  (setvar "CMDECHO" 1) ; reset the cammond echo to ON
  (princ) ; Cean exit
)
; ---< End of MakeSlot.lsp >---

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: MakeSlot.lsp My first routine posting
« Reply #1 on: December 27, 2010, 03:40:09 PM »
Hi Trogg,

Good first program  :-)

I hope you don't mind, I've added some (hopefully constructive) criticism to the code with the aim to help:

Code: [Select]
;; Filename: MakeSlot.lsp
;; Programmer: Greg Battin
;; Date: 9/20/10
;;
;;
;; Purpose: Create a slot formation from two existing circles of any size and
;; trims away the inner arcs.
;;
;; Prompts: Pick a point anywhere on the first circle:
;;   Pick a point anywhere on the second circle:

(defun C:MS ()
[color=green]
  ;; Be sure to localise your variables!
  ;; Might not matter for this program, but it'll certainly
  ;; bite you in the ass later down the line...

  ;; See: www.lee-mac.com/localising.html for info[/color]
 
  (setvar "CMDECHO" 0) ; turn off command echo

[color=green]  ;; I know it only takes two values, but
  ;; it is still good practice to save the original
  ;; value first, rather than set it back to 1.[/color]

  (setq oldOs (getvar "osmode")) ; save user's osnaps
  (setvar "OSMODE" 512) ; set osnap to NEA

[color=green]  ;; Since we are messing with OSMODE, it'd be a
  ;; good idea to include an error handler, else all
  ;; the Snaps are messed up should the user hit Esc
  ;; during the routine.[/color]

[color=green]  ;; See: www.lee-mac.com/errorhandling.html for how to
  ;; do this.[/color]
  
  (setq NP1 (getpoint "\nPick any point on first circle: ")
NP2 (getpoint "\nPick any point on second circle: ")
  )

[color=green]  ;; It'd be good to check that the user has in fact picked
  ;; the two points you requested - an IF statement coupled
  ;; with AND would be good for this.[/color]
  
  (setvar "OSMODE" 256) ; Set osnap to TAN
  
  (setq CP1   (osnap NP1 "CEN") ; Find center of circle 1
CP2   (osnap NP2 "CEN") ; Find center of circle 2

[color=green]  ;; I can see your methodology in using the osnap
  ;; function, but this can be troublesome. Better to get the
  ;; user to select the circles using entsel and get their
  ;; centers using the DXF data.[/color]
    
ANGL  (angle CP1 CP2) ; Angle lengthwise
ANGW  (+ (* 0.5 pi) ANGL) ; Angle lengthwise +90 degrees
ANGW2 (+ (* 1.5 pi) ANGL) ; Angle lengthwise +270 degrees
CRAD  (distance CP1 NP1) ; Radius circle 1
CRAD2 (distance CP2 NP2) ; Radius circle 2
LP1   (polar CP1 ANGW CRAD) ; First line start point  
LP2   (polar cP2 ANGw CRAD2) ; First line end point
LP3   (polar CP1 ANGW2 CRAD) ; Second line start point
LP4   (polar CP2 ANGW2 CRAD2) ; Second line end point
  )
  (command "line" LP1 LP2 "" "select" "last" ""
; Create Selection-set access to line
  "line" LP3 LP4 "")

  (setq TP1 (polar CP1 ANGL CRAD) ; Trim Point 1
TP2 (polar CP2 ANGL (- CRAD2)) ; Trim Point 2
  )
  (command "trim" "p" "last" "" TP1 TP2 "")

[color=green]  ;; Trim is probably the easiest solution - but you
  ;; might have trouble with it sometimes with the wrong
  ;; parts being trimmed. A more robust solution would be to
  ;; create arcs where needed and erase the circles in the
  ;; code.[/color]
  
; Select lines for cut edges
  (prompt "\nDone.\n") ; Message when done
  (setvar "osmode" oldOs) ; restores the user's osnaps
  (setvar "CMDECHO" 1) ; reset the cammond echo to ON

[color=green]  ;; As above, better to set the CMDECHO back to what it was -
  ;; although this is *usually* 1, people don't like Sys Vars
  ;; being changed by code.[/color]
  
  (princ) ; Cean exit
)
; ---< End of MakeSlot.lsp >---

I've also dabbled in Circle tangents in the past  :-)

http://www.theswamp.org/index.php?topic=31371.msg369396#msg369396

http://www.theswamp.org/index.php?topic=31371.msg388410#msg388410

http://www.theswamp.org/index.php?topic=31371.msg389384#msg389384



Lee

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: MakeSlot.lsp My first routine posting
« Reply #2 on: December 27, 2010, 04:09:25 PM »
Trogg;  nice format and code writing.  Easy to understand and follow.

Lee;  As usual nice critique with the why.  Which reminds me,  I need to go back and reread your error handler article.  My one weak spot in my code.
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: MakeSlot.lsp My first routine posting
« Reply #3 on: December 27, 2010, 04:34:03 PM »
Lee;  As usual nice critique with the why.  Which reminds me,  I need to go back and reread your error handler article.  My one weak spot in my code.

Thanks Krushert - any questions about the article or mistakes found, just shout  :-)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: MakeSlot.lsp My first routine posting
« Reply #4 on: December 27, 2010, 05:18:47 PM »
Had some time Trogg, here is how I might approach it.

I've annotated the code as much as possible, and slightly simplified my approach (so intrinsic properties [layer/linetype etc] of the original circles are overlooked for sake of brevity).

Hopefully my explanations are somewhat clear - if there is anything you don't understand, just ask.

Lee

Code: [Select]
(defun [color=red]c:ms[/color] ( / *error* _Arc _Line _Dxf e1 e2 c1 c2 r1 r2 di dr an tan ang )

[color=green]  ;; ------------------------------------------------------- ;;
  ;; Example Courtesy of Lee Mac 2010 of www.lee-mac.com     ;;
  ;;                                                         ;;
  ;; Simple enough code, but oh well: © Lee Mac 2010         ;;
  ;; ------------------------------------------------------- ;;

  ;; Define function, localise variables and
  ;; local subfunction.[/color]

  (defun [color=red]*error*[/color] ( msg )

[color=green]    ;; Error Function not really needed, as
    ;; nothing really needs resetting should the
    ;; user hit Esc. But we'll add it to demonstrate
    ;; how to use an error handler, and to suppress the
    ;; error message when the user hits Esc.[/color]
   
    (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\n** Error: " msg " **")))
    (princ)
  )

  (defun [color=red]_Arc[/color] ( centre radius start end )

[color=green]    ;; Subfunction to create an Arc
    ;; (I use the underscore for no other purpose
    ;;  than to indicate that its a subfunction)

    ;; Arguments:
    ;; centre - centre of the Arc
    ;; radius - Arc Radius
    ;; start  - Arc Start Angle
    ;; end    - Arc End Angle[/color]

    (entmakex
     
[color=green]      ;; Using entmake*x* to return the entity name
      ;; instead of the DXF data list.[/color]
     
      (list
        (cons 0 "ARC")
        (cons 10 centre)
        (cons 40 radius)
        (cons 50 start)
        (cons 51 end)
      )
    )

[color=green]    ;; entmakex function statement is the last
    ;; expression in the function definition so
    ;; the return of entmakex (the entity name)
    ;; will be returned by the subfunction.[/color]
  )

  (defun [color=red]_Line[/color] ( start end )

[color=green]    ;; Subfunction to create a Line

    ;; Arguments:
    ;; start  - Start Point of the Line
    ;; end    - End Point of the Line[/color]

    (entmakex
      (list
        (cons 0 "LINE")
        (cons 10 start)
        (cons 11 end)
      )
    )
  )

  (defun [color=red]_dxf[/color] ( code entity ) (cdr (assoc code (entget entity))))

[color=green]  ;; ^^ Handy little subfunction for returning DXF data[/color]

[color=green]
  ;; Subs defined, start Main Program...[/color]

  (if
[color=green]
    ;; IF the following expression is *non-nil*
    ;; (doesn't have to be explicitely TRUE)[/color]
   
    (and

[color=green]      ;; All the following expression need to be non-nil
      ;; for AND to return True[/color]

      (setq e1 (car (entsel "\nSelect First Circle: ")))

      (eq "CIRCLE" (_dxf 0 e1)) [color=green];; Check that the user has indeed picked a Circle[/color]

      (setq e2 (car (entsel "\nSelect Second Circle: ")))

      (eq "CIRCLE" (_dxf 0 e2)) [color=green];; Well yes, they could be that stupid..[/color]

    ) [color=green];; End AND[/color]

    (progn

[color=green]      ;; Use the progn function to effectively 'wrap'
      ;; the following expressions so that the SINGLE
      ;; progn expression may be fed to the IF function.

      ;; The IF function will only take three arguments:
      ;; Test expression, then expression, else expression.
      ;; Hence if we want to evaluate more than one expression
      ;; for each case, we can use the progn function which will
      ;; merely evaluate all expressions fed to it, but can
      ;; be handed to the IF function as a single expression in itself.[/color]


      (setq c1 (_dxf 10 e1) c2 (_dxf 10 e2)) [color=green];; Centers of both Circles.[/color]

      (setq r1 (_dxf 40 e1) r2 (_dxf 40 e2)) [color=green];; Radii of both Circles.[/color]

      (setq di (distance c1 c2) [color=green];; Distance between centers[/color]
       
            dr (- r1 r2)      [color=green]  ;; Difference in the Radii[/color]

            an (angle c1 c2)   [color=green] ;; Angle of the centers[/color]
      )

      (if (< (abs dr) di)

[color=green]        ;; If the absolute value of the difference in the
        ;; radii is less than the distance between the circle
        ;; centers (else one circle is inside the other)[/color]

        (progn

[color=green]          ;; ^^ There it is again....[/color]

          (setq tan (sqrt (- (* di di) (* dr dr))))

[color=green]          ;; A touch of Pythagoras to get the tangent length[/color]

          (setq ang (atan tan dr))
[color=green]
          ;; Trig to get the angle of the normal, measured from
          ;; the line connecting the two centers.[/color]

          (_Line
            (polar c1 (+ an ang) r1)
            (polar c2 (+ an ang) r2)
          )

[color=green]          ;; Draw the first tangent line...[/color]

          (_Line
            (polar c1 (- an ang) r1)
            (polar c2 (- an ang) r2)
          )
[color=green]
          ;; ...And the second.


          ;; Now for the Arcs![/color]

          (_Arc c1 r1 (+ an ang) (- an ang))

          (_Arc c2 r2 (- an ang) (+ an ang))

[color=green]          ;; Finally, delete the original Circles:[/color]

          (mapcar 'entdel (list e1 e2))

[color=green]          ;; OK, so mapcar wasn't really needed, I could've
          ;; used:
          ;;
          ;; (entdel e1)
          ;; (entdel e2)
          ;;
          ;; But it gives an opportunity for a novice to easily see how
          ;; mapcar works: applying a supplied function to every item in a supplied
          ;; list.[/color]

        ) [color=green];; End PROGN[/color]

        (princ "\n** Unable to Construct Tangents **")
[color=green]
        ;; Warn the user they have attempted the impossible...[/color]

      ) [color=green];; End IF[/color]

    ) [color=green];; End PROGN[/color]

    (princ "\n*Cancel*")

[color=green]    ;; User hasn't selected two Circles[/color]

  ) [color=green];; End IF[/color]

  (princ) [color=green];; Shhh![/color]
 
) [color=green];; End DEFUN[/color]
« Last Edit: December 27, 2010, 07:00:04 PM by Lee Mac »

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: MakeSlot.lsp My first routine posting
« Reply #5 on: December 27, 2010, 07:27:06 PM »
Some food for thought, using an LWPolyline with bulge  :-)

Code: [Select]
(defun c:ms ( / _dxf e1 e2 c1 c2 r1 r2 di dr an tan ang ) (vl-load-com)
  ;; © Lee Mac 2010

  (defun _dxf ( code entity ) (cdr (assoc code (entget entity))))

  (if
    (and
      (vl-every
        (function
          (lambda ( sym str )
            (and (set sym (car (entsel str)))
              (eq "CIRCLE" (cdr (assoc 0 (entget (eval sym)))))
            )
          )
        )
        '(e1 e2) '("\nSelect First Circle: " "\nSelect Second Circle: ")
      )
      (progn
        (setq c1 (_dxf 10 e1) c2 (_dxf 10 e2) r1 (_dxf 40 e1) r2 (_dxf 40 e2)
         
              di (distance c1 c2) dr (- r1 r2) an (angle c1 c2)
        )
        (< (abs dr) di)
      )
    )
    (progn (setq tan (sqrt (- (* di di) (* dr dr))) ang (atan di dr))
      (
        (lambda ( b1 b2 )
          (entmakex
            (list
              (cons 0 "LWPOLYLINE")
              (cons 100 "AcDbEntity")
              (cons 100 "AcDbPolyline")
              (cons 90 4)
              (cons 70 1)
              (cons 10 (polar c1 (+ an ang) r1))
              (cons 42 b1)
              (cons 10 (polar c1 (- an ang) r1))
              (cons 10 (polar c2 (- an ang) r2))
              (cons 42 b2)
              (cons 10 (polar c2 (+ an ang) r2))
            )
          )
        )
        (/ (sin (/ (- pi ang) 2.0)) (cos (/ (- pi ang) 2.0)))
        (/ (sin (/       ang  2.0)) (cos (/       ang  2.0)))
      )
      (mapcar 'entdel (list e1 e2))
    )
  )

  (princ)
)

trogg

  • Bull Frog
  • Posts: 255
Re: MakeSlot.lsp My first routine posting
« Reply #6 on: December 27, 2010, 08:14:53 PM »
Thank you Krushert for the compliment and Thank you Lee for the helpful critique. I'm gonna study what you said and try to unlearn what I was taught by my teacher (If you don't remember, I had a bad Lisp-class teacher).
We never went over error handling. That will definitely be helpful and also how to not mess with people's system variables.
Question: why is it important to call out the localizes variables?

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: MakeSlot.lsp My first routine posting
« Reply #7 on: December 28, 2010, 12:22:12 AM »
Question: why is it important to call out the localizes variables?

Do you mean :
Question: why is it important to declare local variables?

So that they (and their values) will not polute the environment and possibly overide existing values.
The concept of  'scope' also comes into play.
There can be some subtle bugs introduced with the use of global variables.
Long story short : you will have a happier life if you declare your variables local.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

nivuahc

  • Guest
Re: MakeSlot.lsp My first routine posting
« Reply #8 on: December 28, 2010, 09:02:16 AM »
On error handling, I highly recommend this thread.

Nice work. :)

nivuahc

  • Guest
Re: MakeSlot.lsp My first routine posting
« Reply #9 on: December 28, 2010, 09:10:25 AM »
One final piece of advice, trogg;

If you ever get advice from Lee, Kerry, CAB, or MP (as well as several others, but especially those guys) write it down (or copy/pasta it into a file somewhere for future reference). Read through their advice several times, if necessary, and try to understand what it is that they're telling you. If you don't understand their advice, ask questions until you do.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: MakeSlot.lsp My first routine posting
« Reply #10 on: December 28, 2010, 12:57:48 PM »
Question: why is it important to call out the localizes variables?

Along with Kerry's explanation, this should also help to cement it in your mind  :-)

If you ever get advice from Lee, Kerry, CAB, or MP (as well as several others, but especially those guys)

Cheers dude, appreciate it  :-)

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: MakeSlot.lsp My first routine posting
« Reply #11 on: December 28, 2010, 01:05:46 PM »
...not even an honorable mention.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

trogg

  • Bull Frog
  • Posts: 255
Re: MakeSlot.lsp My first routine posting
« Reply #12 on: December 28, 2010, 05:36:47 PM »
thanks guys
much appreciated

johnson

  • Guest
Re: MakeSlot.lsp My first routine posting
« Reply #13 on: January 02, 2011, 01:28:23 AM »
Some food for thought, using an LWPolyline with bulge  :-)

Code: [Select]
(defun c:ms ( / _dxf e1 e2 c1 c2 r1 r2 di dr an tan ang ) (vl-load-com)
  ;; © Lee Mac 2010

  (defun _dxf ( code entity ) (cdr (assoc code (entget entity))))

  (if
    (and
      (vl-every
        (function
          (lambda ( sym str )
            (and (set sym (car (entsel str)))
              (eq "CIRCLE" (cdr (assoc 0 (entget (eval sym)))))
            )
          )
        )
        '(e1 e2) '("\nSelect First Circle: " "\nSelect Second Circle: ")
      )
      (progn
        (setq c1 (_dxf 10 e1) c2 (_dxf 10 e2) r1 (_dxf 40 e1) r2 (_dxf 40 e2)
         
              di (distance c1 c2) dr (- r1 r2) an (angle c1 c2)
        )
        (< (abs dr) di)
      )
    )
    (progn (setq tan (sqrt (- (* di di) (* dr dr))) ang (atan di dr))
      (
        (lambda ( b1 b2 )
          (entmakex
            (list
              (cons 0 "LWPOLYLINE")
              (cons 100 "AcDbEntity")
              (cons 100 "AcDbPolyline")
              (cons 90 4)
              (cons 70 1)
              (cons 10 (polar c1 (+ an ang) r1))
              (cons 42 b1)
              (cons 10 (polar c1 (- an ang) r1))
              (cons 10 (polar c2 (- an ang) r2))
              (cons 42 b2)
              (cons 10 (polar c2 (+ an ang) r2))
            )
          )
        )
        (/ (sin (/ (- pi ang) 2.0)) (cos (/ (- pi ang) 2.0)))
        (/ (sin (/       ang  2.0)) (cos (/       ang  2.0)))
      )
      (mapcar 'entdel (list e1 e2))
    )
  )

  (princ)
)



this is nice....here can we add any extra line.....with any size.

johnson

  • Guest
Re: MakeSlot.lsp My first routine posting
« Reply #14 on: January 09, 2011, 08:10:57 PM »
Some food for thought, using an LWPolyline with bulge  :-)

Code: [Select]
(defun c:ms ( / _dxf e1 e2 c1 c2 r1 r2 di dr an tan ang ) (vl-load-com)
  ;; © Lee Mac 2010

  (defun _dxf ( code entity ) (cdr (assoc code (entget entity))))

  (if
    (and
      (vl-every
        (function
          (lambda ( sym str )
            (and (set sym (car (entsel str)))
              (eq "CIRCLE" (cdr (assoc 0 (entget (eval sym)))))
            )
          )
        )
        '(e1 e2) '("\nSelect First Circle: " "\nSelect Second Circle: ")
      )
      (progn
        (setq c1 (_dxf 10 e1) c2 (_dxf 10 e2) r1 (_dxf 40 e1) r2 (_dxf 40 e2)
         
              di (distance c1 c2) dr (- r1 r2) an (angle c1 c2)
        )
        (< (abs dr) di)
      )
    )
    (progn (setq tan (sqrt (- (* di di) (* dr dr))) ang (atan di dr))
      (
        (lambda ( b1 b2 )
          (entmakex
            (list
              (cons 0 "LWPOLYLINE")
              (cons 100 "AcDbEntity")
              (cons 100 "AcDbPolyline")
              (cons 90 4)
              (cons 70 1)
              (cons 10 (polar c1 (+ an ang) r1))
              (cons 42 b1)
              (cons 10 (polar c1 (- an ang) r1))
              (cons 10 (polar c2 (- an ang) r2))
              (cons 42 b2)
              (cons 10 (polar c2 (+ an ang) r2))
            )
          )
        )
        (/ (sin (/ (- pi ang) 2.0)) (cos (/ (- pi ang) 2.0)))
        (/ (sin (/       ang  2.0)) (cos (/       ang  2.0)))
      )
      (mapcar 'entdel (list e1 e2))
    )
  )

  (princ)
)



this is nice....here can we add any extra line.....with any size.


please see the attached drawing.

fixo

  • Guest
Re: MakeSlot.lsp My first routine posting
« Reply #15 on: January 11, 2011, 11:40:16 AM »
Found in my old codes
this will get you started I think
Code: [Select]
;; edited 10.01.11
(defun C:symt(/ *error*  ;|*debug*|; acsp adoc ang cir cp dist elp gap lineobj ln1 ln2 maxis pb pc pc1 pc2 pe1 pe2 pp pr rec resp)
(vl-load-com)
   ;; error trap by Doug Broad
  (defun *error*  (msg)   ; create standard error handler
      (cond ((not msg))   ; normal exit, no error
    ((member msg '("Function cancelled" "quit / exit abort"))) ; escape
    ((princ (strcat "\nError: " msg))   ; display fatal error
     ;(cond (*debug* (vl-bt)))   ; if in debug mode, dump backtrace
     ))
   
      (command "._undo" "_end")     
      )
 
  (defun 2dp  (p)
    (list (car p) (cadr p)))

  (defun 2d_varpt  (p)
    (vlax-safearray-fill
      (vlax-make-safearray vlax-vbdouble '(0 . 1))
      (2dp p)
      )
    )

  (command "._undo" "_begin")
  (setq adoc (vla-get-activedocument
       (vlax-get-acad-object))
acsp

     (if (= (getvar "cvport") 1)
       (vla-get-paperspace adoc)
       (vla-get-modelspace adoc)
       )
)
  (initget 0 "Circle Slot Ellipse")
  (if (not *shape*)
    (setq *shape* "Circle")
    )
  (setq resp (cond ((getkword
      (strcat "\nChoose a  shape [Circle/Slot/Ellipse] <"
      *shape*
      "> : ")))
   (*shape*)
   )
)
  (setq *shape* resp)
  (cond
    ;;************************** Circle ****************************
    ((= resp "Circle")
     (setq pc (getpoint "\nPick center of shape >>: "))
     (setq cir (vla-Addcircle acsp (vlax-3d-point pc) 0.0001))

     (while (and (setq pr (grread 5)) (= (car pr) 5))
       (if (> (distance (cadr pr) pc) 0)
(vla-put-Radius cir (distance (cadr pr) pc)))) ;

     (setq pb (vlax-curve-getClosestPointTo cir (cadr pr))
   dist (vlax-curve-getdistatpoint cir pb)
   gap (* (vla-get-Radius cir) 0.03)
   pc1 (vlax-curve-getpointatdist cir (- dist gap))
   pc2 (vlax-curve-getpointatdist cir (+ dist gap)))
     (vl-cmdf "_break" (vlax-vla-object->ename cir) "_F" pc1 pc2)
     (setq ln1 (vla-Addline acsp (vlax-3d-point pc1) (vlax-3d-point pb)))
     (setq ln2 (vla-Addline acsp (vlax-3d-point pc2) (vlax-3d-point pb)))

     (while (and (setq pr (grread 5)) (= (car pr) 5))
       (if (> (distance (cadr pr) pc) 0)
(progn
   (vla-put-endpoint ln1 (vlax-3d-point (cadr pr)))
   (vla-put-endpoint ln2 (vlax-3d-point (cadr pr))))
))
     )
    ;;circle

    ;;************************** Ellipse ****************************
    ((= resp "Ellipse")
     (setq pe1 (getpoint "\nPick start point of axis >>: ")
   pe2 (getpoint pe1 "\nPick end point of axis >>: ")
   ang (angle pe1 pe2)
   cp (mapcar (function (lambda (a b) (/ (+ a b) 2.))) pe1 pe2)
   maxis (vlax-3d-point
   (trans (polar '(0 0 0) ang (distance pe1 pe2)) 0 1)))
     (setq elp (vla-Addellipse
acsp
(vlax-3d-point (trans cp 0 1))
maxis
0.8))

     (while (and (setq pr (grread 5)) (= (car pr) 5))
       (if (> (distance (cadr pr) cp) 0)
(progn
   (setq maxis (vlax-3d-point
(trans (polar '(0 0 0) ang (distance cp (cadr pr))) 0 1)))
   (vla-put-majoraxis elp maxis)
   )))   ;

     (setq pb (vlax-curve-getClosestPointTo elp (cadr pr))
   dist (vlax-curve-getdistatpoint elp pb)
   gap (* (vlax-curve-getDistAtParam elp (vlax-curve-getendParam elp))
   0.03)
   pc1 (vlax-curve-getpointatdist elp (- dist gap))
   pc2 (vlax-curve-getpointatdist elp (+ dist gap)))
     (vl-cmdf "_break" (vlax-vla-object->ename elp) "_F" pc1 pc2)
     (setq ln1 (vla-Addline acsp (vlax-3d-point pc1) (vlax-3d-point pb)))
     (setq ln2 (vla-Addline acsp (vlax-3d-point pc2) (vlax-3d-point pb)))

     (while (and (setq pr (grread 5)) (= (car pr) 5))
       (if (> (distance (cadr pr) cp) 0)
(progn
   (vla-put-endpoint ln1 (vlax-3d-point (cadr pr)))
   (vla-put-endpoint ln2 (vlax-3d-point (cadr pr))))
))
     )
    ;;************************** Slot ****************************
    ((= resp "Slot")
     (setq pe1    (getpoint "\nPick start point of axis >>: ")
   pe2    (getpoint pe1 "\nPick end point of axis >>: ")
   ang    (angle pe1 pe2)
   cp    (mapcar (function (lambda (a b) (/ (+ a b) 2.))) pe1 pe2)
   lineobj (vlax-invoke
     acsp
     'addline
     pe1
     pe2))

     (setq rec
    (vlax-invoke
      acsp
      'addlightweightpolyline

      (apply 'append
     (mapcar (function (lambda (p) (list (car p) (cadr p))))
     (list pe1 pe1 pe2 pe2)))))
     (vla-setbulge rec 0 -1)
     (vla-setbulge rec 2 -1)
     (vla-put-closed rec :vlax-true)

     (while
       (and
(setq pp (grread 5))
(= (car pp) 5)
)
(setq dist (/ (distance (cadr pp)
(vlax-curve-getClosestPointTo lineobj (cadr pp)))
      2.0)
      )

(vla-put-coordinate
  rec
  0
  (vlax-safearray-fill
    (vlax-make-safearray vlax-vbdouble '(0 . 1))
    (2dp
      (polar pe1 (- ang (/ pi 2)) dist))))

(vla-put-coordinate
  rec
  1
  (vlax-safearray-fill
    (vlax-make-safearray vlax-vbdouble '(0 . 1))
    (2dp
      (polar pe1 (+ ang (/ pi 2)) dist))))

(vla-put-coordinate
  rec
  2
  (2d_varpt
    (polar pe2 (+ ang (/ pi 2)) dist)))

(vla-put-coordinate
  rec
  3
  (vlax-safearray-fill
    (vlax-make-safearray vlax-vbdouble '(0 . 1))
    (2dp
      (polar pe2 (- ang (/ pi 2)) dist))))

)

     (setq pb (vlax-curve-getClosestPointTo rec (cadr pp))
   dist (vlax-curve-getdistatpoint rec pb)
   gap (* (vlax-curve-getDistAtParam rec (vlax-curve-getendParam rec))
   0.015)
   pc1 (vlax-curve-getpointatdist rec (- dist gap))
   pc2 (vlax-curve-getpointatdist rec (+ dist gap)))
     (vl-cmdf "_break" (vlax-vla-object->ename rec) "_F" pc1 pc2)
     (setq ln1 (vla-Addline acsp (vlax-3d-point pc1) (vlax-3d-point pb)))
     (setq ln2 (vla-Addline acsp (vlax-3d-point pc2) (vlax-3d-point pb)))

     (while (and (setq pp (grread 5)) (= (car pp) 5))
       (if (> (distance (cadr pp) pb) 0)
(progn
   (vla-put-endpoint ln1 (vlax-3d-point (cadr pp)))
   (vla-put-endpoint ln2 (vlax-3d-point (cadr pp))))
))
     (if lineobj
       (progn (vla-delete lineobj)
      (vlax-release-object lineobj)))

     )

    )
  (*error* nil)
(princ)

)

johnson

  • Guest
Re: MakeSlot.lsp My first routine posting
« Reply #16 on: January 11, 2011, 07:50:24 PM »
Found in my old codes
this will get you started I think
Code: [Select]
;; edited 10.01.11
(defun C:symt(/ *error*  ;|*debug*|; acsp adoc ang cir cp dist elp gap lineobj ln1 ln2 maxis pb pc pc1 pc2 pe1 pe2 pp pr rec resp)
(vl-load-com)
   ;; error trap by Doug Broad
  (defun *error*  (msg)  ; create standard error handler
      (cond ((not msg))  ; normal exit, no error
   ((member msg '("Function cancelled" "quit / exit abort"))) ; escape
   ((princ (strcat "\nError: " msg))  ; display fatal error
    ;(cond (*debug* (vl-bt)))  ; if in debug mode, dump backtrace
    ))
    
      (command "._undo" "_end")      
      )
  
  (defun 2dp  (p)
    (list (car p) (cadr p)))

  (defun 2d_varpt  (p)
    (vlax-safearray-fill
      (vlax-make-safearray vlax-vbdouble '(0 . 1))
      (2dp p)
      )
    )

  (command "._undo" "_begin")
  (setq adoc (vla-get-activedocument
      (vlax-get-acad-object))
acsp

    (if (= (getvar "cvport") 1)
      (vla-get-paperspace adoc)
      (vla-get-modelspace adoc)
      )
)
  (initget 0 "Circle Slot Ellipse")
  (if (not *shape*)
    (setq *shape* "Circle")
    )
  (setq resp (cond ((getkword
     (strcat "\nChoose a  shape [Circle/Slot/Ellipse] <"
     *shape*
     "> : ")))
  (*shape*)
  )
)
  (setq *shape* resp)
  (cond
    ;;************************** Circle ****************************
    ((= resp "Circle")
     (setq pc (getpoint "\nPick center of shape >>: "))
     (setq cir (vla-Addcircle acsp (vlax-3d-point pc) 0.0001))

     (while (and (setq pr (grread 5)) (= (car pr) 5))
       (if (> (distance (cadr pr) pc) 0)
(vla-put-Radius cir (distance (cadr pr) pc)))) ;

     (setq pb (vlax-curve-getClosestPointTo cir (cadr pr))
  dist (vlax-curve-getdistatpoint cir pb)
  gap (* (vla-get-Radius cir) 0.03)
  pc1 (vlax-curve-getpointatdist cir (- dist gap))
  pc2 (vlax-curve-getpointatdist cir (+ dist gap)))
     (vl-cmdf "_break" (vlax-vla-object->ename cir) "_F" pc1 pc2)
     (setq ln1 (vla-Addline acsp (vlax-3d-point pc1) (vlax-3d-point pb)))
     (setq ln2 (vla-Addline acsp (vlax-3d-point pc2) (vlax-3d-point pb)))

     (while (and (setq pr (grread 5)) (= (car pr) 5))
       (if (> (distance (cadr pr) pc) 0)
(progn
  (vla-put-endpoint ln1 (vlax-3d-point (cadr pr)))
  (vla-put-endpoint ln2 (vlax-3d-point (cadr pr))))
))
     )
    ;;circle

    ;;************************** Ellipse ****************************
    ((= resp "Ellipse")
     (setq pe1 (getpoint "\nPick start point of axis >>: ")
  pe2 (getpoint pe1 "\nPick end point of axis >>: ")
  ang (angle pe1 pe2)
  cp (mapcar (function (lambda (a b) (/ (+ a b) 2.))) pe1 pe2)
  maxis (vlax-3d-point
  (trans (polar '(0 0 0) ang (distance pe1 pe2)) 0 1)))
     (setq elp (vla-Addellipse
acsp
(vlax-3d-point (trans cp 0 1))
maxis
0.8))

     (while (and (setq pr (grread 5)) (= (car pr) 5))
       (if (> (distance (cadr pr) cp) 0)
(progn
  (setq maxis (vlax-3d-point
(trans (polar '(0 0 0) ang (distance cp (cadr pr))) 0 1)))
  (vla-put-majoraxis elp maxis)
  )))  ;

     (setq pb (vlax-curve-getClosestPointTo elp (cadr pr))
  dist (vlax-curve-getdistatpoint elp pb)
  gap (* (vlax-curve-getDistAtParam elp (vlax-curve-getendParam elp))
  0.03)
  pc1 (vlax-curve-getpointatdist elp (- dist gap))
  pc2 (vlax-curve-getpointatdist elp (+ dist gap)))
     (vl-cmdf "_break" (vlax-vla-object->ename elp) "_F" pc1 pc2)
     (setq ln1 (vla-Addline acsp (vlax-3d-point pc1) (vlax-3d-point pb)))
     (setq ln2 (vla-Addline acsp (vlax-3d-point pc2) (vlax-3d-point pb)))

     (while (and (setq pr (grread 5)) (= (car pr) 5))
       (if (> (distance (cadr pr) cp) 0)
(progn
  (vla-put-endpoint ln1 (vlax-3d-point (cadr pr)))
  (vla-put-endpoint ln2 (vlax-3d-point (cadr pr))))
))
     )
    ;;************************** Slot ****************************
    ((= resp "Slot")
     (setq pe1   (getpoint "\nPick start point of axis >>: ")
  pe2   (getpoint pe1 "\nPick end point of axis >>: ")
  ang   (angle pe1 pe2)
  cp   (mapcar (function (lambda (a b) (/ (+ a b) 2.))) pe1 pe2)
  lineobj (vlax-invoke
    acsp
    'addline
    pe1
    pe2))

     (setq rec
   (vlax-invoke
     acsp
     'addlightweightpolyline

     (apply 'append
    (mapcar (function (lambda (p) (list (car p) (cadr p))))
    (list pe1 pe1 pe2 pe2)))))
     (vla-setbulge rec 0 -1)
     (vla-setbulge rec 2 -1)
     (vla-put-closed rec :vlax-true)

     (while
       (and
(setq pp (grread 5))
(= (car pp) 5)
)
(setq dist (/ (distance (cadr pp)
(vlax-curve-getClosestPointTo lineobj (cadr pp)))
     2.0)
     )

(vla-put-coordinate
 rec
 0
 (vlax-safearray-fill
   (vlax-make-safearray vlax-vbdouble '(0 . 1))
   (2dp
     (polar pe1 (- ang (/ pi 2)) dist))))

(vla-put-coordinate
 rec
 1
 (vlax-safearray-fill
   (vlax-make-safearray vlax-vbdouble '(0 . 1))
   (2dp
     (polar pe1 (+ ang (/ pi 2)) dist))))

(vla-put-coordinate
 rec
 2
 (2d_varpt
   (polar pe2 (+ ang (/ pi 2)) dist)))

(vla-put-coordinate
 rec
 3
 (vlax-safearray-fill
   (vlax-make-safearray vlax-vbdouble '(0 . 1))
   (2dp
     (polar pe2 (- ang (/ pi 2)) dist))))

)

     (setq pb (vlax-curve-getClosestPointTo rec (cadr pp))
  dist (vlax-curve-getdistatpoint rec pb)
  gap (* (vlax-curve-getDistAtParam rec (vlax-curve-getendParam rec))
  0.015)
  pc1 (vlax-curve-getpointatdist rec (- dist gap))
  pc2 (vlax-curve-getpointatdist rec (+ dist gap)))
     (vl-cmdf "_break" (vlax-vla-object->ename rec) "_F" pc1 pc2)
     (setq ln1 (vla-Addline acsp (vlax-3d-point pc1) (vlax-3d-point pb)))
     (setq ln2 (vla-Addline acsp (vlax-3d-point pc2) (vlax-3d-point pb)))

     (while (and (setq pp (grread 5)) (= (car pp) 5))
       (if (> (distance (cadr pp) pb) 0)
(progn
  (vla-put-endpoint ln1 (vlax-3d-point (cadr pp)))
  (vla-put-endpoint ln2 (vlax-3d-point (cadr pp))))
))
     (if lineobj
       (progn (vla-delete lineobj)
     (vlax-release-object lineobj)))

     )

    )
  (*error* nil)
(princ)

)


Its really nice.But here for circle and slot option line length gap is coming very small.so how to fix that line gap length.please see the PIC.For ellipse that gap is coming good.
« Last Edit: January 11, 2011, 07:59:21 PM by johnson »

fixo

  • Guest
Re: MakeSlot.lsp My first routine posting
« Reply #17 on: January 12, 2011, 08:09:15 AM »
Sorry for the belating, mate
Just change the gap size in the similar code lines:
Code: [Select]
...gap (* (vla-get-Radius cir) 0.03);<--set the scale bigger (say set 0.1 instead of 0.03)

~'J'~