Author Topic: Fillet any 2 intersecting lines  (Read 5967 times)

0 Members and 1 Guest are viewing this topic.

David Bethel

  • Swamp Rat
  • Posts: 656
Fillet any 2 intersecting lines
« 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
R12 Dos - A2K

GP

  • Newt
  • Posts: 83
  • Vercelli, Italy
Re: Fillet any 2 intersecting lines
« Reply #1 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)")

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Fillet any 2 intersecting lines
« Reply #2 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
R12 Dos - A2K

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Fillet any 2 intersecting lines
« Reply #3 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)
)

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Fillet any 2 intersecting lines
« Reply #4 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 (written almost 20 years ago -- yikes!).

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Fillet any 2 intersecting lines
« Reply #5 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
R12 Dos - A2K

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Fillet any 2 intersecting lines
« Reply #6 on: April 08, 2013, 09:29:22 AM »
You're very welcome David, let us know how you get on! :-)

GP

  • Newt
  • Posts: 83
  • Vercelli, Italy
Re: Fillet any 2 intersecting lines
« Reply #7 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.

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Fillet any 2 intersecting lines
« Reply #8 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.

Beekee

  • Mosquito
  • Posts: 19
Re: Fillet any 2 intersecting lines
« Reply #9 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.
« Last Edit: October 01, 2015, 08:33:43 AM by Beekee »

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Fillet any 2 intersecting lines
« Reply #10 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 and will depend on the order in which the line end points are passed to the function.

Lee