我最近开始对计算机数控 (CNC) 感兴趣,并一直在考虑将其用于METAPOST
CNC 工作流程(使用 pstoedit 将 .pdf(或 .mp)文件转换为 G 代码)。现有的开源计算机辅助制造 (CAM) 程序似乎都存在效率和优雅性方面的困难(就科学正确性而言)--- 如果您在使用 CAM 工具时有具体的成功案例,请在评论中注明。
什么样的函数/模块/程序,在给定一个填充区域的情况下,能够创建一个连续的、尽可能平滑的(IE(不是由线段组成)螺旋路径,将使用给定大小和特定最小重叠的圆形笔完全填充该区域(并且可以从区域中心开始向外移动,或从外向内移动)?如果它还能够容纳孔洞,则可以获得加分,如果它可以创建子路径以提高效率,则可以获得更多加分。
这在 METAPOST 中可行吗?如果不行,除了 g.kov 的漂亮 Asymptote 解决方案(这是一个很好的开始,但使用线段并且不会实例化新的子区域)之外,我还应该研究哪些其他工具?
答案1
这不是一个完整的解决方案,但可以用作入门。在此示例中,a在环境struct Region
中定义asydef
。它采用两条路径,out
并in
在它们之间构造一条螺旋路径,该路径nTurns
围绕内部路径转弯。
fillreg.tex
:
\documentclass{article}
\usepackage{lmodern}
\usepackage{subcaption}
\usepackage[inline]{asymptote}
\usepackage[left=2cm,right=2cm]{geometry}
\begin{asydef}
import graph;
struct Region{
guide out;
guide in;
int nPoints, nTurns, n;
guide spiral;
void unwind(){
guide g; pair p,q,r; real t,s,u;
for(int i=0;i<nTurns-1;++i){
t=i/(nTurns-1);
s=(i+1)/(nTurns-1);
p=(1-t)*point(out,0)+t*point(in,0);
r=p;
g=g--r;
for(int j=1;j<n;++j){
p=(1-t)*point(out,(real)(j*size(out)/(n-1)))
+t*point(in,(real)(j*size(in)/(n-1)));
q=(1-s)*point(out,(real)(j*size(out)/(n-1)))
+s*point(in,(real)(j*size(in)/(n-1)));
u=j/(n-1);
r=(1-u)*p+u*q;
g=g--r;
}
}
spiral=g;
}
void operator init(guide out, guide in, int nPoints=20, int nTurns=10){
this.out=out;
this.in=in;
this.nPoints=nPoints;
this.nTurns=nTurns;
this.n=max(size(out),size(in))*nPoints;
unwind();
}
};
void draw(Region R, pen p=currentpen){
draw(R.out,p);
draw(R.in,p);
draw(R.spiral,p);
};
\end{asydef}
\begin{document}
%
\begin{figure}
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{0.49\textwidth}
\begin{asy}
size(200);
Region R=Region(
rotate(135)*box((-2,-2),(2,2)),shift(0.2,0.4)*scale(0.618,0.382)*unitcircle
,nPoints=80
,nTurns=8
);
draw(R, darkblue+2bp);
\end{asy}
\caption{$\mathrm{nTurns}=8$.}
\label{fig:1a}
\end{subfigure}
%
\begin{subfigure}{0.49\textwidth}
\begin{asy}
size(200);
Region R=Region(
rotate(135)*box((-2,-2),(2,2)),shift(0.2,0.4)*scale(0.618,0.382)*unitcircle
,nPoints=80
,nTurns=80
);
draw(R, orange+2bp);
\end{asy}
\caption{$\mathrm{nTurns}=80$.}
\label{fig:1b}
\end{subfigure}
%
\caption{A region filled with a spiral path.}
\end{figure}
%
%
\begin{figure}
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{0.3\textwidth}
\begin{asy}
size(200);
guide out=(50,-1)..(50,33)..(7,53)..(-11,2)..(-42,-36)..(28,-37)..cycle;
guide in=(34,0)..(24,23)..(16,6)..(2,-8)..(12,-13)..cycle;
Region R=Region(out,in,nPoints=80,nTurns=8);
draw(R, darkblue+2bp);
\end{asy}
\caption{$\mathrm{nTurns}=8$.}
\label{fig:2a}
\end{subfigure}
%
\begin{subfigure}{0.3\textwidth}
\begin{asy}
size(200);
guide out=(50,-1)..(50,33)..(7,53)..(-11,2)..(-42,-36)..(28,-37)..cycle;
guide in=(34,0)..(24,23)..(16,6)..(2,-8)..(12,-13)..cycle;
Region R=Region(out,in,nPoints=80,nTurns=40);
draw(R, orange+2bp);
\end{asy}
\caption{$\mathrm{nTurns}=40$.}
\label{fig:2b}
\end{subfigure}
%
\begin{subfigure}{0.3\textwidth}
\begin{asy}
size(200);
guide out=(50,-1)..(50,33)..(7,53)..(-11,2)..(-42,-36)..(28,-37)..cycle;
guide in=(34,0)..(24,23)..(16,6)..(2,-8)..(12,-13)..cycle;
Region R=Region(out,in,nPoints=80,nTurns=60);
draw(R, orange+2bp);
\end{asy}
\caption{$\mathrm{nTurns}=60$.}
\label{fig:3b}
\end{subfigure}
%
\caption{A region filled with a spiral path.}
\end{figure}
\end{document}
为了处理它latexmk
,请创建文件latexmkrc
:
sub asy {return system("asy '$_[0]'");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");
然后运行latexmk -pdf fillreg.tex
。