我想在球体表面绘制圆弧,以模拟原子与分子中的探针原子相交的情况。我附上了一个我想用 tikz 或渐近线绘制的示例图像。
非常感谢您的帮助。
答案1
以下代码使用该contour
模块计算参数化表面与隐式定义表面的交点。它不能完全解决您的问题,因为在 Asymptote 中将一个半透明表面绘制在另一个半透明表面前面可能很棘手;但这只是一个开始,它至少或多或少回答了名义上的问题。
settings.outformat="png";
settings.render=4;
size(10cm);
import graph3;
import contour;
currentlight.background = black;
currentprojection = orthographic(5, 2, 4);
// Some aliases that make the contour module a bit easier to use.
typedef path[] disconnected_path;
typedef guide[] disconnected_guide;
typedef path3[] disconnected_path3;
real fuzz = .001;
real umax(surface s, real fuzz=fuzz) {
if (s.ucyclic()) return s.index.length;
else return s.index.length - fuzz;
}
real vmax(surface s, real fuzz=fuzz) {
if (s.vcyclic()) return s.index[0].length;
return s.index[0].length - fuzz;
}
int nu = 8, nv = 8;
path3 semicircle = Arc(c=O, -Z, Z, normal=X, n=nu);
surface myUnitsphere = surface(semicircle, c=O, axis=Z, n=nv);
surface sphere(triple c, real r) {
surface toReturn = shift(c)*scale3(r)*myUnitsphere;
return toReturn;
}
// Make the type function3 an alias f0r the type real(triple), i.e., a function3 is a function from triples to reals.
typedef real function3(triple);
// Make the type function2 an alias f0r the type real(real,real), i.e., a function2 is a function from (real, real) to reals.
typedef real function2(real, real);
// Returns the restriction of f to the surface s, given by its built-in parametrization.
function2 pullback(function3 f, surface s) {
return new real(real u, real v) {
return f(s.point(u,v));
};
}
/*
* Parameters: an implicit surface {f = 0} and a parametrized surface s.
* Returns a possibly disconnected path, in the coordinates of the parametric surface s, that describes
* the intersection of the two surfaces.
*/
disconnected_path parametrized_intersection(function3 f, surface s, pair smin = (0,0), pair smax = (umax(s), vmax(s))) {
disconnected_guide toReturn = contour(pullback(f, s), smin, smax, new real[] {0})[0];
return toReturn;
}
path3 on_surface(path p, surface s) {
int size = length(p);
triple[] points = new triple[size];
for (int i = 0; i < size; ++i) {
pair pathpoint = point(p,i);
points[i] = s.point(pathpoint.x, pathpoint.y);
}
path3 toReturn = operator..(...points);
if (cyclic(p)) {
toReturn = toReturn & cycle;
}
return toReturn;
}
disconnected_path3 on_surface(disconnected_path p, surface s) {
disconnected_path3 toReturn;
for (path segment : p) {
toReturn.push(on_surface(segment, s));
}
return toReturn;
}
function3 implicit_sphere(triple c, real r) {
return new real(triple p) {
return length(p - c)^2 - r^2;
};
}
/********************************/
surface mySphere = sphere(c=O, r=1);
draw(mySphere, surfacepen=material(diffusepen=gray(0.1), emissivepen=gray(0.9)));
triple c = 1.5Y;
real r = 0.8;
surface s = sphere(c=c, r=r);
function3 s_implicit = implicit_sphere(c=c, r=r);
disconnected_path param_circle = parametrized_intersection(s_implicit, mySphere);
disconnected_path3 circle = on_surface(param_circle, mySphere);
draw(s, surfacepen=material(diffusepen=0.5*blue + opacity(0.5), emissivepen=0.5*white));
draw(circle, blue);
c = 1.4X;
r = 0.5;
s = sphere(c=c, r=r);
s_implicit = implicit_sphere(c=c, r=r);
param_circle = parametrized_intersection(s_implicit, mySphere);
circle = on_surface(param_circle, mySphere);
draw(s, surfacepen=material(diffusepen=0.5*blue + opacity(0.5), emissivepen=0.5*white));
draw(circle, blue);
结果: