TikZ 的混乱台球

TikZ 的混乱台球

我正在寻找一个可以帮助我表示不同形状的混沌台球的 TikZ 库。

任何想法?

在此处输入图片描述

答案1

这是另一个不错的选择渐近线,可以轻松计算路径的交叉点和方向:

圆形台球

体育场台球

这是体育场台球的代码:

\documentclass{standalone}
\usepackage{asymptote}

\begin{document}

\begin{asy}[width=10cm,height=10cm]
import graph;

size(200);

// circle billiard
// path bill = Circle((0,0),90.0);
// real phi = 2*pi*0.23456;

// stadium billiard
path bill = (-50,-50)--(50,-50)--arc((50,0), 50, -90, 90)
  --(50,50)--(-50,50)--arc((-50,0), 50, 90, 270)--cycle;
real phi = 2*pi*0.123456;


draw(bill);


pair s = (20,20), db, dt = exp(I*phi), e = s+200*dt;
path traj = s--e;
real [] c;


for(int i=0; i<50; ++i) {

  c = intersect(bill, traj);
  e = point(traj, c[1]);
  db = dir(bill, c[0]);

  draw(s--e,red);
  dot(e,blue);

  dt = -dt + 2*dot(dt,db)*db;

  s = e;
  e = s + 200*dt;

  traj = (s+dt)--e;
}
\end{asy}
\end{document}

要得到圆圈,请取消注释以下行

// path bill = Circle((0,0),90.0);
// real phi = 2*pi*0.23456;

并注释掉台球路径

path bill = (-50,-50)--(50,-50)--arc((50,0), 50, -90, 90)
  --(50,50)--(-50,50)--arc((-50,0), 50, 90, 270)--cycle;
real phi = 2*pi*0.123456;

编辑:这个问题太有趣了,我也不得不做西奈台球:

在此处输入图片描述

代码只有几行:

\documentclass{standalone}
\usepackage{asymptote}

\begin{document}

\begin{asy}[width=10cm,height=10cm]
import graph;

size(200);

// Sinai billiard
path bill = (-90,-90)--(90,-90)--(90,90)--(-90,90)--cycle;
path inner = reverse(Circle((0,0),30.0));
real phi = 2*pi*0.05;

filldraw(bill^^inner,lightgray,black);


pair s = (30,30), db, dt = exp(I*phi), e = s+200*dt;
path traj = s--e;
real [] co;
real [][] ci;


for(int i=0; i<80; ++i) {

  co = intersect(traj, bill);
  ci = intersections(traj, inner);

  if(ci.length > 0) {
    e = point(traj, ci[0][0]);
    db = dir(inner, ci[0][1]);
  } else {
    e = point(traj, co[0]);
    db = dir(bill, co[1]);
  }

  draw(s--e,red);
  dot(e,blue);

  dt = -dt + 2*dot(dt,db)*db;

  s = e;
  e = s + 200*dt;

  traj = (s+dt)--e;
}
\end{asy}

\end{document}

答案2

为了进行比较,这里是 Alex 的代码到 Metapost 的翻译。

\starttext
\startMPpage[offset=2mm]

u := 1mm;
phi := 0.12345;

path billiard, ball, trajectory;
pair dt, hit, location, awayPoint, tangent; 

% stadium billiard
billiard = (-50u,-50u)--( 50u,-50u) {right} .. {left}  (50u, 50u) 
        -- (-50u, 50u)--(-50u, 50u) {left}  .. {right} cycle;

ball := fullcircle scaled 3mm;

draw billiard;

location := (20u, 20u);
dt := dir(phi);

for i = 0 upto 50 :
  awayPoint := location + 200u*dt ;
  trajectory := (location+dt) -- awayPoint;

  save timeBilliard, timeBall;
  (timeBilliard, timeBall) = billiard intersectiontimes trajectory;

  hit := point timeBilliard of billiard;
  draw location -- hit withcolor red;
  fill ball shifted hit withcolor blue;

  tangent := direction timeBilliard of billiard;
  % The result of direction has arbitrary magnitude. Normalize it;
  tangent := tangent/abs(tangent);

  dt := -dt + 2*(dt dotprod tangent)*tangent;
  location  := hit;

endfor

\stopMPpage
\stoptext

这使:

在此处输入图片描述

将反射次数增加到 500 可得到:

在此处输入图片描述

并将其增加到 2000 得到:

在此处输入图片描述

显示空间填充。

然而,如果从一个圆圈开始,那么 2000 次碰撞将得出:

在此处输入图片描述

一个有趣的选项是将反射随机化:在对切线进行归一化后,添加

  % Randomize the tangent
  tangent := tangent randomized 0.3;
  % Renormalize the result
  tangent := tangent/abs(tangent);

这使:

在此处输入图片描述

通过这种随机化,如果你从一个圆圈开始,你就会得到空间填充(2000 次碰撞后):

在此处输入图片描述

相关内容