Given two lines, create two tangent arcs that connect them, with the connections beeing tangent too.

Given two lines, create two tangent arcs that connect them, with the connections beeing tangent too.

aitorm
Advocate Advocate
6,853 Views
54 Replies
Message 1 of 55

Given two lines, create two tangent arcs that connect them, with the connections beeing tangent too.

aitorm
Advocate
Advocate

Hi there!

 

I usually face this situation where I need to connect two lines with a curve and I don't like the blend command because it is not a polyline and I don't like to transform a spline to a polyline because it is not accurate and simple.

 

The best would be to create two curves, connected to each other and the two lines and that are tangent to each other and to the lines.

 

Do you think it is possible to create a Lisp for that? I couldn't even imagine how to start. Thank you so much

Accepted solutions (1)
6,854 Views
54 Replies
Replies (54)
Message 2 of 55

john.uhden
Mentor
Mentor

@aitorm 

Can you provide us a picture of what you you are trying to create?
Do you want to specify the radii?

I might be able to understand circles, but arcs have beginnings and ends; what are the specs on those?

John F. Uhden

Message 3 of 55

hak_vz
Advisor
Advisor

a) Provide dwg sample with before and after  state.

 


@aitorm wrote:

..... I don't like to transform a spline to a polyline because it is not accurate and simple.


If you work with splines then creating whatever you want will be difficult since splines are generated  using fit points and internal calculations.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 4 of 55

aitorm
Advocate
Advocate

Thank you.

 

This is basically my input, two separated polylines with different inclination:

aitorm_4-1647772580556.png

 

 

And I need a lisp to create two arcs that join them like this (but leaving no constraints):

 

aitorm_1-1647772145312.png

aitorm_3-1647772289921.png

 

 

And then it would be cool if it converts the whole thing into a single polyline.

 

The aim is to get the simplest still smooth polyline.

 

I am attaching the file to test. Thank you so much.

 

 

Message 5 of 55

Sea-Haven
Mentor
Mentor

Its fairly straight forward even with no code, a decision needs to be made which end point to hold, then draw an arc from that end point, then just fillet for second arc all done. Now where is that arc from end of line sequence. May need to use Circle TTR and trim for second arc.

0 Likes
Message 6 of 55

leeminardi
Mentor
Mentor

@aitorm   as I understand your question you would like to create two arcs to connect two lines without modifying the end points of either line.  Is this correct?

 

For example, given two lines the center of a fillet is located on the line bisecting the angle formed by the two lines (green). If we are willing to modify the end point of one of the lines then the fillet radius RF would be determined by which line's endpoint is closest to the intersection of the bisector and a line perpendicular to the line.  For example, in the case shown below that would be point B.  

leeminardi_1-1647784786252.png

You seek to create two arcs to replace the single fillet arc with tangencies at all arc and line endpoints. There may be many solutions to this problem but I think they require one arc to have a radius greater than RF and the other smaller than RF.  You could arbitrarily  set one arc to 2 or 3 times RF (or something else within limits) and then have the program solve for the other radius and center point. For example, in the image below I set RA to about 3 times RF and solved for RB which is less than RF.

leeminardi_2-1647785448569.png

Is this what you want to do?

 

 

 

lee.minardi
Message 7 of 55

hak_vz
Advisor
Advisor

From my experience, it is hard to create code i.e algorithm that will produce polyline with arc and line segments as you request, that will look acceptable regarding smoothness of a curve and transition from arc to line.

Since you have to retain straight polyline endpoint you can do it easily:

  •  join straight polyline segments with a polyline 
  • offset this polyline some delta value
  • MOVE this joining polyline for desired distance to the position of straight curve segment
  • use command FILLET command to create arc segments on both side

You have to do it this way since for each arc segments there are two possible solutions for fillet and lisp code may have problem to find right one.

Here is a screencast that shows how to do it.

 

PS If your request is what @leeminardi  has shown in post #6, this can be done, but I'm not sure if this will create acceptable (smooth) result.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 8 of 55

aitorm
Advocate
Advocate

Great! This is exactly what I want! (but in a Lisp). Do you think it is possible?

0 Likes
Message 9 of 55

aitorm
Advocate
Advocate

Thank you. It is not exactly what I want, because I need the two arcs to coincide.

0 Likes
Message 10 of 55

calderg1000
Mentor
Mentor

Dear @aitorm 

The geometric solution for the problem of compound curves has a solution; see formulas.
It would not be very complicated to program them, but it is required to specify the input data.

Regards.

 

calderg1000_1-1647812972591.png

 

 

 

 

calderg1000_0-1647812901861.png

 


Carlos Calderon G
EESignature
>Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

Message 11 of 55

stevor
Collaborator
Collaborator

Draw an arc inside the line extensions, then an arc tangent to that arc.

It is called a bi-arc, code examples exist, and if there is interest, 

an autolisp may appear.

S
Message 12 of 55

aitorm
Advocate
Advocate

Thank you @stevor and @calderg1000 ; looks like you know what I want better than I do. I think it will be a very useful tool if created. 

0 Likes
Message 13 of 55

Kent1Cooper
Consultant
Consultant

I am reminded of a similar topic from some years back, but having found >the topic<, I see that the issue is not quite the same.  But maybe something about it could be helpful....

Kent Cooper, AIA
Message 14 of 55

leeminardi
Mentor
Mentor

@calderg1000 thanks for the link.  @stevor thanks for noting that it is called a "bi-arc".  That helped me find this link with a straightforward way to find point PM.  Once you have PM finding the centers of the two arcs is easy. The specific arcs you get is a function of the d1 (or d2) that you choose so some rule of thumb needs to be used to define it first.

 

@Kent1Cooper I'm sure you can do a much better job at writing the vlisp code than me.  Do you want to go for it? 😉

lee.minardi
Message 15 of 55

john.uhden
Mentor
Mentor

@leeminardi 

"than me I"

What, your vector voodoo can't beat Kent's (command)?

John F. Uhden

Message 16 of 55

leeminardi
Mentor
Mentor

@john.uhden I (me) wanted to give you a chance to exercise your role as grammar police officer extraordinaire!

 

As for the vector voodoo, I'm cool with that aspect of vlisp programming it's  getting the ends of a line segment of a polyline that I find a chore.  I'd like the user to pick a line (or polyline segment) near the end where the arc will start.  I then need to create a unit vector at that end with the correct "sense" (not to be confused with your definition of "direction").😉

lee.minardi
Message 17 of 55

john.uhden
Mentor
Mentor

@leeminardi 

My kids' Grammar was a stickler on grammar.

You wrote, "I'd like the user to pick a line (or polyline segment) near the end where the arc will start."

Might I suggest:

(setq pick (entsel "\nSelect a line or polyline near the desired end of where you desire the arc to start: "))

Maybe if I understood the question I wouldn't have to ask if the arc can start at the end of any segment or only at one end or the other of a polyline with multiple segments..

Umm, and since by definition arcs are drawn CCW, might you also need to ask which direction the arc should be drawn lest you end up with something like   C as opposed to C   ?  (Please pardon my pseudographics; I don't know how to write a reverse C, which is a lousy looking arc anyway.)

John F. Uhden

Message 18 of 55

leeminardi
Mentor
Mentor

I want the user to pick two lines and then have the code return the two ends of each line such that P1 is the end of the first line nearest the pick point and P1Other is the other end of the line.  Same for the second line.

lee.minardi
Message 19 of 55

leeminardi
Mentor
Mentor
Accepted solution

@aitorm   Here's a lisp program that I think will do what you want.  The user interface could be cleaned up a bit.  I have not tested it much and the value for d influences the radii of the arcs that are created. Let me know if you have any questions.

 

The program creates a single polyline and a point at the junction between the two arcs.  Depending on the value of "d" you will get different results.  For example, d = 2 yields:

leeminardi_0-1647886996315.png

Note that the transition point is "outside" the two lines. 

While for d = 4 you get:

leeminardi_1-1647887026096.png

 

; Calculates the bi-arc to create a single polyline from
; two lines.
; forumula from https://www.ryanjuckett.com/biarc-interpolation/
; L. Minardi 3/22/2022  v1 edited smooth factor input
;  v2-v4 improved user interface, 
;
; calculate unit vector from v1 to v2
(defun uvec (v1 v2 / s)
  (setq s (distance v1 v2))
  (setq s (mapcar '/ (mapcar '- v2 v1) (list s s s)))
)
;;; Compute the dot product of 2 vectors a and b
(defun dot (a b / dd)
  (setq dd (mapcar '* a b))
  (setq dd (+ (nth 0 dd) (nth 1 dd) (nth 2 dd)))
)					;end of dot

(defun c:biarc (/ p1 p1o p2 p2o qI t1 t2 d1 d2 v dd1 dd2 q1 q2 pm s)

(SETQ TP1 (entsel "\nSelect First Line near end: ")) ; implies which way 
(setq tpp1 (entget (car tp1))
	p1 (cdr (assoc 10 tpp1))
	p1o (cdr (assoc 11 tpp1))
	pp (cadr tp1)
)
(setq d1 (distance p1 pp) d2 (distance p1o pp) )
(if (> d1 d2)
    (setq temp p1 p1 p1o p1o temp)
)

(SETQ TP1 (entsel "\nSelect Second Line near end: ")) ; implies which way 
(setq tpp2 (entget (car tp1))
	p2 (cdr (assoc 10 tpp2))
	p2o (cdr (assoc 11 tpp2))
	pp (cadr tp1)
)
(setq d1 (distance p2 pp) d2 (distance p2o pp) )
(if (> d1 d2)
    (setq temp p2 p2 p2o p2o temp)
)

(setq s	(getreal "\nEnter smooth factor <4>: "))
(cond
  ((= s nil) (setq s 4.))
  ((= s 0) (progn (princ "0 is invalid. Smooth set to 4.") (setq s 4.)))
)
  (setq	qI (inters p1 p1o p2 p2o nil)
	d1 (/ (distance p1 qI) s)
	t1 (uvec p1o p1)
	t2 (uvec p2 p2o)
  )
  (setq v (mapcar '- p2 p1))
  (setq	d2 (/
	     (- (* 0.5 (dot v v)) (* d1 (dot v t1)))
	     (- (dot v t2) (* d1 (- (dot t1 t2) 1.)))
	   )
  )
  (setq	dd1 (/ d2 (+ d1 d2))
	dd2 (/ d1 (+ d1 d2))
  )
  (setq	q1 (mapcar '+ p1 (mapcar '* t1 (list d1 d1 d1)))
	q2 (mapcar '- p2 (mapcar '* t2 (list d2 d2 d2)))
  )
  (setq	pm (mapcar '+
		   (mapcar '* q1 (list dd1 dd1 dd1))
		   (mapcar '* q2 (list dd2 dd2 dd2))
	   )
  )
  (command "_point" "_non" pm)
  (command "_pline" "_non" p1o "_non" p1 "A" "_non" pm "_non" p2 "L" p2o
	   "")
  (princ)
)

 

 

 

 

P.S.  The vector Voo Doo is for @john.uhden 

 

lee.minardi
Message 20 of 55

ВeekeeCZ
Consultant
Consultant

Nice... just finish your d1 setting. It seems like it could be anything as long as it's 4.

 

d1 (getreal "\Enter smooth factor (4)")
)
(setq d1 (cond (d1) (4)))

(setq qI (inters p1 p1o p2 p2o nil)
d1 (/ (distance p1 qI) d1)