TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: David Bethel on April 07, 2013, 11:16:16 AM

Title: Fillet any 2 intersecting lines
Post by: David Bethel on April 07, 2013, 11:16:16 AM
I've searched pretty hard for this :

In plain Autolisp : To calculate the ARC data to fillet 2 intersecting LINEs regardless of their UCS, so long as they intersect ( 3D or 2D ) without ( command )

Known values :
(4) LINE endpoints ( WCS )
(1) Intersecting point ( inters p1 p2 p3 p4 nil )
Fillet radius  ( ie 1.0 )

These 2 lines intersect @ 3,3,4

Code: [Select]
(entmake '((0 . "LINE")(10 3.69631915 2.65184043 4.69631915)(11 5 2 6)))
(entmake '((0 . "LINE")(10 1 1 0)(11 2.36080723 2.36080723 2.72161446)))


To chamfer them would be pretty easy ( Find point r units from the intersecting point )

Fillet is proving to be a bit more challenging.

Any thoughts or thread referrals ?  -David
Title: Re: Fillet any 2 intersecting lines
Post by: GP on April 07, 2013, 01:42:46 PM
A proposal with GEOMCAL, pending VLisp

** DATA  **
(setq a1 (list 3.69631915 2.65184043 4.69631915))
(setq a2 (list 5 2 6))
(setq b1 (list 1 1 0))
(setq b2 (list 2.36080723 2.36080723 2.72161446))
(setq c (inters a1 a2 b1 b2 nil))
Fillet radius = 1.0


Code: [Select]
(cal "a3=pld(c,a1,1.0)")
(cal "b3=pld(c,b1,1.0)")
(cal "pm=plt(a3,b3,0.5)")
(cal "d1=dpl(pm,c,a1)")
(setq d2 (distance pm c))
(setq d3 (sqrt (- (expt d2 2) (expt d1 2))))
(setq d (/ d3 d1))
(setq dc (sqrt (+ (expt d 2) 1.0)))
 
;****  ARC  ****

;p1 = start
(cal "p1=pld(c,a1,d)")

;p2 = end
(cal "p2=pld(c,B1,d)")

;pc = center
(cal "pc=pld(c,pm,dc)")
Title: Re: Fillet any 2 intersecting lines
Post by: David Bethel on April 07, 2013, 03:06:19 PM
That looks to be interesting !  I'll dig into it and see what I can do.

Thanks!  -David
Title: Re: Fillet any 2 intersecting lines
Post by: Lee Mac on April 07, 2013, 06:34:43 PM
Nice solution GP, using the triangle similarity - the 'cal' functions save a lot of code :-)

Here is an alternative solution, though not quite as elegant:
Code: [Select]
;; Fillet  -  Lee Mac
;; p1,p2: WCS points defining 1st Line
;; p3,p4: WCS points defining 2nd Line
;;    rd: Fillet radius

(defun fillet ( p1 p2 p3 p4 rd / a1 a2 c1 c2 cn di ip zv )
    (foreach x'(p1 p2 p3 p4)
        (set x (trans (eval x) 0 1))
    )
    (if (setq ip (inters p1 p2 p3 p4 nil))
        (progn
            (if (equal p1 ip 1e-8) (setq p1 p2))
            (if (equal p3 ip 1e-8) (setq p3 p4))
            (setq zv (trans (v^v (mapcar '- p1 ip) (mapcar '- p3 ip)) 1 0 t)
                  ip (trans ip 1 zv)
                  p1 (trans p1 1 zv)
                  p3 (trans p3 1 zv)
                  a1 (angle ip p1)
                  a2 (angle ip p3)
                  di (abs (/ rd (tan (/ (- a1 a2) 2.0))))
                  c1 (polar ip a1 di)
                  c2 (polar ip a2 di)
                  cn (inters c1 (polar c1 (+ a1 (/ pi 2.0)) 1.0)
                             c2 (polar c2 (+ a2 (/ pi 2.0)) 1.0) nil
                     )
            )
            (if (LM:Clockwise-p c1 ip c2)
                (mapcar 'set '(c1 c2) (list c2 c1))
            )
            (entmakex
                (list
                   '(0 . "ARC")
                    (cons 010 cn)
                    (cons 040 rd)
                    (cons 050 (angle cn c1))
                    (cons 051 (angle cn c2))
                    (cons 210 zv)
                )
            )
        )
    )
)

;; Clockwise-p - Lee Mac
;; Returns T if p1,p2,p3 are clockwise oriented

(defun LM:Clockwise-p ( p1 p2 p3 )
    (<  (* (- (car  p2) (car  p1)) (- (cadr p3) (cadr p1)))
        (* (- (cadr p2) (cadr p1)) (- (car  p3) (car  p1)))
    )
)

;; Tangent  -  Lee Mac
;; Args: x - real

(defun tan ( x )
    (if (not (equal 0.0 (cos x) 1e-10))
        (/ (sin x) (cos x))
    )
)

;; Vector Cross Product  -  Lee Mac
;; Args: u,v - vectors in R^3

(defun v^v ( u v )
    (list
        (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
        (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
        (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
    )
)

Test program:
Code: [Select]
(defun c:test ( / l1 l2 rd )
    (if
        (and
            (princ "\nSelect 1st Line: ")
            (setq l1 (ssget "_+.:E:S" '((0 . "LINE"))))
            (princ "\nSelect 2nd Line: ")
            (setq l2 (ssget "_+.:E:S" '((0 . "LINE"))))
            (setq rd (getdist "\nFillet Radius: "))
            (setq l1 (entget (ssname l1 0))
                  l2 (entget (ssname l2 0))
            )
        )
        (fillet
            (cdr (assoc 10 l1))
            (cdr (assoc 11 l1))
            (cdr (assoc 10 l2))
            (cdr (assoc 11 l2))
            rd
        )
    )
    (princ)
)
Title: Re: Fillet any 2 intersecting lines
Post by: owenwengerd on April 07, 2013, 09:08:09 PM
Any thoughts or thread referrals ?

If you can use (command) look at 3DFILLET.lsp from my lisp freebies page (http://www.manusoft.com/software/freebies/lisp.html) (written almost 20 years ago -- yikes!).
Title: Re: Fillet any 2 intersecting lines
Post by: David Bethel on April 08, 2013, 08:37:23 AM
Thanks to all!

I test them out this week an post the results ( irregular shaped polygon glass panels with radius corners )

-David
Title: Re: Fillet any 2 intersecting lines
Post by: Lee Mac on April 08, 2013, 09:29:22 AM
You're very welcome David, let us know how you get on! :-)
Title: Re: Fillet any 2 intersecting lines
Post by: GP on April 08, 2013, 09:31:34 AM
@David
You're welcome


@Lee
I love "cal" :D
I often use the "cal" function if there is not a large amount of data to be calculated, otherwise it becomes very slow.
Title: Re: Fillet any 2 intersecting lines
Post by: Lee Mac on April 08, 2013, 09:57:46 AM
@Lee
I love "cal" :D
I often use the "cal" function if there is not a large amount of data to be calculated, otherwise it becomes very slow.

Its all about choosing the right tool for the job :-)
There are certainly times when the concision of code and readiness of a solution far outweigh the need for raw program performance.
Title: Re: Fillet any 2 intersecting lines
Post by: Beekee on October 01, 2015, 08:19:20 AM
Hello all,
Hi @Lee,
first of all, thank you for your routine.... I dared to use in my routine as it is, but I admit I don't understand that much...
But only problem is that for some situations it returns the arc with negative Z normal vector (-1). As I said, i'm not following these vector operations... so it is something what can be fixed or I don't know... flatten works on it...

And the second.. that not problem. I needed to get endpoints from your sub. After some testing and experiments i found something that works... but it's somehow upside down to me... Not sure why/if that's correct.. but it works :)
Thanks you in advance.
Title: Re: Fillet any 2 intersecting lines
Post by: Lee Mac on October 01, 2015, 01:59:05 PM
Hi Beekee,

The normal vector is calculated using the cross product of the vectors spanning from the intersection of the two lines to each opposite line end point. Therefore, the direction of the normal vector will be consistent with the right-hand rule (https://en.wikipedia.org/wiki/Cross_product#Definition) and will depend on the order in which the line end points are passed to the function.

Lee