KTUG마당은 KTUG를 방문하는 모든 이용자가 대화를 나누고 소식을 전하는 곳입니다.
- 로그인 없이 자유롭게 글을 읽고 쓸 수 있는 철학은 처음과 같이 계속됩니다.
- Team Blog의 글을 이곳 게시판의 "정보글"로 모았습니다. Team blog는 기고자가 올린 글에 질문을 받는 부담을 줄이기 위하여 댓글을 허용하지 않았습니다. 그러나 이곳 게시판으로 모으면서 댓글을 달 수 있습니다. 게시물을 작성하실 때 댓글을 원하지 않으시면 댓글을 허용하시지 않으시기를 바랍니다. 또한 불필요한 소모성 댓글을 달지 않도록 주의하여 주시기를 바랍니다.
- TeX과 관련된 질문이나 답변은 QnA 마당을 이용하십시오. TeX과 관련된 질문은 지웁니다
- MathJax를 이용한 수식조판을 사용하실 수 있습니다. 여기를 참조하세요.
- 스팸 글을 막기 위하여 짧은 시간 내에 다시 글이 등록되는 IP를 막거나, 광고 글을 막기 위하여 금지어로 .com, .net 등을 설정하고 있습니다. 다소간의 불편함이 있으시더라도 양해 바랍니다.
- 금지어에서 stackexchange, stackoverflow, ctan, overleaf, , github, google.com, gmail.com, .org, .io, sil.org, wiki.com, tistory.com등은 해제하였습니다.
- 사용하는 편집기는 CKeditor입니다. 편집기에서 [enter]를 누르면 <p> 태그가 들어가고, 문단으로 생각하고 한줄을 비웁니다. 글줄만 바꾸려면 shift-enter 를 누르시면 <BR>가 들어가므로 용도에 맞게 나누어 쓸 수 있습니다.
자유글 Knuth, "The Letter S"; Progress, "S자 이야기", and tzplot
2024.06.20 15:54
Progress 님의 "S자 이야기"(2005)는 D. Knuth의 1980년 논문 "The Letter S"에 관련된 글입니다. 이 글은 pgreenbook의 샘플 예제인 pgreenbooksample.tex을 컴파일하면 한 챕터로 들어가 있습니다. (이 부분만 별도로 잘라내어 첨부 theLetterS_story_progress.pdf 하였습니다.)
Knuth 선생의 "The Letter S"에 나오는 토르니엘로의 S자 작도법을 "현대적 수학 언어로 재기술한" 부분은, 우리말로 대략 옮기면 다음과 같습니다. 위의 Progress님 글은 이 문장을 순서대로 읽기 쉽게 재배열하고 약간의 설명을 덧붙이고 있는데요, 여기서는 아무런 편집적 수정을 가하지 않고 번역만 해보았습니다.
또 이 논문에는 여기 기술한 작도법을 MetaFont (가상)코드로 제시하는 부분이 있는데, 그것은 이렇습니다.
이제 이것을 tzplot으로, 차례차례 그려보았습니다.
* thelettersTZplot.pdf
* thelettersTZplot.tex
뭘 어찌했는지는 소스 파일에 아주아주 상세히 적어놓았습니다. 위의 번역문 및 코드와 대조해서 살펴보시면 의외로 재미있을지도 모릅니다.
그리고 이걸 하려다 보니, 임의의 두 점과 중심, 반지름이 주어지는 경우에 두 점을 잇는 호를 그리는 명령이 필요하더라고요. 그래서 만들었습니다. tzplot 자체에 이미 있는지 없는지 모르지만 매뉴얼에서 찾지 못해서 새로 정의했는데, 의도대로 잘 동작하는 듯해서 뿌듯합니다.
그나저나 반지름 계산을 sqrt((x1-o1)^2+(y1-o1)^2) 이렇게 두어 번 하다가, \tzdistance라는 게 있단 걸 기억해내고 되돌아가서 코드를 바꿔야 했습니다. tzplot이 매우 훌륭하다는 게, 이 글의 주제입니다.
댓글 11
-
noname
2024.06.21 08:27
-
ischo
2024.06.22 20:08
\tzarcfrom이 두 점을 호로 연결하는 것이기는 한데, (해보지는 않았지만) 주어진 중심점과 두 점이 있으니까, \tzpointangle로 각을 재고, \tzarc로 호를 그리면 될 듯요.
-
noname
2024.06.21 17:52
Torniello가 자와 콤파스로 그린 알파벳 가운데 대문자 T(위의 그림)를 tzplot으로 그려보려 하였더니, 다음과 같은 문제를 만났습니다.
대수적으로 풀면 되겠지만 tzplot으로 해보고 싶지요? 시도해보시고 잘 되면 알려주세요. :)
-
ischo
2024.06.22 19:57
계산이 귀찮으면, 몸이 조금 고생하면 되겠네요.
재작년에 해두었던 것인데, 귀찮아서 그냥 두었던 것이 생각나서 꺼내서 해봤습니다.두 가지를 더한 것입니다.
* \tznodecircle 옵션 추가
* \tzcoortangenttocircle 추가파일을 첨부할 수 없어서 여기에 둡니다. (작업중이므로 언제든 삭제될 수 있습니다.)
\documentclass{standalone} \usepackage{tzplot-v2.11} %%% version 2.11 \begin{document} \begin{tikzpicture}[font=\scriptsize] % grid \tzhelplines[solid](0,6)(9,9) \tzcoor(0,6)(L){$(0,6)$}[bl] \tzcoor(9,9)(R){$(9,9)$}[ar] % circles \tzcoor*(1,9-1-.25)(a){$a$}[[label distance=-2pt]r] \tzcoor*(1,9+.25)(b){$b$}[[label distance=-2pt]r] \tznodecircle(a)(A)(2cm) \tznodecircle(b)(B)(5mm) \tznode(A.-30){$A$}[br] \tznode(B.0){$B$}[r] % line tangent to circles \tzcoor*(1,9+.765)(X) % trial and error \tzcoortangenttocircle(B)(X)(Tb) \tzcoortangenttocircle(A)(X)(Ta) \tzline[tzextend={5mm}{3cm}](X)(Tb){$\ell$}[ar=10pt,at start] \tzdot*(Ta){$F$}[al] \tzdot*(Tb){$G$}[al] \tzline(a)(Ta) \tzline(b)(Tb) \end{tikzpicture} \end{document}
-
noname
2024.06.23 07:30
공통접선의 방정식을 \(ax+y+c=0\)으로 놓고 연립방정식을 세워서 풀면(제가 직접 풀지 않고 울무슨알파한테 시켰습니다만...) 네 개의 직선 방정식을 보여주는데, (그 중 둘은 공통내접선일테니 무시) \(a=\pm\sqrt{3}\)이라는 것입니다. \tzpointangle(F)(G)=\(60^\circ\).
기울기가 \(\sqrt{3}\)이기 때문에 골치아픈 계산을 하지 않고도 직각삼각형의 비례를 이용해서 F와 G의 좌표값을 간단히(간신히?) 구할 수 있었습니다.
\[
\begin{aligned}
F:~ &\left(1-\frac{\sqrt{3}}{2},7.75+\frac12\right) \approx (0.13397, 8.25)\\
G:~ &\left(1-\frac{0.25\sqrt{3}}{2},9.25+\frac{0.25}{2}\right) \approx (0.78349,9.375)
\end{aligned}
\]그리고 위의 코드에서 보여주신 점 X, 즉 두 접선의 교점의 \(y\)좌표는 \(7.75+2=9.75\)입니다. 여기까지가 계산에 의해 구한 값이고요,
====
제가 생각하기엔 원 A와 B를 둘 다 nodecircle로 그리고 그 둘 다에 coortangenttocircle하는 것보다는, 원 A만을 nodecircle로 그려서 X에서 A에 coortangenttocircle하여 접점을 찾은 다음에 X 위치를 trial&error(어차피 해야 하는 거라면) 조절하면서 B와의 접점을 찾는 것이 더 나은 결과를 보여줄 지도 모르겠습니다. 보여주신 코드에서 \(y_{\mathrm X}=9.765\)인데, 제가 해봤더니 A에만 접선을 그을 때는 \(9.7499\)로 해도 대략 비슷한 그림이 나오더라고요.
\tzcircle"B"(b)(0.25) % line tangent to circles %\tzcoor*(1,9+.765)(X) % trial and error \tzcoor*(1,9.75)(X) %\tzcoortangenttocircle(B)(X)(Tb) \tzcoortangenttocircle(A)(X)(Ta) \tzline"XTA"(X)(Ta) \tzXpoint{B}{XTA}(Tb)
====
사실, 저 토르니엘로의 작도법에 보면 작은 원의 반지름이 1/3로 되어 있습니다. 제가 0.25로 바꾸어서 제시한 이유는 좌표 계산을 손으로 하기 쉽게 하려고 그랬던 것인데요, 아무튼지 만약 작은 원의 반지름(\(r_b\))를 1/3로 잡으면 점 F 위치의 근삿값은 대략 \((0.0835,8.0667)\), G는 \((0.6945,9.4667)\)이라고 합니다(수치계산은 울무슨알파 님...).
-
geoge
2024.06.23 14:50
GeoGebra:
-
noname
2024.07.08 06:41
유클리드 "작도"와 피타고라스 정리를 적용하여 찾는 방법을 tzplot으로 그렸습니다.
\documentclass{standalone} \usepackage{tzplot} \begin{document} \begin{tikzpicture}[font=\scriptsize] % 그리기 준비 \def\Ra{1} \def\Rb{.25} %% 주어진 반지름 \def\RA{\fpeval{9-\Ra-\Rb}} %% 원 A의 중심의 y좌표 \def\RB{\fpeval{9+\Rb}} %% 원 B의 중심의 y좌표 \tzhelplines[solid](0,6)(9,9) \tzcoor(0,6)(L){$(0,6)$}[bl] \tzcoor(9,9)(R){$(9,9)$}[ar] \tzcoor*(1,\RA)(a){$a$}[[label distance=-2pt]r] \tzcoor*(1,\RB)(b){$b$}[[label distance=-2pt]r] \tzcircle"A"(a)(\Ra) \tzcircle"B"(b)(\Rb) %% $\angle aXb$가 직각이 되도록 하는 점 X를 찾는다 \def\LenDist{\fpeval{\RB-\RA}} %% 중심 사이의 거리 = 1.5 \def\LenDiff{\fpeval{\Ra-\Rb}} %% 반지름의 차. 1-0.25=0.75 %% 직각삼각형 $\triangle aXb$의 이웃변($\overline{Xb}$) 길이를 계산한다. %% 이웃변 길이를 "계산"한다는 점에서 "자와 콤파스" 작도 규칙에는 어긋난다. \def\LenPerp{\fpeval{sqrt((\LenDist)^2-(\LenDiff)^2)}} %% a에서 반지름이 \LenDiff(반지름의 차)인 원을 그리고 b에서 반지름 \LenPerp인 원을 그린다. \tzcircle[red]"SA"(a)(\LenDiff) \tzcircle[red]"SB"(b)(\LenPerp) %% 두 원의 교점 X 중에서 왼쪽에 있는 것을 찾음 \tzXpoint{SB}{SA}(X) %% SB를 먼저 그려야 X-1이 왼쪽 교점이 된다.... %% X-1이 되게 하려는 이유는 단순히 (X)로 참조하고 싶기 때문. \tzdot*(X){$X$}[b](1.5pt) %% a에서 X로 가는 반직선을 연장하고, \tzLFn[gray]"LA"(a)(X)[-.5:1] %% b에서 이에 평행한 직선을 긋는다. %% 평행선을 긋는 방법은 여러 가지 있겠는데, 지금 문제는 y좌표만을 %% 문제삼고 있으므로, 두 중심간 거리만큼 평행이동하는 것으로 충분하다. %% "작도"에서 평행선을 그리는 것은 얼마든지 가능하다. \tzLFn[gray]<0,\LenDist>"LB"(a)(X)[0:1] %% 각각 원과의 교점 F, G를 찾아 표시한다. \tzXpoint{A}{LA}(F) \tzXpoint{B}{LB}(G) \tzdot*(F){F}[[label distance=-3pt]al](2pt) \tzdot*(G){G}[[label distance=-3pt]al](2pt) %% F와 G를 잇는 선을 그리고, F, G의 좌표를 얻어 표시한다. \tzline[thick,blue](F)(G) \tzgetxyval(F){\Fx}{\Fy} \tzgetxyval(G){\Gx}{\Gy} \tznode(3,6.5){F: \Fx,\Fy}[r] \tznode(3,6.2){G: \Gx,\Gy}[r] %% 별 필요 없지만 삼각형 aXb도 눈에 띄게 해둔다. \tzpolygon[red,thick](a)(X)(b); \tzto[->](X)(F) \tzto[->](b)(G) %% 별 필요 없지만 직각 표시도 해둔다. \tzrightanglemark(a)(X)(b) \end{tikzpicture} \end{document}
-
DohyunKim
2024.06.24 11:24
전산학적으로 접근하는 방법도 있습니다. tikz는 잘 몰라서 metapost로 해보았습니다.
precision을 더 정밀하게 주려면
\mplibnumbersystem{double}
을 선언하면 됩니다만 정확한 수치를 얻는 게 목적이 아니므로 그냥 두었습니다.\documentclass{article} \usepackage{luamplib} \begin{document} \mpfig u := 100; path A, B; pair ca, cb; numeric ra, rb; 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; precision := 0.0001; % stack overflow가 나지 않을 작은 값 def get_tangent (expr bt, et) = numeric ta, tb, diff; pair va, vb, pa, pb; ta = 1/2[bt, et]; % 시작time과 끝time의 중간 va = direction ta of A; % 원A의 그 time 기울기 tb = directiontime va of B; % 같은 기울기를 갖는 원B의 time pa = point ta of A; % ta의 좌표 pb = point tb of B; % tb의 좌표 vb = pa - pb; % 두 점을 잇는 직선의 기울기 diff = angle va - angle vb; % 두 기울기 각도의 차이 if diff < -precision : % 차이가 큰데 음수이면 get_tangent(ta,et); % 왼쪽 절반을 가지고 재귀 호출 elseif diff > precision : % 차이가 큰데 양수이면 get_tangent(bt,ta); % 오른쪽 절반을 가지고 재귀 호출 else : show pa, pb; fi enddef; get_tangent(2,4); % 원의 이사분면에 답이 있을 것이 분명하므로 draw pa--pb withpen pencircle scaled 2 withcolor red; \endmpfig \end{document}
결과는...
>> (13.39755,824.9978) >> (78.3494,937.49945)
-
noname
2024.06.26 07:52
좋은 거 배웠습니다. ;) tikz말고 pgf로는 비슷한 걸 할 수 있을 듯도 하지만 metapost와 비교할 수는 없겠습니다.
-
Progress
2024.06.26 20:20
[뒷이야기]
"The Letter S"는 Knuth 교수의 책 Digital Typography에서 그나마 가장 만만했던(?) 글이 아니었나 싶습니다. 저는 프로그래밍은 할 줄 모르니 그냥 그래픽 프로그램을 사용해서라도 함 그려보자 생각하고 어도비 일러스트레이터로 그려본 것입니다.
(2004년에서 2006년 사이였으리라 생각됨==> 이미 첫글에 2005년이라고 써놓으셨네요. 요샌 읽어도 머리에 남는게 없어요. 죄송함다)어쨌든 그리는데 \(P_1\)와 \(P_6\), \(P_2\)와 \(P_3\)를 "어떻게 이으라"는 설명이 없는 겁니다. 토르니엘로가 잊은건지 크누스 교수가 잊은건지...
게다가 S자 허리에 해당하는 \(P_9\)와 \(P_{10}\), \(P_7\)와 \(P_8\)을 그냥 "직선"으로 이으라는 겁니다. 아니 세상에, S자는 구석구석 우아하게 곡선으로 이어져야 하는 거 아닙니까?
(백번 양보하여 위와 아래 시작하는 부분을 사선으로 싹둑(직선) 자르는 건 그렇다고 치더라도)그래서 저는 저 그림이 마음에 들지 않았습니다.
-
Progress
2024.06.27 00:19
어쨌든 그리는데 \(P_1\)와 \(P_6\), \(P_2\)와 \(P_3\)를 "어떻게 이으라"는 설명이 없는 겁니다. 토르니엘로가 잊은건지 크누스 교수가 잊은건지...
noname님이 올려주신 thelettersTZplot.tex 소스를 보니, 이걸 어떻게 이으라는게 논문의 본문에 있는가 보군요. tzplot으로 그린 그림에서 파란색 선으로 그은 부분 말입니다.
대충 읽은거 다 들켰네요. 다시 한번 원문을 잘 읽어보겠습니다.
* 어쨌든 근 20년만에 오해를 풀 수 있겠습니다. ;)
생각해보니 \arctwopoints 명령에 반지름을 줄 필요가 없네요. "the Letter S"의 설명을 그대로 따라가다 보니 반지름을 계산해서 넣고 하는 게 있어서 그렇게 했지만 이건 없애도 문제 없을 듯합니다.
명령의 정의와 그리기 코드를 수정했습니다.