### Tangential arc between two circles

JR
Joachim Röttinger
Fri, Jan 7, 2022 5:01 PM

that perfectly worked, thank you so much.

-----Ursprüngliche Nachricht-----
Gesendet: Freitag, 7. Januar 2022 16:23
Betreff: [OpenSCAD] Re: Tangential arc between two circles

Note that you can simplify your code somewhat by seeking coordinate-free solutions.  For example, distance between P1 and P2 is norm(P1-P2), in 2D or 3D (or any dimension, actually).  I played around with the tangent arcs problem and arrived at this, which appears to work, including in the case in your example:

function unit(v) = v/norm(v);

function circle_intersection(c1,r1,c2,r2) =
let(
d = norm(c2-c1),
a = (c2-c1)/d,
b = [-a.y,a.x],
L = (r1^2-r2^2+d^2)/2/d,
hsqr = r1^2-L^2
)
hsqr<0 ? []
: let(h=sqrt(hsqr))
[La+hb+c1, La-hb+c1];

// Returns list of two arc parameters: [center, start_pt, end_pt] function circle_arc(c1,r1,c2,r2,R) =
assert( 2R > r1+r2+norm(c1-c2), "Specified arc radius, R, is too small.  The arc does not exist.")
let(
R1 = R-r1,
R2 = R-r2,
Mlist = circle_intersection(c1,R1,c2,R2)
)
[for(M=Mlist) [M, c1+r1
unit(c1-M), c2+r2*unit(c2-M)]];

On Fri, Jan 7, 2022 at 8:34 AM Adrian Mariano avm4@cornell.edu wrote:

I dug into the math a bit more.  I think that yes, the problem is
round-off error.  In the  referenced math you'll note that they don't
compute the final answer as the intersection of two circles, and
neither should you.  Just a slight error in the radius and you go from
a single (tangent) intersection to non-intersecting.  Instead you
should be computing this, as shown in the web site, as the
intersection of the line from M to M1 with circle 1, and then same for
circle 2.

On Fri, Jan 7, 2022 at 8:30 AM Joachim Röttinger joe@joecool.de wrote:

Yes, P1 and P2 have only one intersection point. Function getIntersectionPointsOfTwoCircles2D should return the same point twice.
The circle should intersect and not be inside as the mathematical formulas are correct.
If I take C2 = [50, 0]; it works

-----Ursprüngliche Nachricht-----
Gesendet: Freitag, 7. Januar 2022 14:21
Betreff: [OpenSCAD] Re: Tangential arc between two circles

Your two circles are tangent, with one of them inside the other one.
There is only one intersection point, and the notion of the "tangent arcs" makes no sense in this case.

On Fri, Jan 7, 2022 at 7:31 AM Joachim Röttinger joe@joecool.de wrote:

Hi, I’m trying to write a module that draws an tangential arc between two circles (based on https://www.frassek.org/2d-mathe/kreise-verbinden/).

In principle it works but there are situations where it does not.

The sample code below echos a nan when P2 has been calculated. My assumption is that the issue is based on a loose of precision after calculation of point M.

Can anybody give me a hint how to solve this. Thank you in advance.

\$fa = 0.01;

\$fs = 0.01;

C1 = [0, 0];

r1 = 20;

C2 = [50, 50];

r2 = 2.5;

R = 90;

test(C1, r1, C2, r2, R);

module test(C1, r1, C2, r2, R) {

`````` R1 = R - r1;

R2 = R - r2;

M = getIntersectionPointsOfTwoCircles2D(C1, R1, C2, R2)[0];

P1 = getIntersectionPointsOfTwoCircles2D(C1, r1, M, R)[0];

P2 = getIntersectionPointsOfTwoCircles2D(C2, r2, M, R)[0];

echo(M, P1, P2);

translate(C1) circle(r=r1);

translate(C2) circle(r=r2);

color("Cyan") polygon(points = [P1, P2, M]);

color("Blue") translate([0, 0, -2]) circleWithCenter2D(r=R,
``````

C=M);

`````` polygonWithRadiusBetweenTwoPoints2D(P1, P2, M, r=R);
``````

}

module polygonWithRadiusBetweenTwoPoints2D (P1, P2, C, r=1) {

`````` startAngle = getAngleBetweenTwoPoints2D(C, P1);

endAngle = startAngle + getAngleBetweenThreePoints2D(P1, P2,
``````

C);

`````` angles=[ for (i = [startAngle:endAngle-1]) i ];

coords=[ for (j=concat(angles, [endAngle])) [r*cos(j),
``````

r*sin(j)] ];

`````` translate(C) polygon(coords);
``````

}

module circleWithCenter2D(r=1, d, C) {

`````` translate(C) circle(r=r);
``````

}

`````` translate(pt)

rotate(a,v)

translate(-pt)

children();
``````

}

// getDistanceBetweenTwoPoints2D

// returns the distance between 2 points

// P1: point 1

// P2: point 2

function getDistanceBetweenTwoPoints2D(P1, P2) =

`````` let(x1=P1[0], y1=P1[1], x2=P2[0], y2=P2[1])

sqrt((x1 - x2)^2 + (y1 - y2)^2);
``````

// getAngleBetweenThreePoints2D

// returns the angle between 3 points

// P1: point 1

// P2: point 2

// C: center point at angle

function getAngleBetweenThreePoints2D(P1, P2, C) =

`````` let(x1=P1[0], y1=P1[1], x2=P2[0], y2=P2[1], xC=C[0], yC=C[1])

atan2(y2 - yC, x2 - xC) - atan2(y1 - yC, x1 - xC);
``````

// getAngleBetweenTwoPoints2D

// returns the angle between 2 points

// P1: point 1

// P2: point 2

function getAngleBetweenTwoPoints2D(P1, P2) =

`````` let(x1=P1[0], y1=P1[1], x2=P2[0], y2=P2[1])

atan2(y2 - y1, x2 - x1);
``````

// getIntersectionPointsOfTwoCircles2D

// returns 2 possible intersection points of 2 circles

// C1: center of circle 1

// r1: radius of circle 1

// C2: center of circle 2

// r2: radius of circle 2

function getIntersectionPointsOfTwoCircles2D(C1, r1, C2, r2) =

`````` let(

x1=C1[0], y1=C1[1], x2=C2[0], y2=C2[1],

d=sqrt((x2-x1)^2 + (y2-y1)^2),

a=(r1^2-r2^2+d^2)/(2*d),

h=sqrt(r1^2-a^2),

x3=x1+a*(x2-x1)/d,

y3=y1+a*(y2-y1)/d,

x4=x3+h*(y2-y1)/d,

y4=y3-h*(x2-x1)/d,

x5=x3-h*(y2-y1)/d,

y5=y3+h*(x2-x1)/d

) [[x4, y4], [x5, y5]];
``````

To unsubscribe send an email to discuss-leave@lists.openscad.org

To unsubscribe send an email to discuss-leave@lists.openscad.org

To unsubscribe send an email to discuss-leave@lists.openscad.org

To unsubscribe send an email to discuss-leave@lists.openscad.org

M
MichaelAtOz
Sat, Jan 8, 2022 6:44 AM

Note that circle() does not take a Boolean, in 4 places. That now generates warnings.

Also an extra comma in the bottom let().

From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com]
Sent: Sat, 8 Jan 2022 03:21
Subject: [OpenSCAD] Re: Tangential arc between two circles

try this animation

--
This email has been checked for viruses by AVG.
https://www.avg.com

Note that circle() does not take a Boolean, in 4 places. That now generates warnings. Also an extra comma in the bottom let(). _____ From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com] Sent: Sat, 8 Jan 2022 03:21 To: OpenSCAD general discussion Subject: [OpenSCAD] Re: Tangential arc between two circles try this animation -- This email has been checked for viruses by AVG. https://www.avg.com
SP
Sanjeev Prabhakar
Sat, Jan 8, 2022 7:20 AM

I am using openSCAD 2021.09.12 and it not showing any errors or warnings

On Sat, 8 Jan 2022, 12:15 MichaelAtOz, oz.at.michael@gmail.com wrote:

Note that circle() does not take a Boolean, in 4 places. That now
generates warnings.

Also an extra comma

Thanks for your comments I am using openSCAD 2021.09.12 and it not showing any errors or warnings On Sat, 8 Jan 2022, 12:15 MichaelAtOz, <oz.at.michael@gmail.com> wrote: > Note that circle() does not take a Boolean, in 4 places. That now > generates warnings. > > Also an extra comma >
M
MichaelAtOz
Sat, Jan 8, 2022 9:27 AM

Hmmm, don't know why.

From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com]
Sent: Sat, 8 Jan 2022 18:20
Subject: [OpenSCAD] Re: Tangential arc between two circles

I am using openSCAD 2021.09.12 and it not showing any errors or warnings

On Sat, 8 Jan 2022, 12:15 MichaelAtOz, oz.at.michael@gmail.com wrote:

Note that circle() does not take a Boolean, in 4 places. That now generates warnings.

Also an extra comma

--
This email has been checked for viruses by AVG.
https://www.avg.com

Hmmm, don't know why. _____ From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com] Sent: Sat, 8 Jan 2022 18:20 To: OpenSCAD general discussion Subject: [OpenSCAD] Re: Tangential arc between two circles Thanks for your comments I am using openSCAD 2021.09.12 and it not showing any errors or warnings On Sat, 8 Jan 2022, 12:15 MichaelAtOz, <oz.at.michael@gmail.com> wrote: Note that circle() does not take a Boolean, in 4 places. That now generates warnings. Also an extra comma -- This email has been checked for viruses by AVG. https://www.avg.com
SP
Sanjeev Prabhakar
Sat, Jan 8, 2022 9:50 AM

Remove true from line number 9,10,17,18
Then there is no error

On Sat, 8 Jan 2022, 14:58 MichaelAtOz, oz.at.michael@gmail.com wrote:

Hmmm, don't know why.

From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com]
Sent: Sat, 8 Jan 2022 18:20
Subject: [OpenSCAD] Re: Tangential arc between two circles

I am using openSCAD 2021.09.12 and it not showing any errors or warnings

On Sat, 8 Jan 2022, 12:15 MichaelAtOz, oz.at.michael@gmail.com wrote:

Note that circle() does not take a Boolean, in 4 places. That now
generates warnings.

Also an extra comma

To unsubscribe send an email to discuss-leave@lists.openscad.org

Ah, just downloaded the Jan 2021 version Remove true from line number 9,10,17,18 Then there is no error On Sat, 8 Jan 2022, 14:58 MichaelAtOz, <oz.at.michael@gmail.com> wrote: > Hmmm, don't know why. > > > > > ------------------------------ > > *From:* Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com] > *Sent:* Sat, 8 Jan 2022 18:20 > *To:* OpenSCAD general discussion > *Subject:* [OpenSCAD] Re: Tangential arc between two circles > > > > Thanks for your comments > > I am using openSCAD 2021.09.12 and it not showing any errors or warnings > > > > On Sat, 8 Jan 2022, 12:15 MichaelAtOz, <oz.at.michael@gmail.com> wrote: > > Note that circle() does not take a Boolean, in 4 places. That now > generates warnings. > > Also an extra comma > > > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
M
MichaelAtOz
Sat, Jan 8, 2022 11:26 AM

I am using openSCAD 2021.09.12 and it not showing any errors or warnings

Something to check against a recent snapshot.

From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com]
Sent: Sat, 8 Jan 2022 20:51
Subject: [OpenSCAD] Re: Tangential arc between two circles

Remove true from line number 9,10,17,18

Then there is no error

On Sat, 8 Jan 2022, 14:58 MichaelAtOz, oz.at.michael@gmail.com wrote:

Hmmm, don't know why.

From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com]
Sent: Sat, 8 Jan 2022 18:20
Subject: [OpenSCAD] Re: Tangential arc between two circles

I am using openSCAD 2021.09.12 and it not showing any errors or warnings

On Sat, 8 Jan 2022, 12:15 MichaelAtOz, oz.at.michael@gmail.com wrote:

Note that circle() does not take a Boolean, in 4 places. That now generates warnings.

Also an extra comma

To unsubscribe send an email to discuss-leave@lists.openscad.org

--
This email has been checked for viruses by AVG.
https://www.avg.com

> I am using openSCAD 2021.09.12 and it not showing any errors or warnings Something to check against a recent snapshot. _____ From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com] Sent: Sat, 8 Jan 2022 20:51 To: OpenSCAD general discussion Subject: [OpenSCAD] Re: Tangential arc between two circles Ah, just downloaded the Jan 2021 version Remove true from line number 9,10,17,18 Then there is no error On Sat, 8 Jan 2022, 14:58 MichaelAtOz, <oz.at.michael@gmail.com> wrote: Hmmm, don't know why. _____ From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com] Sent: Sat, 8 Jan 2022 18:20 To: OpenSCAD general discussion Subject: [OpenSCAD] Re: Tangential arc between two circles Thanks for your comments I am using openSCAD 2021.09.12 and it not showing any errors or warnings On Sat, 8 Jan 2022, 12:15 MichaelAtOz, <oz.at.michael@gmail.com> wrote: Note that circle() does not take a Boolean, in 4 places. That now generates warnings. Also an extra comma _______________________________________________ OpenSCAD mailing list To unsubscribe send an email to discuss-leave@lists.openscad.org -- This email has been checked for viruses by AVG. https://www.avg.com
G
Fri, Jan 14, 2022 3:37 AM

I have this weird behaviour of flipping the angles.
I've not yet been able to pin-point where the issue is?

[image: image.png]

[image: image.png]

//
// https://www.frassek.org/2d-mathe/kreise-verbinden/
//
// \$t = animation step
\$fn=40;
cx1=0; // circle 1
cy1=0;
cr1=20;
//cx2=5+sin(\$t*360)*17; // circle 2
cx2=50;
cy2=50;
cr2=2.5;

// do we have valid values

d12=sqrt( (cx1-cx2)^2+(cy1-cy2)^2 ); // distance between circles
echo("distance between circles=",d12);
testR=(cr1+cr2+d12)/2; //
assert(rt > testR, concat("Tangent radius not big enough! Needs to be
larger than:",str(testR)));

function rm(theta)=[[cos(theta),sin(theta)],[-sin(theta),cos(theta)]];

function ang(x,y)=
x>=0&&y>=0?atan(y/x):x<0&&y>=0?180-abs(atan(y/x)):x<0&&y<0?180+abs(atan(y/x)):360-abs(atan(y/x));

function
cir(r,p=[0,0],s=50)=[for(i=[0:360/s:360-360/s])[p.x+rcos(i),p.y+rsin(i)]];

module p_line(path,size=.5){
for(i=[0:len(path)-1])
let(p0=path[i],p1=i<len(path)-1?path[i+1]:path[0])

``````hull(){
translate(p0)circle(size/2);
translate(p1)circle(size/2);}}
``````

module p_lineo(path,size=.5){
for(i=[0:len(path)-2])
let(p0=path[i],p1=path[i+1])

``````hull(){
translate(p0)circle(size/2);
translate(p1)circle(size/2);}}
``````

function

function 2cir_tarc(r1,r2,cp1,cp2,r)=
let(
l1=norm(cp2-cp1),
l2=r-r1,
l3=r-r2,
x=(l2^2-l3^2+l1^2)/(2l1),
h=sqrt(l2^2-x^2),
v1=cp2-cp1,u1=v1/norm(v1),
p0=cp1+u1
x,
cp3=p0-u1hrm(90),
v2=cp2-cp3,u2=v2/norm(v2),
v3=cp1-cp3,u3=v3/norm(v3),
ang1=ang(u2.x,u2.y),
ang2=ang(u3.x,u3.y)
)
arc(r,ang1,ang2,cp3);

arc=2cir_tarc(cr1,cr2,[cx1,cy1],[cx2,cy2],rt);
arc2=2cir_tarc(cr2,cr1,[cx2,cy2],[cx1,cy1],rt);

color("cyan") p_lineo(arc,.2);
color("green") p_lineo(arc2,.2);
p_line(cir(cr1,[cx1,cy1]),.2);
p_line(cir(cr2,[cx2,cy2]),.2);

On Sat, Jan 8, 2022 at 6:26 AM MichaelAtOz oz.at.michael@gmail.com wrote:

I am using openSCAD 2021.09.12 and it not showing any errors or warnings

Something to check against a recent snapshot.

From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com]
Sent: Sat, 8 Jan 2022 20:51
Subject: [OpenSCAD] Re: Tangential arc between two circles

Remove true from line number 9,10,17,18

Then there is no error

On Sat, 8 Jan 2022, 14:58 MichaelAtOz, oz.at.michael@gmail.com wrote:

Hmmm, don't know why.

From: Sanjeev Prabhakar [mailto:sprabhakar2006@gmail.com]
Sent: Sat, 8 Jan 2022 18:20
Subject: [OpenSCAD] Re: Tangential arc between two circles

I am using openSCAD 2021.09.12 and it not showing any errors or warnings

On Sat, 8 Jan 2022, 12:15 MichaelAtOz, oz.at.michael@gmail.com wrote:

Note that circle() does not take a Boolean, in 4 places. That now
generates warnings.

Also an extra comma