
分子内の原子がプローブ原子と交差する様子をモデル化するために、球の表面に円弧を描きたいと思います。tikz または asymptote のいずれかを使用して描画するサンプル画像を添付します。
ご協力ありがとうございました。
答え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);
結果: