TeX - LaTeX Asked by user226320 on January 30, 2021
Is it possible to draw the attached picture?
My tried:
documentclass[tikz,border=2mm]{standalone}
usetikzlibrary{fit,backgrounds}
begin{document}
begin{tikzpicture}[cable/.style={circle, fill=cyan!70!black, minimum size=5mm, inner sep=0pt, outer sep=0pt}]
node[cable] (center) at (0,0) {};
foreach i in {0,1,...,6}
node[cable] (1-i) at (60*i:5mm) {};
fill[red!20] circle (0.26);
end{tikzpicture}
end{document}
Using Asymptote
, you can start with something like this:
// circpacking.asy
//
// run
// asy circpacking.asy
//
// to get a standalone circpacking.pdf
//
settings.outformat="pdf";
size(6cm);
pen linePen=darkblue+0.7bp;
pair o=(0.47,0);
real r0=0.2;
pair[] Ok={( 0.53, 0.48),(-0.32, 0.20),( 0.31,-0.55),( 0.78,-0.24),( 0.82, 0.12),};
real[] rk={0.28,0.62,0.37,0.19,0.17,};
int n=Ok.length;
real sq=0.08;
guide g0=circle(o,r0);
guide[] gk; gk.cyclic=true;
transform tr;
for(int i=0;i<n;++i){
tr=shift(sq*(o-Ok[i]));
Ok[i]=tr*Ok[i];
gk.push(circle(Ok[i],rk[i]));
}
guide trunc(int k){
pair[] xp;
guide q;
xp.append(intersectionpoints(gk[k],gk[k-1]));
xp.append(intersectionpoints(gk[k],g0));
xp.append(intersectionpoints(gk[k],gk[k+1]));
q=xp[0]--xp[1]
&arc(Ok[k],xp[1],xp[4])--xp[5]
&arc(Ok[k],xp[5],xp[2])--xp[3]
&arc(Ok[k],xp[3],xp[0])&cycle;
tr=shift(sq*0.3*(Ok[k]-o));
q=tr*q;
return q;
}
guide trunc0(){
pair[] xp; guide q;
for(int i=0;i<n;++i){
xp.append(intersectionpoints(g0,gk[i]));
}
q=xp[0]--xp[1]
&arc(o,xp[1],xp[2])--xp[3]
&arc(o,xp[3],xp[4])--xp[5]
&arc(o,xp[5],xp[6])--xp[7]
&arc(o,xp[7],xp[9])--xp[8]
&arc(o,xp[8],xp[0])
&cycle;
return q;
}
for(int i=0;i<n;++i){
draw(trunc(i),linePen);
}
draw(trunc0(),linePen);
clip(box(o-2*r0*(1,1),o+2*r0*(1,1)));
The idea is, starting from a Steiner chain of kissing circles, move all the circles in a chain toward the surrounded circle, find all the intersections, cut straight the overlaps and slightly move all the truncated circles backwards in order to make some gaps.
Edit
And this is a translation of the above asymptote
code via .svg
format
to TikZ
by means of svg2tikz:
documentclass{article}
usepackage[utf8]{inputenc}
usepackage{tikz}
begin{document}
definecolor{c00003f}{RGB}{0,0,63}
def globalscale {1.000000}
begin{tikzpicture}[y=0.80pt, x=0.80pt, yscale=-globalscale, xscale=globalscale, inner sep=0pt, outer sep=0pt]
begin{scope}[cm={{0.99626,0.0,0.0,0.99626,(41.5276,138.898)}}]
path[draw=c00003f,line cap=round,line join=round,line width=0.562pt,miter limit=10.04] (121.8530,43.4044) -- (145.4980,24.3523) .. controls (152.8360,14.4281) and (157.1750,2.1513) .. (157.1750,-11.1389) .. controls (157.1750,-44.1405) and (130.4220,-70.8936) .. (97.4204,-70.8936) .. controls (70.8777,-70.8936) and (48.3770,-53.5876) .. (40.5863,-29.6438) -- (62.6986,37.4991) .. controls (65.5025,39.5043) and (68.4870,41.2732) .. (71.6231,42.7764) -- (109.1410,47.4744) .. controls (113.5770,46.5924) and (117.8350,45.2196) .. (121.8530,43.4044) -- cycle;
end{scope}
begin{scope}[cm={{0.99626,0.0,0.0,0.99626,(41.5276,138.898)}}]
path[draw=c00003f,line cap=round,line join=round,line width=0.562pt,miter limit=10.04] (58.6962,38.8146) -- (36.5965,-28.3310) .. controls (12.8622,-63.8082) and (-27.5709,-87.1681) .. (-73.4600,-87.1681) .. controls (-146.5380,-87.1681) and (-205.7790,-27.9268) .. (-205.7790,45.1511) .. controls (-205.7790,118.2290) and (-146.5380,177.4700) .. (-73.4600,177.4700) .. controls (-56.3476,177.4700) and (-39.9938,174.2220) .. (-24.9818,168.3080) -- (39.4559,114.1780) .. controls (41.2222,111.2950) and (42.8812,108.3390) .. (44.4273,105.3150) -- (58.8082,48.3489) .. controls (58.8334,47.2860) and (58.8461,46.2200) .. (58.8461,45.1511) .. controls (58.8461,43.0269) and (58.7960,40.9143) .. (58.6962,38.8146) -- cycle;
end{scope}
begin{scope}[cm={{0.99626,0.0,0.0,0.99626,(41.5276,138.898)}}]
path[draw=c00003f,line cap=round,line join=round,line width=0.562pt,miter limit=10.04] (42.4082,117.7020) -- (-22.0387,171.8220) .. controls (-24.4716,179.4210) and (-25.7851,187.5210) .. (-25.7851,195.9280) .. controls (-25.7851,239.5460) and (9.5744,274.9060) .. (53.1925,274.9060) .. controls (96.8107,274.9060) and (132.1700,239.5460) .. (132.1700,195.9280) .. controls (132.1700,187.5340) and (130.8610,179.4470) .. (128.4350,171.8580) -- (104.9390,136.2890) .. controls (101.9690,133.7100) and (98.8053,131.3500) .. (95.4719,129.2320) -- (53.3114,116.9720) .. controls (53.2718,116.9720) and (53.2322,116.9720) .. (53.1925,116.9720) .. controls (49.5343,116.9720) and (45.9342,117.2200) .. (42.4082,117.7020) -- cycle;
end{scope}
begin{scope}[cm={{0.99626,0.0,0.0,0.99626,(41.5276,138.898)}}]
path[draw=c00003f,line cap=round,line join=round,line width=0.562pt,miter limit=10.04] (107.1520,134.8290) -- (130.6250,170.4120) .. controls (135.8100,172.8190) and (141.5880,174.1620) .. (147.6790,174.1620) .. controls (170.0770,174.1620) and (188.2340,156.0050) .. (188.2340,133.6070) .. controls (188.2340,117.9240) and (179.3330,104.3210) .. (166.3070,97.5734) -- (137.4190,94.3609) .. controls (134.0410,95.2416) and (130.8340,96.5470) .. (127.8590,98.2167) -- (108.4510,123.2800) .. controls (107.5850,126.5770) and (107.1240,130.0380) .. (107.1240,133.6070) .. controls (107.1240,134.0160) and (107.1300,134.4230) .. (107.1520,134.8290) -- cycle;
end{scope}
begin{scope}[cm={{0.99626,0.0,0.0,0.99626,(41.5276,138.898)}}]
path[draw=c00003f,line cap=round,line join=round,line width=0.562pt,miter limit=10.04] (137.6100,92.6742) -- (166.4940,95.8951) .. controls (181.2740,91.3063) and (192.0080,77.5236) .. (192.0080,61.2340) .. controls (192.0080,41.1933) and (175.7620,24.9470) .. (155.7210,24.9470) .. controls (152.6640,24.9470) and (149.6950,25.3251) .. (146.8590,26.0369) -- (123.2120,45.0971) .. controls (121.3490,48.8433) and (120.1140,52.9571) .. (119.6460,57.3006) -- (129.6540,86.4646) .. controls (131.9970,88.8845) and (134.6740,90.9791) .. (137.6100,92.6742) -- cycle;
end{scope}
begin{scope}[cm={{0.99626,0.0,0.0,0.99626,(41.5276,138.898)}}]
path[draw=c00003f,line cap=round,line join=round,line width=0.562pt,miter limit=10.04] (108.8560,49.7248) -- (71.3386,45.0229) .. controls (68.2199,46.1067) and (65.2658,47.5420) .. (62.5235,49.2814) -- (48.1261,106.2530) .. controls (49.7824,109.1980) and (51.7779,111.9260) .. (54.0597,114.3850) -- (96.2278,126.6520) .. controls (100.0570,125.6470) and (103.6760,124.1230) .. (107.0050,122.1600) -- (126.4140,97.0975) .. controls (127.3320,93.8808) and (127.8820,90.5090) .. (128.0160,87.0304) -- (118.0060,57.8663) .. controls (115.3660,54.7351) and (112.2850,51.9889) .. (108.8560,49.7248) -- cycle;
end{scope}
end{tikzpicture}
end{document}
Answered by g.kov on January 30, 2021
Here is an automated solution. We define a command circlesqueeze
that takes two arguments, one optional. The required argument is a list of circles separated by commas. The command
circlesqueeze{1/-1/.5,0/-1/.85,.3/.5/.7,1.3/1.2/.6,1/0/.5}
inside a tikzpicture
will squeeze 5 circles. The syntax for each circle is x/y/r
where (x,y)
is the center and r
is the radius. So in the above example, the first circle is centered at (1,-1)
with radius .5
. The second is centered at (0,-1)
with radius .85
and so on. Units are centimeters.
The optional argument is the minimum space between circles. Default is .05cm
. Here is an example with the space reduced to .03cm
.
circlesqueeze[.03]{0/0/1,1/1/.5,0/1.5/.7,1.6/1.4/.25,1.6/0/.8,2/1/.5,1/2/.5}
If you want to change the line width
, it has to be done globally using the command lw
, initially set to .4
. You can change this with renewcommand
. You can use the clip
command to get a picture similar to your original. I approximated the centers and radii:
renewcommand{lw}{1}
begin{tikzpicture}[line width=lw]
clip (-4.5,-4.5) rectangle (6,5);
circlesqueeze[.1]{.2/0/3,2/5/3,-2.6/3/2.1,-3.7/-2.3/3.1,1.5/-4/2.2,6.4/0/4}
end{tikzpicture}
Here is the basic algorithm:
(m)
on the line connecting the two centers (the center axis), between the two circular arcs that will need to be modified, but closer to the center of the smaller circle so that the two flattened segments are the same length.(m)
.eps
) segment is drawn from a second intersection slightly farther from (m)
, then following the first pair of intersections, and reconnecting to the circle. This is a doubled line (white on the outside, black on the inside) to cover up any undesirable remnants of the original circle.Known issues:
Here is the code:
documentclass{article}
usepackage{tikz}
usetikzlibrary{intersections,calc}
usepackage{ifthen}
newcommand{eps}{.01} % arc-line connector length in cm
newcommand{lw}{.4} % line width. Be careful if defining locally.
newcommand{circlesqueeze}[2][.05]{
foreach xa/ya/ra in {#2}
{
draw (xa,ya) circle[radius=ra]; % draw all circles
}
foreach [var=xa, var=ya, var=ra, count=na] in {#2}
foreach [var=xb, var=yb, var=rb, count=nb] in {#2}
{
ifthenelse{na<nb} % compare each pair of circles once
{
pgfmathparse{#1+ra+rb-veclen(xb-xa,yb-ya)}
ifthenelse{lengthtest{pgfmathresult pt > 0 pt}} % if circles are too close
{
coordinate(c1) at (xa,ya); coordinate(c2) at (xb,yb); % circle centers
path[name path=line0] (c1)--(c2); % center axis
path[name path=circ1] (c1) circle[radius=ra];
path[name path=circ2] (c2) circle[radius=rb];
path[name intersections={of=line0 and circ1, by={i1}},
name intersections={of=line0 and circ2, by={i2}}];
coordinate (u12) at ($(c1)!1cm!(c2)-(c1)$); % unit vector from c1 to c2
path
let n1={max(ra,rb)}, n2={min(ra,rb)},
n3={(.5*n2/n1)*(ra>=rb)+(1-.5*n2/n1)*(ra<rb)} in % n3=.5 would be equally spaced. Otherwise, closer to smaller circle
coordinate (m) at ($n3*(i2)+{(1-n3)}*(i1)$);
path[name path=insideline1] % perpendicular to center axis
let p0=(u12),
p1=(m)
in (x1-ra*y0-#1*.5*x0,y1+ra*x0-#1*.5*y0)--(x1+ra*y0-#1*.5*x0,y1-ra*x0-#1*.5*y0);
path[name path=insideline2]
let p0=(u12),
p1=(m)
in (x1-ra*y0+#1*.5*x0,y1+ra*x0+#1*.5*y0)--(x1+ra*y0+#1*.5*x0,y1-ra*x0+#1*.5*y0);
path[name path=outsideline1] % a little farther apart
let p0=(u12),
p1=(m)
in (x1-ra*y0-#1*.5*x0-eps*x0,y1+ra*x0-#1*.5*y0-eps*y0)--(x1+ra*y0-#1*.5*x0-eps*x0,y1-ra*x0-#1*.5*y0-eps*y0);
path[name path=outsideline2]
let p0=(u12),
p1=(m)
in (x1-ra*y0+#1*.5*x0+eps*x0,y1+ra*x0+#1*.5*y0+eps*y0)--(x1+ra*y0+#1*.5*x0+eps*x0,y1-ra*x0+#1*.5*y0+eps*y0);
path[name intersections={of=circ1 and insideline1, by={a1,a2}}];
path[name intersections={of=circ1 and outsideline1, by={b1,b2}}];
path[name intersections={of=circ2 and insideline2, by={a3,a4}}];
path[name intersections={of=circ2 and outsideline2, by={b3,b4}}];
draw[white, line width=2*lw] % first circle
let p1=($(a1)-(c1)$),
p2=($(a2)-(c1)$),
n0= {ra}, % Radius
n1 = {atan2(y1,x1)}, % angle 1
n2 = {atan2(y2,x2)}, % angle 2
n3 = {n2+360*(n1-n2>180)-360*(n1-n2<-180)} % force shorter arc
in (a1) arc(n1:n3:n0);
draw[white, line width=2*lw] % second circle
let p1=($(a3)-(c2)$),
p2=($(a4)-(c2)$),
n0= {rb},
n1 = {atan2(y1,x1)},
n2 = {atan2(y2,x2)},
n3 = {n2+360*(n1-n2>180)-360*(n1-n2<-180)}
in (a3) arc(n1:n3:n0);
draw[line join=round, white, double=black, double distance=lw] (b1)--(a1)--(a2)--(b2);
draw[line join=round, white, double=black, double distance=lw] (b3)--(a3)--(a4)--(b4);
}{} % if dist >= #1 do nothing
}{}% if na >= nb do nothing (only do each pair of circles once)
}
}
begin{document}
begin{tikzpicture}[line width=lw]
circlesqueeze{1/-1/.5,0/-1/.85,.3/.5/.7,1.3/1.2/.6,1/0/.5}
end{tikzpicture}
begin{tikzpicture}[line width=lw]
circlesqueeze[.03]{0/0/1,1/1/.5,0/1.5/.7,1.6/1.4/.25,1.6/0/.8,2/1/.5,1/2/.5}
end{tikzpicture}
renewcommand{lw}{1}
begin{tikzpicture}[line width=lw]
clip (-4.5,-4.5) rectangle (6,5);
circlesqueeze[.1]{.2/0/3,2/5/3,-2.6/3/2.1,-3.7/-2.3/3.1,1.5/-4/2.2,6.4/0/4}
end{tikzpicture}
end{document}
Answered by Sandy G on January 30, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP