生成多个文件时 Asymptote 内存不足错误

生成多个文件时 Asymptote 内存不足错误

我在 Windows 上使用 Asymptote 运行下面的 Asymptote 代码。此代码应生成 180 张图片。以前它运行良好,但也许我在 Linux 上,我不记得了。现在它只生成两张图片,并且由于内存不足而停止。我使用-compact选项asy

settings.outformat = "eps";
import geometry;
import solids;
size(10cm,0);

// camera and light ------------------------------------------------------------
currentprojection = orthographic(0,0,6);
currentlight.background = rgb("363940ff");

// files to be saved -----------------------------------------------------------
string[] files = new string[180];
for(int i = 0; i < 180; ++i){
    string zeros = i < 10 ? "00" : (i < 100 ? "0": "");
    files[i] = "zpic" + zeros + string(i);
}

// Steiner circles -------------------------------------------------------------
circle[] SteinerChain_phi0(circle c0, int n, real shift){
  real R = c0.r; point O = c0.C;
  real sine = sin(pi/n);
  real Cradius = R / (1+sine);
  real Cside = Cradius*sine;
  circle[] circles0 = new circle[n+1];
  for(int i = 0; i < n; ++i){
    real beta = (i+shift)*2*pi/n;
    point pti = Cradius * (cos(beta), sin(beta)) + O;
    circles0[i] = circle(pti, Cside);
  }
  circles0[n] = circle(O, R-2*Cside);
  return circles0;
}

circle[] SteinerChain(circle c0, int n, real phi, real shift){ // c0 : exterior circle
    real invphi = 1/phi;
    point I = (c0.r*invphi, 0) + c0.C;
    real r = c0.r * sqrt(invphi*invphi-1);
    circle[] circles0 = SteinerChain_phi0(c0, n, shift);    
    circle[] circles = new circle[n+1];
    inversion iota = inversion(r*r, I);
    for(int i = 0; i <= n; ++i){
        circles[i] = iota*circles0[i];
    }
    return circles;
}

// -----------------------------------------------------------------------------
struct Cyclide {
  real mu;
  real a;
  real c;
  triple shift;
}
struct MySteinerChain {
    revolution[] spheres;
    Cyclide cyclide;
}

MySteinerChain SteinerChain3D(circle c0, real z, int n, real phi, real shift){
    revolution[] spheres = new revolution[n+1];
    circle[] scircles = SteinerChain(c0, n, phi, shift);
    for(int i = 0; i <= n; ++i){
        triple center = (scircles[i].C.x, scircles[i].C.y, z);
        spheres[i] = sphere(center, scircles[i].r*0.999);
    }
    Cyclide cyclide;
    cyclide.a = (c0.r + scircles[n].r)/2;
    pair O2 = scircles[n].C;
    cyclide.c = (O2.x - c0.C.x)/2;
    cyclide.mu = (c0.r - scircles[n].r)/2;
    cyclide.shift = (c0.C.x + O2.x, c0.C.y + O2.y, 0)/2;
    MySteinerChain out;
    out.spheres = spheres;
    out.cyclide = cyclide;
    return out;
}

// -----------------------------------------------------------------------------
transform3 transfo(real sx, real sy, real sz, real lambda, triple v){
    transform3 T = identity4;
    T[0][0] = sx; T[1][0] = sx*lambda;
    T[1][1] = sy; 
    T[2][2] = sz;
    T[0][3] = v.x; T[1][3] = v.x; T[2][3] = v.z;
    return T;
}

transform3 T = transfo(2, 2, 2, 1/3, (0,0,0));

// -----------------------------------------------------------------------------
int n = 4; // n+1 circles
real phi = 0.3; 

// "bounding box"
triple A = (2.5,2.5,0);
triple C = (-2.5,-2.5,0);

for(int f = 0; f < 180; ++f){
    picture pic;
    draw(pic, A, rgb("363940ff")+opacity(0));
    draw(pic, C, rgb("363940ff")+opacity(0));
    circle c0 = circle((point)(0,0),1);
    MySteinerChain sc = SteinerChain3D(c0, 0.0, n, phi, n*f/180);
    revolution[] spheres = sc.spheres;
    Cyclide c = sc.cyclide;
    for(int i = 0; i <= n; ++i){
        draw(pic, T*surface(spheres[i]), rgb("7E03A8FF"));
    }
    real b = sqrt(c.a*c.a - c.c*c.c);
    triple F(pair uv){
        real h = c.a-c.c*cos(uv.x)*cos(uv.y);
        real x = (c.mu*(c.c-c.a*cos(uv.x)*cos(uv.y))+b*b*cos(uv.x))/h;
        real y = (b*sin(uv.x)*(c.a-c.mu*cos(uv.y)))/h;
        real z = b*sin(uv.y)*(c.c*cos(uv.x)-c.mu)/h;
        return (x,y,z);
    }
    surface s = surface(F, (0,0), (2pi,2pi), 150, 150);
    draw(pic, T*shift(c.shift)*s, yellow+opacity(0.1));
    //
    add(pic); 
    shipout(files[f], bbox(rgb("363940ff"), FillDraw(rgb("363940ff"))));
    erase();
}

答案1

您的示例在 Linux 上使用 Asymptote 版本 2.86 时运行良好。如果您使用的是 Microsoft Windows,请确保安装 64 位可执行文件,因为垃圾收集在 32 位机器上无法正常工作。

相关内容