TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Kate M on January 22, 2004, 10:18:33 AM

Title: arc challenge
Post by: Kate M on January 22, 2004, 10:18:33 AM
Okay, I admit there's motive behind this other than just giving you guys something to do... :-)

I need to draw an arc (or a circle), defined by two tangents and a point on the circle -- not a radius like TTR.

Sorta like this:

(http://theswamp.org/lilly.pond/Kate%20M/arc%20example.JPG)

Make sense? I know it's a little nutty...think there's a command in vanilla AutoCAD that might do this? If not....have fun... ;-)
Title: arc challenge
Post by: Mark on January 22, 2004, 10:26:42 AM
could you modify the image to show the arc/circle, maybe a dotted line.
Title: arc challenge
Post by: Kate M on January 22, 2004, 10:36:33 AM
(http://theswamp.org/lilly.pond/Kate%20M/arc%20example2.JPG)

I actually found a way to do it, but it's a little complicated -- I'm not even sure I could describe it. Has to do with the fact that if you hit enter after starting the arc command, it starts the arc tangent to the last line you drew. Then it's a matter of knowing how far your point of contact is from the intersection of the two "tangent" lines...give me a few and I'll post what I actually did.
Title: arc challenge
Post by: SMadsen on January 22, 2004, 10:37:20 AM
Kate, excellent challenge :)
Just one question: is the point that the circle must pass thru the tangent point? In other words, is the point always located on one of the tangents?
Title: arc challenge
Post by: Kate M on January 22, 2004, 10:42:32 AM
Stig,

Yes, the point is always on one of the tangents.

Here's what I ended up doing:

(http://theswamp.org/lilly.pond/Kate%20M/arc%20example3.JPG)

The geometry's pretty simple, it's just forcing the tangents to behave...for some reason, you can't draw arcs tangent to other lines...using the TAN osnap doesn't give anything.
Title: arc challenge
Post by: hendie on January 22, 2004, 11:01:20 AM
am I missing something here.
Quote
Command: _circle Specify center point for circle or [3P/2P/Ttr (tan tan
radius)]: _3p Specify first point on circle: _tan to
Specify second point on circle: _tan to
Specify third point on circle:

selecting a 3 point circle, then just using tangent snaps for the first two points (on the lines) and then picking a third point gives a circle  as required
or are you just looking for a lisp routine to save using the snap menu
Title: arc challenge
Post by: Kate M on January 22, 2004, 11:18:07 AM
Hendie,

Sort of...I guess maybe what I'm looking for is a fillet with a defined endpoint and an unspecified radius -- the 3P circle doesn't always stay "between" the tangent lines -- see my 2nd picture.
Title: arc challenge
Post by: rude dog on January 22, 2004, 11:51:52 AM
I use start,end,direction from arc pull down menu
turn on ortho first....when it prompts you for direction point pick the
intersection of the two lines[/img]
Title: arc challenge
Post by: Kate M on January 22, 2004, 12:55:00 PM
RD,

Not quite, I only know where the angle starts, not where it ends.
Title: arc challenge
Post by: Mark on January 22, 2004, 01:16:02 PM
I give up............. I had the same answer as hendie. I would like to see the calculations for solving that arc.
Title: arc challenge
Post by: CAB on January 22, 2004, 01:37:27 PM
Kate,
This is off the subject, but how did you capture that image on you system?
I can't get a clear image using PrintScreen then pasting into an image program, save as jpg of tiff.
CAB
Title: arc challenge
Post by: SMadsen on January 22, 2004, 02:05:55 PM
Here are some basic calculations but it does not calculate the proper order of points.
For it to work, lines have to be drawn in CCW orientation. Otherwise it will produce unexpected results.

I don't have time to calculate orientations so I'll just toss it out there.
Basically, it just finds the perpendicular from the picked point, "mirrors" it to the other line and where they intersect is the center point. The perpendiculars then become legs of the start and end angles. Simple.

Code: [Select]
(defun make-arc (cpt pt pt2)
  (setq lst (list '(0 . "ARC")
                  '(100 . "AcDbEntity")
                  '(100 . "AcDbCircle")
                  (cons 10 cpt)
                  (cons 40 (distance pt cpt))
                  '(210 0.0 0.0 1.0)
                  '(100 . "AcDbArc")
                  (cons 50 (angle cpt pt2))
                  (cons 51 (angle cpt pt))
            )
  )
  (entmake lst)
)

(defun C:TANARC (/ cp1 cp2 cpt e1 e2 idist ip n o obj1 obj2
               p1 p2 p3 p4 pt pt2)
  (setq e1 (entsel "\nPick first line: ")
        e2 (entsel "\nPick second line: ")
        pt (getpoint "\nPick start point on line: ")
  )
  (cond
    ((and e1 e2 pt)
     (setq obj1 (vlax-ename->vla-object (car e1))
           obj2 (vlax-ename->vla-object (car e2))
     )
     (mapcar (function (lambda (n o) (set n (vlax-curve-getstartpoint o))))
             '(p1 p3) (list obj1 obj2)
     )
     (mapcar (function (lambda (n o) (set n (vlax-curve-getendpoint o))))
             '(p2 p4) (list obj1 obj2)
     )
     (cond ((setq ip (inters p1 p2 p3 p4 nil))
            (setq idist (distance ip pt)
                  cp1   (polar pt (+ (angle p1 p2) (/ pi 2.0)) idist)
                  pt2   (polar ip (angle p3 p4) (distance ip pt))
                  cp2   (polar pt2 (+ (angle p3 p4) (/ pi 2.0)) idist)
                  cpt   (inters pt cp1 pt2 cp2 nil)
            )
            (make-arc cpt pt pt2)
           )
     )
    )
  )
)
Title: arc challenge
Post by: Mark on January 22, 2004, 02:15:51 PM
- CAB
If your are using 2004 do a pngout or a jpgout

edited
nevermind........... i see you're using 2000  :oops:
Title: arc challenge
Post by: Kate M on January 22, 2004, 02:26:53 PM
CAB,

Just ctrl+alt+print screen, into Paint, save as JPG...nothin' special. WMFOUT is good too.
Title: arc challenge
Post by: Kate M on January 22, 2004, 02:36:34 PM
Pretty nifty, Stig. :-) It's a little tricky where it places the arc, but I got it do what I needed. Orientation would be great, but I won't get greedy. ;-)

Thanks guys!
Title: arc challenge
Post by: SMadsen on January 22, 2004, 02:37:43 PM
Here's a graphic of the points calculated in TANARC, if anyone should happen to be interested in playing with it:

(http://theswamp.org/lilly.pond/public/tanarc.jpg)

Wow, bad quality!
Title: arc challenge
Post by: Keith™ on January 22, 2004, 09:46:01 PM
Ok, I took it upon myself to put together the proggie Kate needs .... you can get it here (http://www.theswamp.org/lilly.pond/public/TanArc.VLX)

Kate, let me know if it suits your needs
Title: arc challenge
Post by: DParcon on January 22, 2004, 11:09:20 PM
Kate,

Here's a routine that takes care of arc direction,
based on Stig's routine/diagram (pure Autolisp,
points calculation and using arcs' command
3-points option).

Code: [Select]


(defun C:TANARC2 (/ ang ang1 ang2 bang cpt dst dst2 e1 e2
                    flag fuzz ipt p1 p2 p3 p4 pt pt1 pt2 rad)
  (prompt "Pick 2 Lines, Arc Start Point First..")
  (setq e1 (entsel "\nPick first line: ")
        e2 (entsel "\nPick second line: ")
        pt (getpoint "\nPick start point on line: ")
        flag nil
        fuzz 1e-12
  )
  (and (and e1 e2 pt)
       (setq p1 (cdr (assoc 10 (entget (car e1)))))
       (setq p2 (cdr (assoc 11 (entget (car e1)))))
       (setq p3 (cdr (assoc 10 (entget (car e2)))))
       (setq p4 (cdr (assoc 11 (entget (car e2)))))
       (setq ipt (inters p1 p2 p3 p4 nil))
       (setq ang1 (angle ipt pt))
       (setq ang2 (if (< (distance ipt p3) (distance ipt p4))
                    (angle ipt p4)
                    (angle ipt p3)
                  )
       )
       (setq ang (* (+ ang1 ang2) 0.5))
       (setq dst (distance ipt pt))
       (setq bang (abs (- ang ang1)))
       (setq dst2 (/ dst (cos bang)))
       (setq cpt (polar ipt ang dst2))
       (setq rad (distance cpt pt))
       (setq pt1 (polar cpt (+ ang pi) rad))
       (setq pt2 (polar ipt ang2 dst))
       (setq flag T)
  )
  (if flag
    (command "_.arc" pt pt1 pt2)
    (Alert "User Error")
  )
)



Enjoy.
Title: arc challenge
Post by: Kate M on January 23, 2004, 09:28:27 AM
Keith - that worked fabulously! Thanks!

Don - I couldn't get it to work unless the original lines were in a "V" shape (not upside-down or sideways). Am I missing something?

Thanks again -- you guys are awesome. :-)
Title: arc challenge
Post by: Keith™ on January 23, 2004, 10:47:17 AM
Kate, the problem mentioned by Stig is also the same problem within Don's routine. What happens is that while the points that define the arc are exact, the method for getting them can give an inaccurate center point or the arc IF either of the lines angle fits this profile : 180 < angle < 0

