编辑

编辑

在 Asymptote 中,给定两点 $A$ 和 $B$ 之间的(曲线)路径,我想绘制一条连接这两点的管子,半径可变,如下图所示。也就是说,如果 $M$ 是路径上的一个点,我希望 $M$ 处的半径是 $M$ 的函数(例如,$M$ 和原点之间的距离)。

我知道管子包,但据我所知,它只允许一个常量部分。

在此处输入图片描述

答案1

我想我明白了(编辑: 不,请参阅下面的编辑), 使用革命,正如@Schrodinger's cat 所建议的(谢谢!)。

(0,0,0)其思想是,先从到构建一个旋转曲面(1,0,0),然后在方向上缩放该曲面Xlength(B-A)然后通过一个将单位向量发送(1,0,0)到单位向量的旋转来映射该曲面(B-A)/length(B-A),并进行平移A

settings.render = 4;
settings.outformat = "pdf";
import solids; 
size(5cm,0);
currentprojection = orthographic(1,2,4); 

path3 pathAB(triple A, triple B, int n){
    path3 out;
    for(int i = 0; i <= n; ++i){
        real t = i/n;
        triple M = A + t*(B-A);
        real r = length(M);
        out = out -- (t, r, 0);
    }
    return out;
}

triple A = (2,1,0);
triple B = (-10,2,1);

path3 p3 = pathAB(A, B, 100); 
revolution a = scale(length(B-A),1,1)*revolution(p3,X,0,360); 

struct quaternion {
  real w;
  real x;
  real y;
  real z;
}

// unit quaternion to rotation matrix
transform3 quat2rot(quaternion q){
    transform3 T = identity4;
    real a = q.w; 
    real b = q.x;
    real c = q.y;
    real d = q.z;
    T[0][0] = a*a+b*b-c*c-d*d; T[0][1] = 2*b*c-2*a*d; T[0][2] = 2*a*c+2*b*d;
    T[1][0] = 2*a*d+2*b*c; T[1][1] = a*a-b*b+c*c-d*d; T[1][2] = 2*c*d-2*a*b;
    T[2][0] = 2*b*d-2*a*c; T[2][1] = 2*a*b+2*c*d; T[2][2] = a*a-b*b-c*c+d*d;
    return T;
}

// quaternion sending u to v
quaternion from2vectors(triple u, triple v){
    real norm_u_norm_v = length(u) * length(v);
    real cos_theta = dot(u, v) / norm_u_norm_v;
    real half_cos = sqrt(0.5 * (1 + cos_theta));
    triple w = cross(u, v) / (norm_u_norm_v * 2 * half_cos);
    quaternion q;
    q.w = half_cos; q.x = w.x; q.y = w.y; q.z = w.z;
    return q;
}

//
quaternion q = from2vectors((1,0,0), (B-A)/length(B-A));
transform3 T = quat2rot(q);
draw(shift(A)*T*surface(a), red+opacity(0.5), render(compression=Low,merge=true));
draw(shift(A)*scale3(0.1)*unitsphere, black);
draw(shift(B)*scale3(0.1)*unitsphere, black);

在此处输入图片描述


编辑

以上都不是我想要的(我不会删除它,因为它有自己的利益)。

我写错了“我知道管道包,但据我所知,它只允许恒定部分。”。确实,tube有一个变换参数允许对路径上每个点的管段应用变换。以下是示例:

settings.render = 4;
settings.outformat = "pdf";
import tube;
import graph3;
size(5cm,0);
currentprojection = orthographic(0,0,4); 

// define a path
triple f(real x){
  return (x, x*x*x, 1);
}
int n = 200;
path3 p = graph(f, -1, 1, n=n, operator ..);

// transformation to apply to the section of the tube
// t varies from 0 to n/4
transform T(real t){
    triple M = relpoint(p, t/(n/4));
    return scale(length(M)/10); 
}

// draw tube
draw(tube(p, unitcircle, T), purple);

draw(shift(relpoint(p,0))*scale3(0.1)*unitsphere, green);
draw(shift(relpoint(p,1))*scale3(0.1)*unitsphere, red);

在此处输入图片描述

这就是我要找的东西。这就是我想要做的,立体双棱镜:

在此处输入图片描述

相关内容