Kreisbögen auf der Kugeloberfläche zeichnen

Kreisbögen auf der Kugeloberfläche zeichnen

Ich möchte Kreisbögen auf die Oberfläche einer Kugel zeichnen, um zu modellieren, wie Atome ein Probeatom in einem Molekül kreuzen. Ich füge ein Beispielbild bei, das ich entweder mit Tikz oder Asymptote zeichnen möchte.

Atome kreuzen Sonde Atom

Kreisbögen für die Kreuzung

Vielen Dank für Ihre Hilfe.

Antwort1

Der folgende Code verwendet das contourModul, um die Schnittmenge einer parametrisierten Oberfläche mit einer implizit definierten Oberfläche zu berechnen. Er bietet keine vollständige Lösung für Ihr Problem, da das Plotten einer durchscheinenden Oberfläche vor einer anderen in Asymptote schwierig sein kann; aber es ist ein Anfang und beantwortet zumindest mehr oder weniger die titelgebende Frage.

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);

Das Ergebnis:

Bildbeschreibung hier eingeben

verwandte Informationen