Skip to content

Instantly share code, notes, and snippets.

@dohyunkim
Last active June 26, 2024 13:29
Show Gist options
  • Save dohyunkim/1768aaeda7678b379e2a8b312475fffb to your computer and use it in GitHub Desktop.
Save dohyunkim/1768aaeda7678b379e2a8b312475fffb to your computer and use it in GitHub Desktop.
\documentclass{article}
\usepackage{luamplib}
\begin{document}
\mpfig
u:=100; % 그리기 용도. 계산만 하려면 1.
path A, B; numeric ra, rb; pair ca, cb;
cb = (1u,9u+rb);
ca = (1u,9u-rb-ra);
ra = 1u;
rb = u/4;
A = fullcircle scaled 2ra shifted ca;
B = fullcircle scaled 2rb shifted cb;
draw A; draw B;
% 닮음꼴의 중심 z0를 구한다. 비례식 이용.
x0 = ra;
(y0-ypart ca)/ra = (y0-ypart cb)/rb;
% z0와 원A, B의 중심을 지름으로 하는 원을 각각 그린다. 직각삼각형의 외접원.
path ta,tb;
ta = fullcircle scaled ypart(z0-ca) shifted 1/2[z0,ca];
tb = fullcircle scaled ypart(z0-cb) shifted 1/2[z0,cb];
% 원 A, B와 새로운 원이 만나는 점을 각각 구한다.
z2 = ta intersectionpoint A;
z1 = tb intersectionpoint B;
show z2,z1;
draw z2--z1 withpen pencircle scaled 1 withcolor red;
\endmpfig
\end{document}
\documentclass{article}
\usepackage{luamplib}
\begin{document}
\mpfig
u := 100;
path A, B; pair ca, cb; numeric ra, rb;
cb = (-2u,0u);
ca = (0u,0u);
ra = 1u;
rb = u/3;
A = fullcircle scaled 2ra shifted ca;
B = fullcircle scaled 2rb shifted cb;
draw A; draw B;
precision := 0.001; % stack overflow가 나지 않을 작은 값
def get_tangent (expr bt, et) =
numeric mt, diff; pair va, vb, pa, pb;
mt = 1/2[bt, et]; % 시작time과 끝time의 중간
va = direction mt of A; % 원A의 그 time 기울기
pa = point mt of A; % mt의 좌표
pb = directionpoint va of B; % 같은 기울기를 갖는 원B의 좌표
vb = pa - pb; % 두 점을 잇는 직선의 기울기
if angle va * angle vb < 0 : vb := -vb ; fi
diff = angle va - angle vb; % 두 기울기 각도의 차이
if (diff > 90) or (diff < -90): diff := -diff; fi
if diff < -precision : % 차이가 큰데 음수이면
get_tangent(mt,et); % 왼쪽 절반을 가지고 재귀 호출
elseif diff > precision : % 차이가 큰데 양수이면
get_tangent(bt,mt); % 오른쪽 절반을 가지고 재귀 호출
else :
show pa, pb;
draw pa--pb withpen pencircle scaled 2 withcolor red;
fi
enddef;
if xpart point 0 of B > xpart point 0 of A :
if ypart point 6 of B < ypart point 6 of A :
get_tangent(0,2);
get_tangent(4,6);
elseif ypart point 2 of B > ypart point 2 of A :
get_tangent(2,4);
get_tangent(6,8);
else :
get_tangent(0,2);
get_tangent(6,8);
fi
elseif xpart point 4 of B < xpart point 4 of A :
if ypart point 6 of B < ypart point 6 of A :
get_tangent(2,4);
get_tangent(6,8);
elseif ypart point 2 of B > ypart point 2 of A :
get_tangent(0,2);
get_tangent(4,6);
else :
get_tangent(2,4);
get_tangent(4,6);
fi
else :
if ypart point 2 of B > ypart point 2 of A :
get_tangent(0,2);
get_tangent(2,4);
elseif ypart point 6 of B < ypart point 6 of A :
get_tangent(4,6);
get_tangent(6,8);
elseif xpart (A intersectiontimes B) > 0 :
if angle (cb - ca) > 90 :
get_tangent(2,3);
get_tangent(3,4);
elseif angle (cb - ca) > 0 :
get_tangent(0,1);
get_tangent(1,2);
elseif angle (cb - ca) > -90 :
get_tangent(6,7);
get_tangent(7,8);
else :
get_tangent(4,5);
get_tangent(5,6);
fi
fi
fi
\endmpfig
\end{document}
\documentclass{article}
\usepackage{luamplib}
\begin{document}
\mpfig
u := 100;
path A, B; pair ca, cb; numeric ra, rb;
ca = (1u,9u-rb-ra);
cb = (1u,9u+rb);
ra = 1u;
rb = u/3;
A = fullcircle scaled 2ra shifted ca;
B = fullcircle scaled 2rb shifted cb;
draw A; draw B;
vardef f (expr t) =
pair va, vb;
va = direction t of A;
vb = point t of A - point t of B;
if angle va * angle vb < 0 :
angle va < angle -vb
else :
angle va < angle vb
fi
enddef;
tolerance := 0.001;
t := solve f(2,4);
show point t of A, point t of B;
draw point t of A -- point t of B withcolor red;
\endmpfig
\end{document}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment