Fillet in Lisp

Fillet in Lisp

Tony_Gibbs
Advocate Advocate
3,668 Views
6 Replies
Message 1 of 7

Fillet in Lisp

Tony_Gibbs
Advocate
Advocate
Can somebody please tell me why this won't work. Or give me an alternative. 
Towards the bottom of the code is the command "FILLET
Everything works before & after this command

.(defun c:qqq (/ a BarLength InsertPoint FirstBar SecondBar FirstLine SecondLine ThirdLine FourthLine) (savevartoold) (reobarlayer) (setvar "Osmode" 1) (setvar "orthomode" 0) (setq BarLength (getreal "\nEnter New Bar Length or Use <500>")) (setq a "T") (while a (setvar "osmode" 1) (setq InsertPoint (getpoint "\nSelect Insertion Corner:")) (initget 33) (setvar "osmode" 513) (setq FirstBar (getpoint InsertPoint "\nFirst corner bar direction:") SecondBar (getpoint InsertPoint "\nSecond corner bar direction:")) (progn (command ".pline" InsertPoint FirstBar "") (setq FirstLine (entlast)) (command ".lengthen" FirstLine "T" 500 FirstBar "" ".offset" 25 FirstLine SecondBar "") (setq ThirdLine (entlast))) (progn (command ".pline" InsertPoint SecondBar "") (setq SecondLine (entlast)) (command ".lengthen" SecondLine "T" 500 SecondBar "" ".offset" 25 SecondLine FirstBar "") (setq FourthLine (entlast))) (progn (command ".fillet" ThirdLine FourthLine ;THIS IS THE LINE I'M HAVING TROUBLE WITH ".lengthen" "T" 500 ThirdLine FourthLine "" ".erase" FirstLine SecondLine "")) (if (= FirstPoint "") (setq a nil)) ) (resetoldvar) (princ) )

 

0 Likes
Accepted solutions (3)
3,669 Views
6 Replies
Replies (6)
Message 2 of 7

ВeekeeCZ
Consultant
Consultant
Accepted solution

FILLET needs to be suplies with pairs (<entityname> point)

 

(entlast) does not offer a point, so make one

(cons (entlast) (some point closer to desired corner - probably made by (polar)) )

0 Likes
Message 3 of 7

smaher12
Advocate
Advocate
Accepted solution

If you decide to ditch the fillet option, this should work.

 

 

(defun c:qqq (/ bl ip fb sb fb1 sb2 ent)

  (setq os (getvar 'osmode)
        om (getvar 'orthomode)
  )
  (setvar 'osmode 513)
  (setvar 'orthomode 0)

  (if (not $bl) (setq $bl 500))
    (setq bl (getreal (strcat "\nSpecify bar length [Inches] <"(rtos $bl 2 0)">: ")))
      (if (not bl) (setq bl $bl))
        (setq $bl bl)

  (while
    (setq ip (getpoint "\nSpecify insertion corner: "))

      (progn
         (setq fb (getpoint ip "\nSpecify first bar direction: ")
               sb (getpoint ip "\nSpecify second bar direction: ")
               fb1 (polar ip (angle ip fb) (+ bl 25))
               sb2 (polar ip (angle ip sb) (+ bl 25))
         )
         (command "_.pline" "_none" fb1 "_none" ip "_none" sb2 "")
         (setq ent (entlast))
         (command "_.offset" 25 ent sb2 ""
                  "_.erase" ent "")
      )
   )
    (setvar 'osmode os)
    (setvar 'orthomode om)
 (princ)
)
Message 4 of 7

Kent1Cooper
Consultant
Consultant
Accepted solution

@Tony_Gibbs wrote:
....
    (setq BarLength (getreal "\nEnter New Bar Length or Use <500>"))
....
(initget 33) (setvar "osmode" 513) ....
(command ".fillet" ThirdLine FourthLine ".lengthen" "T" 500 ThirdLine FourthLine "" ....

A few comments on the above....

 

The BarLength variable is never used.  It can be asked for with any previous setting offered as default, or 500 if there is no previous setting [@smaher12 included a way of doing that; my suggestion below is another way].

 

If 500 is a typical bar length value, I assume you never need decimals, so it may as well be (getint) rather than (getreal).

 

Setting OSMODE to 513 is pointless, because the NEArest part of that will always "win out" over the ENDpoint part -- just use 512 for Nearest only.

 

Since the lines drawn are Polylines, if you adjust the code to successfully Fillet them, the result will be one Polyline [the same entity name as the latest one drawn], so Lengthen will not be able to find one of those that it's asked to work on, because it will no longer exist.  And if it gets to seeing the one that still exists, that will be shortened to an overall length of 500 [both legs combined], approximately removing one leg, except for the fact that Lengthen also requires not just an entity name but a point, so it knows which end to change.

 

And some other issues....

 

You have several unnecessary (progn) functions that "wrap" groups of things that don't need to be wrapped -- they can all stand on their own within the (while) function.

 

The (initget 33) ought to be repeated for the SecondBar prompt as for the FirstBar prompt.

 

Since you turn off ORTHO, I assume the legs of these bent bars will not always be perpendicular.  When they're not, @smaher12's suggestion will not result in correct leg lengths -- the adding of 25 to the initial lengths before Offsetting will work right only with a right-angle bend.

 

You can just get the angles of the legs directly as angles, rather than get points and work with the angles from the corner to them.

 

The whether-to-continue thing can be based directly on whether the User picks a corner point, without the 'a' variable and the checking for it.

 

Here's a [minimally tested] way of doing it that accounts for all of those things:

 

(vl-load-com)
(defun C:qqq (/ InsPt Ang1 Ang2 start pl1 pl2)
 (savevartoold) (reobarlayer) (setvar 'osmode 1) (setvar 'orthomode 0)
  (setq BarLength ; non-localized variable to remember for later use
    (cond ; [assuming always integer values used]
      ( (getint ; [returns nil on Enter]
          (strcat
            "\nEnter New Bar Length <"
            (if BarLength (itoa BarLength) "500"); prior value as default if present
            ">: "
          ); strcat
        ); getint
      ); User-input condition
      (BarLength); User pressed Enter with prior value
      (500); Enter with no prior value [first use]
    ); cond
  ); setq
  (while (setq InsPt (getpoint "\nSelect Insertion Corner <exit>: "))
    (setvar 'osmode 512)
    (initget 33)
    (setq Ang1 (getangle InsPt "\nFirst corner bar direction:"))
    (initget 33)
    (setq Ang2 (getangle InsPt "\nSecond corner bar direction:"))
    (command "_.pline"
      "_none" (setq start (polar InsPt Ang1 BarLength))
      "_none" InsPt
      "_none" (polar InsPt Ang2 BarLength)
      ""
      "_.offset" 25 (list (setq pl1 (entlast )) InsPt)
        (mapcar '/ (mapcar '+ start (vlax-curve-getEndPoint pl1)) '(2 2 2)) ""
      "_scale" (setq pl2 (entlast)) ""
        (setq InsPt (vlax-curve-getPointAtParam pl2 1)); replace former value
        "_reference" (distance InsPt (vlax-curve-getStartPoint pl2)) BarLength
    ); command
    (entdel pl1)
    (setvar 'osmode 1); for next one
  ); while
  (resetoldvar)
  (princ)
); defun

It could replace the Offsetting and length adjustment and deletion of the initial Polyline, with just MOVE-ing the Polyline instead.  That would eliminate some steps and at least one variable, but would also require some trigonometric calculations to determine how far and in what direction to Move it.

Kent Cooper, AIA
Message 5 of 7

Tony_Gibbs
Advocate
Advocate
Thank you very much for your help

Tony
0 Likes
Message 6 of 7

smaher12
Advocate
Advocate

No problem. I enjoyed learning a little something from it.

 

Kent1Cooper had a key point in my previous suggestion. If the bars are not always perpendicular, that the result of leg lengths would be incorrect. Therfore with a little research the following should work much better.

 

(defun c:qqq (/ os om bl ip fb sb a1 a2 t1 t2 t3)
  (setq os (getvar 'osmode)
        om (getvar 'orthomode)
  )
  (setvar 'osmode 513)
  (setvar 'orthomode 0)

  (if (not $bl) (setq $bl 500))
    (setq bl (getreal (strcat "\nSpecify bar length [Inches] <"(rtos $bl 2 0)">: ")))
      (if (not bl) (setq bl $bl))
        (setq $bl bl)

  (while
    (setq ip (getpoint "\nSpecify insertion corner: "))

    (progn
      (setq fb (getpoint ip "\nSpecify first bar direction: ")
	    sb (getpoint ip "\nSpecify second bar direction: ")
      )

      ;;; find angle of 3 points - thank you lee mac
      (setq a1 ((lambda ( a ) (min a (- (+ pi pi) a)))
		 (rem (+ pi pi (- (angle ip fb) (angle ip sb))) (+ pi pi)))
	    a2 (/ (* 180.0 (/ a1 pi)) 2)
      )
      ;;; 25 is the offset height divide by tangent angle 
      (setq t1 (/ 25 (/ (sin (* (/ (float a2) 180) pi)) (cos (* (/ (float a2) 180) pi))))
	    t2 (polar ip (angle ip fb) t1)
	    t3 (polar t2 (+ (angle ip fb) (/ pi 2)) 25)
      )
      (command "_.pline" "_none" (polar t3 (angle ip fb) bl)
	       "_none" t3 "_none" (polar t3 (angle ip sb) bl) "")
    );progn
  );while

  (setvar 'osmode os)
  (setvar 'orthomode om)
 (princ)
)

 

 

Message 7 of 7

Tony_Gibbs
Advocate
Advocate

Thanks to all who had input into this. I will now rewrite this routine and incorporate your codes

Much appreciated

 

Tony

0 Likes