The same thing can happen IF the line is drawn in the opposite direction, instead of drawing the lines from left to right, if they were drawn from right to left it buggers up the code without some more error checking.

So, to put the whole thing together and eliminate the need for a whole lot of error checking, the key was to have the user select the beginning tangent point and the line to have a matching point. Using each point, we needed to find the intersection of both of those point at 90deg from the line they are located on.

So, basically it is ..
Code: [Select]

(setq center (inters pt1 pt2 pt3 pt4))


Now we know that the distance between pt1 and center is the radius of the arc, AND it will always be on the smaller angle side of the lines because there is no intersection of the lines on the larger angle side.

So, you have the point selected by the user, and the center of the arc, now all you need to do is draw an arc from PT1 using a radius of (distance pt1 center) to PT3 which is a point lying on the second line an equal distance from the intersection of the two lines to PT1.

The only error checking reqired is to make sure the arc is drawn using the correct beginning angle, otherwise it creates the arc representing the remaining portion of the circle.

Not really too difficult, but I wanted to make it as simple for the end user as possible. I am glad it worked out ok.
Title: arc challenge
Post by: SMadsen on January 23, 2004, 11:16:06 AM
DParcon, cool that you played some with the function. Although switching the points based on direction did some of it, it doesn't cut it all the way.

Keith, it didn't quite work, either. Guess we need to determine which "quadrant" is being picked?
(http://theswamp.org/lilly.pond/public/tanarcK.jpg)

Oh I love to make comments without making suggestions on my own :)
Title: arc challenge
Post by: Keith™ on January 23, 2004, 11:30:23 AM
Mine didn't work, or the modifications to yours didn't work, I am confused...
Title: arc challenge
Post by: SMadsen on January 23, 2004, 11:38:06 AM
None of them works outside the scope of the specific situation that Kate illustrated.
Title: arc challenge
Post by: Kate M on January 23, 2004, 12:31:23 PM
Guess this is a little more complicated than I thought it would be... :-)
Title: arc challenge
Post by: daron on January 23, 2004, 12:32:20 PM
You did say it was a challenge. Well, you were right.
Title: arc challenge
Post by: deegeecees on January 23, 2004, 12:34:25 PM
use the sketch command...

Problem solved! :D
Title: arc challenge
Post by: Keith™ on January 23, 2004, 12:58:34 PM
Ok well let me revisit it then ...
Title: arc challenge
Post by: DParcon on January 23, 2004, 04:39:48 PM
Kate,

 Here's some minor alterations to the routine I've
 posted. This will probably solved the current arc
 direction problems (no rigorous testing done)
 particularly on the 1st/4th quadrant scenarios.
 
 Change the statements for ang2 and ang as
 shown below:

 
Code: [Select]


       (setq ang2 (angle ipt (cadr e2)))
       (setq ang (if (> (setq ang (* (+ ang1 ang2) 0.5)) pi)
                   (- ang pi)
                   ang
                 )
       )

 


 For additional accuracy, you can calculate the actual values
 of the line angles using the endpoints. You can change the
 fuzz factor if you want (currently @ 0.57 degree).The changes
 will include ang1, ang2 & ang as in the code shown below:
 
 
Code: [Select]

     
       (setq ang1 (if (equal (angle ipt pt) (angle p1 p2) 0.01)
                     (angle p1 p2)
                     (angle p2 p1)
                 )
       )      
       (setq ang2 (if (equal (angle ipt (car e2)) (angle p3 p4) 0.01)
                    (angle p3 p4)
                    (angle p4 p3)
                 )
       )
       (setq ang (if (> (setq ang (* (+ ang1 ang2) 0.5)) pi)
                   (- ang pi)
                   ang
                 )
       )

 


 I believe these changes will cover all possible applications
 you have (hopefully).
