Desenhar arcos circulares na superfície da esfera

Desenhar arcos circulares na superfície da esfera

Eu gostaria de desenhar arcos circulares na superfície de uma esfera para modelar como os átomos cruzam um átomo-sonda em uma molécula. Anexo um exemplo de imagem que gostaria de desenhar com tikz ou assíntota.

átomos que cruzam o átomo da sonda

arcos circulares para a intersecção

Muito obrigado pela sua ajuda.

Responder1

O código a seguir usa o contourmódulo para calcular a interseção de uma superfície parametrizada com uma superfície definida implicitamente. Ele não oferece uma solução completa para o seu problema, pois traçar uma superfície translúcida na frente de outra pode ser complicado no Assíntota; mas é um começo e pelo menos responde mais ou menos à questão titular.

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

O resultado:

insira a descrição da imagem aqui

informação relacionada