модель молекулы 20 атомов

import numpy as np
import matplotlib.pyplot as plt
import random

# Определяем виды атомов
atom_types = ['A', 'B', 'C', 'D', 'E']
num_atoms = 20
desired_distance = 2.0  # Желаемое расстояние между атомами

# Генерация случайного набора атомов
atoms = [random.choice(atom_types) for _ in range(num_atoms)]

# Функция для генерации равномерно распределенных координат
def generate_coordinates(num_atoms, desired_distance):
    coordinates = []
    while len(coordinates) < num_atoms:
        coord = np.random.rand(3) * 10  # Умножаем на 10 для масштабирования
        if all(np.linalg.norm(coord - np.array(existing_coord)) >= desired_distance for existing_coord in coordinates):
            coordinates.append(coord)
    return np.array(coordinates)

# Генерация координат
coordinates = generate_coordinates(num_atoms, desired_distance)

# Создаем структуру для связей
bonds = {i: [] for i in range(num_atoms)}

# Функция для нахождения трех ближайших атомов
def find_nearest_atoms(index, coordinates, num_nearest=3):
    distances = np.linalg.norm(coordinates - coordinates[index], axis=1)
    nearest_indices = np.argsort(distances)[1:num_nearest + 1]  # Пропускаем сам атом
    return nearest_indices

# Создаем связи между ближайшими атомами
for i in range(num_atoms):
    nearest_atoms = find_nearest_atoms(i, coordinates)
    bonds[i].extend(nearest_atoms)

# Визуализация
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# Рисуем атомы и добавляем метки с небольшим смещением
for i, coord in enumerate(coordinates):
    ax.scatter(*coord, s=100)
    # Смещение меток
    ax.text(coord[0] + 0.1, coord[1] + 0.1, coord[2] + 0.1, atoms[i], size=20, zorder=1, color='black')

# Рисуем связи
for i in range(num_atoms):
    for j in bonds[i]:
        ax.plot([coordinates[i][0], coordinates[j][0]],
                [coordinates[i][1], coordinates[j][1]],
                [coordinates[i][2], coordinates[j][2]], color='gray', alpha=0.5)

# Настройки графика
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('Модель молекулы')

plt.show()









Алгоритм программы
Импорт необходимых библиотек:

Импортируйте библиотеки numpy для численных расчетов и matplotlib для визуализации.
Определение параметров:

Определите список типов атомов (например, ['A', 'B', 'C', 'D', 'E']).
Установите количество атомов (например, num_atoms = 20).

Установите желаемое расстояние между атомами (например, desired_distance = 2.0).
Генерация случайного набора атомов:

Создайте список atoms, заполнив его случайными типами атомов из определенного списка.
Определение функции для генерации координат:

Определите функцию generate_coordinates(num_atoms, desired_distance), которая:
Создает пустой список coordinates.

В цикле (пока количество координат меньше num_atoms):
Генерирует случайные координаты в трехмерном пространстве (умножая случайные значения на 10 для масштабирования).

Проверяет, что сгенерированные координаты находятся на расстоянии не менее desired_distance от всех уже существующих координат.
Если проверка пройдена, добавляет координаты в список coordinates.
Возвращает массив с координатами.

Генерация координат атомов:

Вызовите функцию generate_coordinates, чтобы получить координаты для всех атомов.
Создание структуры для связей:

Создайте словарь bonds, где ключами будут индексы атомов, а значениями — списки ближайших атомов.
Определение функции для поиска ближайших атомов:

Определите функцию find_nearest_atoms(index, coordinates, num_nearest=3), которая:
Вычисляет расстояния от атома с заданным индексом до всех остальных атомов.
Находит индексы трех ближайших атомов (пропуская сам атом) и возвращает их.
Создание связей между атомами:

В цикле по всем атомам:
Для каждого атома найдите три ближайших атома с помощью функции find_nearest_atoms.
Добавьте найденные индексы в соответствующий список bonds.
Визуализация:

Создайте 3D-график с помощью matplotlib.
В цикле по всем атомам:
Отобразите атомы на графике (используя ax.scatter).

Добавьте текстовые метки для каждого атома с небольшим смещением.
В цикле по всем атомам:
Нарисуйте связи между ближайшими атомами (используя ax.plot).
Настройка графика:

Установите метки для осей и заголовок графика.
Отображение графика:

Вызовите plt.show() для отображения визуализации.



     **



в коде была неточность  -> 
одинаковые буквы атомов были разными по цвету
здесь это исправлено

Словарь цветов:
Создан словарь colors, который сопоставляет каждому типу атома определенный цвет.
Использование цвета при визуализации: При отрисовке атомов теперь используется цвет, соответствующий типу атома, что обеспечивает однородность в отображении.
Теперь атомы с одинаковыми буквами будут отображаться одним цветом, что сделает визуализацию более логичной и понятной



 


import numpy as np
import matplotlib.pyplot as plt
import random

# Определяем виды атомов и соответствующие им цвета
atom_types = ['A', 'B', 'C', 'D', 'E']
colors = {
    'A': 'red',
    'B': 'blue',
    'C': 'green',
    'D': 'orange',
    'E': 'purple'
}
num_atoms = 20
desired_distance = 2.0  # Желаемое расстояние между атомами

# Генерация случайного набора атомов
atoms = [random.choice(atom_types) for _ in range(num_atoms)]

# Функция для генерации равномерно распределенных координат
def generate_coordinates(num_atoms, desired_distance):
    coordinates = []
    while len(coordinates) < num_atoms:
        coord = np.random.rand(3) * 10  # Умножаем на 10 для масштабирования
        if all(np.linalg.norm(coord - np.array(existing_coord)) >= desired_distance for existing_coord in coordinates):
            coordinates.append(coord)
    return np.array(coordinates)

# Генерация координат
coordinates = generate_coordinates(num_atoms, desired_distance)

# Создаем структуру для связей
bonds = {i: [] for i in range(num_atoms)}

# Функция для нахождения трех ближайших атомов
def find_nearest_atoms(index, coordinates, num_nearest=3):
    distances = np.linalg.norm(coordinates - coordinates[index], axis=1)
    nearest_indices = np.argsort(distances)[1:num_nearest + 1]  # Пропускаем сам атом
    return nearest_indices

# Создаем связи между ближайшими атомами
for i in range(num_atoms):
    nearest_atoms = find_nearest_atoms(i, coordinates)
    bonds[i].extend(nearest_atoms)

# Визуализация
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# Рисуем атомы и добавляем метки с небольшим смещением
for i, coord in enumerate(coordinates):
    ax.scatter(*coord, s=100, color=colors[atoms[i]])  # Используем цвет в зависимости от типа атома
    # Смещение меток
    ax.text(coord[0] + 0.1, coord[1] + 0.1, coord[2] + 0.1, atoms[i], size=20, zorder=1, color='black')

# Рисуем связи
for i in range(num_atoms):
    for j in bonds[i]:
        ax.plot([coordinates[i][0], coordinates[j][0]],
                [coordinates[i][1], coordinates[j][1]],
                [coordinates[i][2], coordinates[j][2]], color='gray', alpha=0.5)

# Настройки графика
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('Модель молекулы')

plt.show()


Рецензии
хотел спросить у разработчиков портала стихи.ру
почему в произведении нельзя вставлять больше одной картинки ?
это могло быть полезно для наглядности отображения большого текста

Алекс Альтек   23.04.2025 01:57     Заявить о нарушении