Title: arc challenge
Post by: DParcon on January 23, 2004, 06:21:30 PM
Kate,

 The "ang" calculation in my previous post is not
 entirely correct (won't work in some instances).
 Also, in the calculation of "ang2", change (car e2)
 to (cadr e2) which is the pick point.
 
 The final calculation for "ang" is shown below and
 considers if each line is either in the 1st or 4th
 quadrant.

   
Code: [Select]


   (setq ang (if (or (and (< 0 ang1 (* pi 0.5))
                          (< (* pi 1.5) ang2 (* pi 2.0))
                     )
                     (and (< (* pi 1.5) ang1 (* pi 2.0))
                          (< 0 ang2 (* pi 0.5))
                     )  
                 )  
               (- (* (+ ang1 ang2) 0.5) pi)
               (* (+ ang1 ang2) 0.5)
             )
   )

   


 With these changes, the routine will now work provided
 the start point of the arc is located on the first line and
 on the same side where the line was picked.
Title: arc challenge
Post by: Keith™ on January 24, 2004, 01:42:43 AM
Ok Kate, (and others) here (http://www.theswamp.org/lilly.pond/public/TanArc.VLX) is the updated version.
It now works in each quadrant.

Test it out and give feedback as needed..
Title: arc challenge
Post by: CAB on January 24, 2004, 12:41:01 PM
Wow, what a brain teaser that was.. (or is)

But I think I got the LISP version working.

Keith, yours works but if I use crossing line as the distance reference
Your routine will pick it up as the line choice. Just an observation.

Don, I could not get the patches to work, maybe I inserted them wrong.
Didn't spend mush time trying to figure it out.

I'm not going to tell how nuch time I spent. :)

Code: [Select]
(defun c:tanarc2 (/ ang   ang1  ang2  bang cpt   dst   dst2  e1
 e2 flag  ipt   p1  p2 p3    p4    pt  pt1
 pt2 ipt   ptc   90deg 180deg      270deg  360deg
)
   ;; compute the delta angle between a1 & a
  (defun @delta (a1 a2)
   (cond
    ((> a1 (+ a2 pi)) (- (+ a2 pi pi) a1))
    ((> a2 (+ a1 pi)) (abs(- a2 a1 pi pi)))
    ((- a2 a1))
   )
  )
  ;; find the line angle closest to angle to picked point for the line selection
  (defun angequal (ang12 pkpt)
    (or (equal ang12 pkpt 0.1)
(and (< pkpt (+ ang12 90deg))
    (> pkpt (- ang12 90deg))
)
(and (> (+ ang12 90deg) 360deg)
    (> pkpt (- ang12 90deg))
    (< pkpt (- (* pi 2.5) ang12))
)
    )
  )


  ;; determine the first angle in a ccw direction
  (defun startang ()
    (cond
      ((equal (+ ang1 ang) ang2 0.1) ang1)
      ((equal (+ ang2 ang) ang1 0.1) ang2)
      ((< (+ ang1 ang) ang2) ang2)
      (t ang1)
    )
  )

  (prompt "Pick 2 Lines, Arc Start Point First..")
  (setvar "osmode" 176)
  (setq e1     (entsel "\nPick first line: ")
e2     (entsel "\nPick second line: ")
pt     (getpoint "\nPick start point on line: ")
flag   nil
90deg  (* pi 0.5)
180deg pi
270deg (* pi 1.5)
360deg (* pi 2)
  )
  (setvar "osmode" 0)

  (and (and e1 e2 pt)
       (setq p1 (cdr (assoc 10 (entget (car e1)))))
       (setq p2 (cdr (assoc 11 (entget (car e1)))))
       (setq p3 (cdr (assoc 10 (entget (car e2)))))
       (setq p4 (cdr (assoc 11 (entget (car e2)))))
       (setq ipt (inters p1 p2 p3 p4 nil))

       (if (angequal (angle p1 p2) (angle ipt (cadr e1)))
          (setq ang1 (angle p1 p2))
          (setq ang1 (angle p2 p1))
       )
       (if (angequal (angle p3 p4) (angle ipt (cadr e2)))
          (setq ang2 (angle p3 p4))
          (setq ang2 (angle p4 p3))
       )
       (setq dst (distance ipt pt))
       (setq pt1 (polar ipt ang1 dst))
       (setq pt2 (polar ipt ang2 dst))

       (setq ang (@delta ang1 ang2))
       (setq bang (/ ang 2))

       (setq dst2 (/ dst (cos bang)))
       (setq sang (startang))
       (setq cpt (polar ipt (+ bang sang) dst2))
       (setq ptc (polar cpt (+ pi (+ bang sang)) (distance cpt pt1)))
       (setq flag t)
  )
  (if flag
    (command "_.arc" pt1 ptc pt2)
    (alert "User Error")
  )
 
  (princ)
)
(princ)
Title: arc challenge
Post by: Guest on January 29, 2004, 10:36:47 PM
"I need to draw an arc (or a circle), defined by two tangents and a point on the circle -- not a radius like TTR."

The way that I would draw that is:

1.  Locate the 2nd point at the same distance from the vertex by using  Circle, Radius

2.  Draw the arc using the Start, End, Direction option

3.  Delete construction and trim as needed  

Odon
Title: arc challenge
Post by: Keith™ on January 29, 2004, 11:38:29 PM
Example my man .... we need an example ....
Title: arc challenge
Post by: Kate M on January 30, 2004, 09:14:27 AM
Quote
1. Locate the 2nd point at the same distance from the vertex by using Circle, Radius

The problem was that I didn't *know* the radius...just a start or end point and the two tangents.
Title: arc challenge
Post by: daron on January 30, 2004, 09:29:21 AM
I think guest was trying to take over your thread Kate. Should I move him to his own thread?
Title: arc challenge
Post by: Kate M on January 30, 2004, 09:45:18 AM
No, I think he was quoting my first post.
Title: arc challenge
Post by: SMadsen on January 30, 2004, 10:08:32 AM
Quote from: Kate M
Quote
1. Locate the 2nd point at the same distance from the vertex by using Circle, Radius

The problem was that I didn't *know* the radius...just a start or end point and the two tangents.

This is how I would draw it, too. You don't need the radius but you do need two points: the intersection point and the start point:

(http://theswamp.org/lilly.pond/public/drawarc.jpg)

Command: ARC
Specify start point of arc or
: [pick start point]
Specify second point of arc or [Center/End]: End
Specify end point of arc: [pick end point]
Specify center point of arc or [Angle/Direction/Radius]: Direction
Specify tangent direction for the start point of arc: [pick a point in the direction, e.g. intersection point]
Title: arc challenge
Post by: CAB on January 31, 2004, 02:27:32 PM
Never used Direction before. It simplifys things a bit.

Here is my code modified to use the direction method.

Code: [Select]
(defun c:tanarc2 (/ ang   ang1  ang2  bang cpt   dst   dst2  e1
 e2 flag  ipt   p1  p2 p3    p4    pt  pt1
 pt2 ipt   ptc   90deg 180deg      270deg  360deg
)
  ;; find the line angle closest to angle to picked point for the line selection
  (defun angequal (ang12 pkpt)
    (or (equal ang12 pkpt 0.1)
(and (< pkpt (+ ang12 90deg))
    (> pkpt (- ang12 90deg))
)
(and (> (+ ang12 90deg) 360deg)
    (> pkpt (- ang12 90deg))
    (< pkpt (- (* pi 2.5) ang12))
)
    )
  )



  (prompt "Pick 2 Lines, Arc Start Point First..")
  (setvar "osmode" 176)
  (setq e1     (entsel "\nPick first line: ")
e2     (entsel "\nPick second line: ")
pt     (getpoint "\nPick start point on line: ")
flag   nil
90deg  (* pi 0.5)
180deg pi
270deg (* pi 1.5)
360deg (* pi 2)
  )
  (setvar "osmode" 0)

  (and (and e1 e2 pt)
       (setq p1 (cdr (assoc 10 (entget (car e1)))))
       (setq p2 (cdr (assoc 11 (entget (car e1)))))
       (setq p3 (cdr (assoc 10 (entget (car e2)))))
       (setq p4 (cdr (assoc 11 (entget (car e2)))))
       (setq ipt (inters p1 p2 p3 p4 nil))

       (if (angequal (angle p1 p2) (angle ipt (cadr e1)))
          (setq ang1 (angle p1 p2))
          (setq ang1 (angle p2 p1))
       )
       (if (angequal (angle p3 p4) (angle ipt (cadr e2)))
          (setq ang2 (angle p3 p4))
          (setq ang2 (angle p4 p3))
       )
       (setq dst (distance ipt pt))
       (setq pt1 (polar ipt ang1 dst))
       (setq pt2 (polar ipt ang2 dst))

       (setq flag t)
  )
  (if flag
    (command "_.arc" pt1 "en" pt2 "d" ipt)
    (alert "User Error")
  )

  (princ)
)
(princ)
Title: arc challenge
Post by: Kate M on February 02, 2004, 09:28:32 AM
Huh...I'd tried direction before, but I must not have been picking the right start tangent or something, because it never came out quite right...works now, though. Learn something new every day, right? :-) Thanks for all the help!!!