Graph3D - แทนที่จุดยอดด้วย MoleculePlot3D

Aug 24 2020

เราจะแทนที่จุดยอดในกราฟ 3 สลัวด้วยGraphics3Dวัตถุแต่ละชิ้นได้อย่างไร?

ในกรณีที่เป็นรูปธรรมของฉันฉันต้องการที่จะเห็นภาพเครือข่ายทางเคมีและแทนที่จุดที่มีตนMoleculePlot3Dเป็นตัวแทน ในทีเซอร์นั่นคือกราฟ 3 มิติปัจจุบันที่ฉันใช้งานอยู่ คุณอาจจินตนาการถึงแอปพลิเคชันสุดท้าย :)

ผมใช้แนวคิดจากกระทู้นี้ในการตั้งพิกัด

ทรงกลมสีแดงควรแทนที่ด้วยแปลงโมเลกุล 3 สลัว

ลองพิจารณาตัวอย่างเล็ก ๆ น้อย ๆ นี้:

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

การตั้งค่าMoleculePlot3Dอินสแตนซ์ที่เกี่ยวข้อง:

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

อย่างไรก็ตามฉันมีปัญหาในการแทนที่จุดยอดในทางGraph3Dโปรแกรม ฉันจัดการแก้ไข 2D Graph:

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"}]

ฉันจะทำสิ่งนี้ใน Graph3D ได้อย่างไร? ในกรณีทั้งหมดฉันจะทำงานกับโมเลกุลต่อไปนี้:

{"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"}

โมเลกุลที่ค่อนข้างเล็กโดยไม่จำเป็นต้องทำการสเกลมากใน MoleculePlots

คำตอบ

2 JasonB. Aug 25 2020 at 02:35

คำตอบนี้หลีกเลี่ยงการInsetทั้งหมดและคว้า primitives กราฟิกจากภายในแสดงออกจากระบบและดังนั้นจึงเป็นบิตที่เปราะบางเพราะมันสามารถทำลายในรุ่นอนาคตที่ปรับโครงสร้างการส่งออกจากMoleculePlot3DMoleculePlot3D

การตรวจสอบแสดงให้เห็นว่า Graphics3D ที่ส่งคืนโดย MoleculePlot3D จะมีGraphicsComplexอะตอมและพันธะทั้งหมดเสมอ เราสามารถใช้มันGraphicsComplexและรวมเข้าด้วยกันGeometricTransformationเพื่อสร้างฟังก์ชันรูปร่างจุดยอด

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

นี่คือตัวอย่าง

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
]