Graph3D - remplacer les sommets par MoleculePlot3D

Aug 24 2020

Comment pouvons-nous remplacer les sommets d'un graphe à 3 Graphics3Ddimensions par des objets individuels ?

Dans mon cas concret, je souhaite visualiser un réseau chimique et remplacer les sommets par leurs MoleculePlot3Dreprésentations respectives . En guise de teaser, c'est le graphique 3D actuel avec lequel je travaille. Vous pouvez probablement imaginer l'application finale :)

J'ai utilisé les idées de ce post pour configurer les coordonnées.

Les sphères rouges doivent être remplacées par des tracés de molécules à 3 dimensions.

Considérez cet exemple minimal:

Graph3D[{"CO" \[DirectedEdge] "C", "CO" \[DirectedEdge] "O"}]

Configuration des MoleculePlot3Dinstances correspondantes :

vert = AssociationThread[
  {"CO", "C", "O"} -> {
   MoleculePlot3D[Molecule[{Atom["[C]"], Atom["[O]"]}, {Bond[{1, 2}, "Double"]}]], 
   MoleculePlot3D[Molecule[{Atom["[C]"]}]], 
   MoleculePlot3D[Molecule[{Atom["[O]"]}]]}]

Cependant, j'ai des difficultés à remplacer les sommets dans le Graph3Dprogramme. J'ai réussi à modifier le graphique 2D:

Graph[{
    Annotation["CO", VertexShapeFunction -> (Inset[vert["CO"], #1, Center, 2*#3] &), VertexSize -> 0.2],
    Annotation["C",  VertexShapeFunction -> (Inset[vert["C"], #1, Center, 2*#3] &),  VertexSize -> 0.2],   
    Annotation["O",  VertexShapeFunction -> (Inset[vert["O"], #1, Center, 2*#3] &),  VertexSize -> 0.2]}, 
    {"CO" \[DirectedEdge] "C", "CO" \[DirectedEdge] "O"}]

Comment puis-je faire cela dans Graph3D? Dans le cas complet, je travaillerai avec les molécules suivantes:

{"C", "C+", "CH", "CH+", "CN", "CO", "CS", "CS+", "H", "H2", "HCO+", 
 "HCS+", "He", "N", "O", "OH", "S", "SO", "CH2+", "CO+", "O+", "OCS+", 
 "S+", "SO+", "CH2", "CN+", "H2O", "HCN", "HS", "H3O+", "HS+", "CH3+", 
 "HNC", "H3CO+", "CH4", "N+", "N2", "H+", "OH+", "OCS", "H2O+", "H2+", 
 "H2S+", "H3+", "He+", "O2", "SO2"}

Donc, des molécules relativement petites sans avoir besoin de faire une mise à l'échelle extrême dans les MoleculePlots.

Réponses

2 JasonB. Aug 25 2020 at 02:35

Cette réponse évite Insettout à fait et saisit les primitives graphiques de l' intérieur de l'expression d'un système MoleculePlot3D, et est donc un peu fragile car elle pourrait casser dans une future version qui restructure la sortie à partir de MoleculePlot3D.

L'inspection montre que le Graphics3D renvoyé par MoleculePlot3D contient toujours un GraphicsComplexavec tous les atomes et liaisons. Nous pouvons donc l'utiliser GraphicsComplexet l'envelopper GeometricTransformationpour rendre la fonction de forme de sommet

molVertex[mol_][coords_, vertex_, scale_] := Module[
    {graphic = MoleculePlot3D @ mol, gc},
    gc = Cases[graphic, _GraphicsComplex, Infinity];
    GeometricTransformation[
        gc, 
        TranslationTransform[coords] @* ScalingTransform[scale]
    ]
]

Voici un exemple,

SeedRandom @ 42;
g = RandomGraph @ {5, 8};
mols = Map[
    Molecule,
    {"CCCC(C)(C)OCC", "SC1CCCC1", "O=P(O)(O)CCO", "CCCC", "F[Ti](Cl)(Cl)Cl"}
];
Graph3D[
    Annotation[#,
        VertexShapeFunction -> molVertex[mols[[#]]],
        VertexSize -> 0.2
    ]& /@ VertexList[g],
    EdgeList @ g
]