
Me gustaría dibujar arcos circulares en la superficie de una esfera para modelar cómo los átomos se cruzan con un átomo sonda en una molécula. Adjunto una imagen de ejemplo que me gustaría dibujar ya sea con tikz o asíntota.
Muchas gracias por tu ayuda.
Respuesta1
El siguiente código utiliza el contour
módulo para calcular la intersección de una superficie parametrizada con una superficie definida implícitamente. No ofrece una solución completa a su problema, ya que trazar una superficie translúcida frente a otra puede ser complicado en Asíntota; pero es un comienzo y al menos responde más o menos a la pregunta principal.
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);
El resultado: