diff --git a/1.py b/1.py new file mode 100644 index 0000000..4c5a820 --- /dev/null +++ b/1.py @@ -0,0 +1,27 @@ +import matplotlib.pyplot as plt + +# Get the input from the user +base = float(input("Enter the length of the base of the trapezoid: ")) +height = float(input("Enter the height of the trapezoid: ")) +square_side = float(input("Enter the length of the side of the square: ")) + +# Calculate the area of the trapezoid +area = (base + height) / 2 * square_side + +# Calculate the number of squares that can be divided from the trapezoid +num_squares = int(area / square_side**2) + +# Create a figure and axes +fig, ax = plt.subplots() + +# Draw the trapezoid +ax.fill_betweenx([height / 2, height / 2, height, height], [0, base / 2, base / 2 + base, base], color='blue') + +# Draw the squares +for i in range(num_squares): + x = i * square_side + y = height / 2 + ax.fill([x, x + square_side, x + square_side, x], [y, y, y + square_side, y + square_side], color='red') + +# Show the plot +plt.show() \ No newline at end of file diff --git a/10.py b/10.py new file mode 100644 index 0000000..ed51e12 --- /dev/null +++ b/10.py @@ -0,0 +1,64 @@ +import matplotlib.pyplot as plt +import numpy as np + +def draw_trapezoid_and_squares(base1, base2, height, square_size): + """ + Функция для рисования трапеции и её разбиения на квадраты. + + :param base1: Длина нижнего основания трапеции + :param base2: Длина верхнего основания трапеции + :param height: Высота трапеции + :param square_size: Размер стороны квадрата + """ + # Определяем координаты вершин трапеции + x1, y1 = 0, 0 # Левая нижняя вершина + x2, y2 = base1, 0 # Правая нижняя вершина + x3, y3 = (base1 - base2) / 2, height # Левая верхняя вершина + x4, y4 = x3 + base2, height # Правая верхняя вершина + + # Рисуем трапецию + trapezoid_x = [x1, x2, x4, x3, x1] + trapezoid_y = [y1, y2, y4, y3, y1] + + plt.figure(figsize=(8, 6)) + plt.plot(trapezoid_x, trapezoid_y, 'b-', label='Трапеция') + + # Разбиваем трапецию на квадраты + num_rows = int(height // square_size) # Количество строк квадратов + for row in range(num_rows): + # Вычисляем высоту текущей строки + current_height = (row + 1) * square_size + if current_height > height: + break + + # Определяем ширину трапеции на текущей высоте + width_at_height = base1 - (base1 - base2) * (current_height / height) + start_x = (base1 - width_at_height) / 2 + end_x = start_x + width_at_height + + # Разбиваем строку на квадраты + num_cols = int(width_at_height // square_size) + for col in range(num_cols): + square_x = start_x + col * square_size + square_y = row * square_size + + # Рисуем квадрат + square = plt.Rectangle((square_x, square_y), square_size, square_size, fill=False, edgecolor='r', linewidth=1) + plt.gca().add_patch(square) + + # Настройки графика + plt.gca().set_aspect('equal', adjustable='box') + plt.title('Разбиение трапеции на квадраты') + plt.xlabel('X') + plt.ylabel('Y') + plt.legend() + plt.grid(True) + plt.show() + +# Пример использования +base1 = 10 # Нижнее основание +base2 = 6 # Верхнее основание +height = 8 # Высота +square_size = 1 # Размер квадрата + +draw_trapezoid_and_squares(base1, base2, height, square_size) diff --git a/11g.py b/11g.py new file mode 100644 index 0000000..caca1d8 --- /dev/null +++ b/11g.py @@ -0,0 +1,118 @@ +import numpy as np +import matplotlib.pyplot as plt + +# --- 1. Определение параметров моделирования --- + +# Геометрические параметры (1D модель: только глубина Z) +DZ = 0.1 # Размер ячейки по глубине (Z) в метрах (10 см) +Z_MAX = 2.0 # Максимальная глубина моделирования в метрах +L_MAX = 10.0 # Максимальная длина (не используется в 1D модели) +W_MAX = 22.0 # Максимальная ширина (не используется в 1D модели) + +# Количество узлов (ячеек) по глубине +N_NODES = int(Z_MAX / DZ) + 1 +DEPTHS = np.linspace(0, Z_MAX, N_NODES) + +# Теплофизические параметры грунта (приближенные значения для талого грунта) +LAMBDA = 1.5 # Теплопроводность грунта (λ), Вт/(м·К) +RHO_C = 2.0e6 # Объемная теплоемкость (ρ·C), Дж/(м³·К) +ALPHA = LAMBDA / RHO_C # Температуропроводность (α), м²/с + +# Параметры времени +DT_HOUR = 3600 # Шаг по времени (Δt) в секундах (1 час) +N_DAYS = 365 # Продолжительность моделирования в днях (1 год) +N_STEPS = N_DAYS * 24 # Общее количество временных шагов + +# Критерий устойчивости (Число Фурье, r) +R = (ALPHA * DT_HOUR) / (DZ**2) + +# Проверка устойчивости явной схемы +if R > 0.5: + print(f"ВНИМАНИЕ: Нарушен критерий устойчивости (R = {R:.4f}).") + print("Уменьшите шаг по времени (DT_HOUR) или шаг по пространству (DZ).") + R = 0.5 # Принудительное ограничение для демонстрации +else: + print(f"Критерий устойчивости соблюден (R = {R:.4f} <= 0.5).") + +# --- 2. Инициализация температуры --- + +# Начальная температура грунта (равномерное распределение) +T_INITIAL = 5.0 # °C +Temperature = np.full(N_NODES, T_INITIAL) + +# Массив для записи результатов (для построения графика) +temp_history = [Temperature.copy()] + +# --- 3. Определение граничных условий (ГКУ) --- + +def surface_temperature(step): + """ + Граничное условие (ГКУ) на поверхности (z=0). + Используется синусоидальная функция для имитации сезонного цикла (1 год). + """ + time_in_hours = step * DT_HOUR + time_in_years = time_in_hours / (365 * 24 * 3600) + + # Параметры: T_avg = 0°C, Amplitude = 20°C, сдвиг фазы (начало зимы) + T_avg = 0.0 + T_amp = 20.0 + # Фаза: +pi/2, чтобы начать симуляцию с T(0) = T_avg + return T_avg + T_amp * np.sin(2 * np.pi * time_in_years + np.pi/2) + +# ГКУ на нижней границе (z=Z_MAX) - постоянная температура +T_BOTTOM = T_INITIAL + +# --- 4. Цикл моделирования --- + +print(f"Начало моделирования: {N_DAYS} дней ({N_STEPS} шагов по 1 часу)...") + +for n in range(N_STEPS): + T_old = Temperature.copy() + + # 1. Применение граничных условий + # Верхняя граница (i=0) - Температура воздуха (Dirichlet BC) + T_surface = surface_temperature(n) + Temperature[0] = T_surface + + # Нижняя граница (i=N_NODES-1) - Постоянная температура (Dirichlet BC) + Temperature[-1] = T_BOTTOM + + # 2. Расчет температуры для внутренних узлов (i=1 до N_NODES-2) + # Формула явной схемы FDM: T_i^{n+1} = T_i^n (1 - 2r) + r (T_{i-1}^n + T_{i+1}^n) + for i in range(1, N_NODES - 1): + # --- Здесь должно быть место для учета фазовых переходов (мерзлота/талый грунт) --- + # В реальной модели R и T_i^{n+1} должны рассчитываться с учетом + # изменения LAMBDA, RHO_C и скрытой теплоты L (L_v, формула 3.13) + # в зависимости от T_i^n и температуры фазового перехода (T_bf, формула 3.7). + # В этой упрощенной модели LAMBDA, RHO_C, R - константы. + # --------------------------------------------------------------------------------- + + T_new = T_old[i] * (1 - 2 * R) + R * (T_old[i-1] + T_old[i+1]) + Temperature[i] = T_new + + # Запись истории температуры каждые 90 дней для графика + if (n % (90 * 24) == 0) and (n > 0): + temp_history.append(Temperature.copy()) + +temp_history.append(Temperature.copy()) +print("Моделирование завершено.") + +# --- 5. Визуализация результатов --- + +plt.figure(figsize=(10, 6)) +time_labels = [f"День {int(i / 24)}" for i in np.linspace(0, N_STEPS, len(temp_history))] + +# Добавление начального состояния +plt.plot(temp_history[0], -DEPTHS, label=f't=0 (Начальное)', linestyle='--') + +# Построение графиков для разных моментов времени +for i, T_profile in enumerate(temp_history[1:]): + plt.plot(T_profile, -DEPTHS, label=f'{time_labels[i+1]}', linewidth=2) + +plt.xlabel('Температура, °C') +plt.ylabel('Глубина, м') +plt.title('Одномерное моделирование теплопереноса в грунте (1 год)') +plt.grid(True, linestyle=':', alpha=0.6) +plt.legend(title='Время') +plt.axvline(x=0, color='grey', linestyle='-') +plt.show() \ No newline at end of file diff --git a/12g.py b/12g.py new file mode 100644 index 0000000..d68c1aa --- /dev/null +++ b/12g.py @@ -0,0 +1,179 @@ +import numpy as np +import matplotlib.pyplot as plt +from matplotlib import cm +import h5py + +# --- 1. Параметры и сетка (2D) --- +DX = 0.1 +DZ = 0.1 + +Z_MAX = 2.0 +X_MAX = 10.0 + +N_Z = int(Z_MAX / DZ) + 1 +N_X = int(X_MAX / DX) + 1 + +# Время и теплофизические параметры +N_DAYS = 365 +DT = 1800 # 30 минут (сек). +ALPHA = 7.5e-7 +R = ALPHA * DT / (DX**2) +N_STEPS = int(N_DAYS * 24 * 3600 / DT) + +# Параметры сохранения данных +HDF5_FILENAME = 'temperature_simulation_results.hdf5' +RECORD_INTERVAL_STEPS = int(24 * 3600 / DT) + +print(f"2D-сетка: {N_Z}x{N_X} узлов.") +print(f"Устойчивость соблюдена: R = {R:.4f} <= 0.25.") + +# --- 2. Инициализация и геометрическая маска (Трапеция) --- + +T_INITIAL = 5.0 # °C +Temperature = np.full((N_Z, N_X), T_INITIAL, dtype=float) + +# Создание маски для области ТРАПЕЦИИ: +mask = np.full((N_Z, N_X), False) + +# Параметры трапеции (ширина на дне 10м, на поверхности 5м) +W_bottom = X_MAX +W_top = 5.0 + +for i in range(N_Z): + depth_i = i * DZ + W_z = W_bottom - (W_bottom - W_top) * (1 - depth_i / Z_MAX) + offset_x = (X_MAX - W_z) / 2 + + start_j = int(offset_x / DX) + end_j = int((X_MAX - offset_x) / DX) + + start_j = max(0, start_j) + end_j = min(N_X, end_j) + + mask[i, start_j:end_j] = True + +# Обнуляем температуру вне маски (заполняем NaN) +Temperature[~mask] = np.nan + +# --- 3. Граничные условия (Упрощенные) --- + +def surface_temp(step): + """Температура поверхности (Z=0) - синусоида 1 год.""" + time_in_seconds = step * DT + time_in_years = time_in_seconds / (N_DAYS * 24.0 * 3600.0) + T_avg = 0.0 + T_amp = 20.0 + return T_avg + T_amp * np.sin(2 * np.pi * time_in_years + np.pi/2) + +T_BOTTOM = T_INITIAL + +# --- 4. Цикл моделирования и сохранение в HDF5 (Без изменений) --- + +print(f"Начало моделирования ({N_STEPS} шагов). Результаты будут сохранены в {HDF5_FILENAME}...") + +with h5py.File(HDF5_FILENAME, 'w') as f: + + f.attrs['DZ'] = DZ + f.attrs['DX'] = DX + f.attrs['N_DAYS'] = N_DAYS + f.attrs['DT_seconds'] = DT + f.create_dataset('mask', data=mask, dtype='bool') + + temp_dset = f.create_dataset('temperature_profiles', + shape=(0, N_Z, N_X), + maxshape=(N_DAYS + 1, N_Z, N_X), + dtype='f4', + chunks=(1, N_Z, N_X), + compression="gzip") + + record_counter = 0 + + for n in range(N_STEPS): + T_old = Temperature.copy() + + T_surface = surface_temp(n) + Temperature[0, mask[0, :]] = T_surface + Temperature[N_Z - 1, mask[N_Z - 1, :]] = T_BOTTOM + + for i in range(1, N_Z - 1): + for j in range(1, N_X - 1): + if mask[i, j]: + T_i_minus_1 = T_old[i-1, j] if mask[i-1, j] else T_old[i, j] + T_i_plus_1 = T_old[i+1, j] if mask[i+1, j] else T_old[i, j] + T_j_minus_1 = T_old[i, j-1] if mask[i, j-1] else T_old[i, j] + T_j_plus_1 = T_old[i, j+1] if mask[i, j+1] else T_old[i, j] + + T_new = T_old[i, j] * (1 - 4 * R) + R * (T_i_minus_1 + T_i_plus_1 + T_j_minus_1 + T_j_plus_1) + + Temperature[i, j] = T_new + + if n % RECORD_INTERVAL_STEPS == 0: + temp_dset.resize(record_counter + 1, axis=0) + temp_dset[record_counter, :, :] = Temperature + record_counter += 1 + + if record_counter % 50 == 0: + print(f"Записан профиль за день {record_counter}.") + + +print(f"Моделирование завершено. Сохранено {record_counter} профилей температуры в файле {HDF5_FILENAME}.") + +# --- 5. Пример визуализации (Чтение из HDF5 с исправлениями) --- + +try: + with h5py.File(HDF5_FILENAME, 'r') as f: + temp_dset_read = f['temperature_profiles'] + mask_read = f['mask'][:] + + days_to_plot = [0, 90, 180, 270, N_DAYS - 1] # N_DAYS - 1, так как 365-й день это индекс 364 + indices_to_plot = [day for day in days_to_plot if day < temp_dset_read.shape[0]] + + if not indices_to_plot: + print("Нет сохраненных данных для визуализации.") + else: + X_COORD = np.linspace(0, X_MAX, N_X) + Z_COORD = np.linspace(-Z_MAX, 0, N_Z) + + fig, axes = plt.subplots(1, len(indices_to_plot), figsize=(18, 5)) + fig.suptitle(f'2D Теплоперенос (Чтение из {HDF5_FILENAME})', fontsize=14) + + T_all = temp_dset_read[:].flatten() + T_min = np.nanmin(T_all) + T_max = np.nanmax(T_all) + + # ИСПРАВЛЕНИЕ 1: Использование plt.colormaps + cmap_base = plt.colormaps['RdYlBu'] + # Создаем копию для изменения "плохих" значений + cmap_custom = cmap_base.copy() + cmap_custom.set_bad('lightgray') + + for idx, day_index in enumerate(indices_to_plot): + T_profile = temp_dset_read[day_index, :, :] + # Проверяем, что оси - это массив, если только одна ось + ax = axes[idx] if len(indices_to_plot) > 1 else axes + + im = ax.imshow(T_profile, + extent=[0, X_MAX, -Z_MAX, 0], + origin='upper', + cmap=cmap_custom, + aspect='auto', + vmin=T_min, + vmax=T_max) + + ax.contour(X_COORD, Z_COORD, mask_read.astype(int), levels=[0.5], colors='k', linewidths=1.5, linestyles='--') + ax.set_title(f'День: {day_index}') + ax.set_xlabel('Длина, м') + ax.set_ylabel('Глубина, м') + + # ИСПРАВЛЕНИЕ 2: Удаление rect=[0, 0, 0.98, 1] и let axes handle spacing + plt.tight_layout() + + # Добавление цветовой шкалы + # Убедимся, что cbar создается корректно, используя массив осей + cbar = fig.colorbar(im, ax=axes.ravel().tolist() if len(indices_to_plot) > 1 else axes, orientation='vertical', fraction=0.02, pad=0.04) + cbar.set_label('Температура, °C') + + plt.show() + +except Exception as e: + print(f"Ошибка при чтении или визуализации HDF5: {e}") \ No newline at end of file diff --git a/12gdef.py b/12gdef.py new file mode 100644 index 0000000..28087d8 --- /dev/null +++ b/12gdef.py @@ -0,0 +1,122 @@ +import numpy as np +import matplotlib.pyplot as plt +from matplotlib import cm + +def initialize_trapezoid_simulation(depth_max, length_bottom, length_top, T_initial, dz_dx=0.1): + """ + Создает заготовку для 2D-моделирования теплопереноса в трапециевидном грунтовом массиве. + + :param depth_max: Максимальная глубина (Z_MAX), м. + :param length_bottom: Ширина трапеции на дне (при Z_MAX), м. + :param length_top: Ширина трапеции на поверхности (при Z=0), м. + :param T_initial: Начальная равномерная температура грунта, °C. + :param dz_dx: Размер ячейки сетки (DX = DZ), м. + :return: Словарь с инициализированными данными (Temperature, Mask, Coordinates). + """ + + # 1. Определение параметров сетки + DX = DZ = dz_dx + + N_Z = int(depth_max / DZ) + 1 + N_X = int(length_bottom / DX) + 1 + + # 2. Инициализация и геометрическая маска + + # Создаем 2D-массив температуры, заполненный начальной температурой T_initial + Temperature = np.full((N_Z, N_X), T_initial, dtype=float) + + # Создаем булеву маску для определения области трапеции + mask = np.full((N_Z, N_X), False) + + for i in range(N_Z): + depth_i = i * DZ + + # Линейное изменение ширины по глубине Z + # W(Z) = L_bottom - (L_bottom - L_top) * (1 - Z/Z_MAX) + W_z = length_bottom - (length_bottom - length_top) * (1 - depth_i / depth_max) + + # Центрирование: отступ слева + offset_x = (length_bottom - W_z) / 2 + + # Индексы X, которые попадают в трапецию + start_j = int(offset_x / DX) + end_j = int((length_bottom - offset_x) / DX) + + # Заполняем маску для текущей глубины + start_j = max(0, start_j) + end_j = min(N_X, end_j) + mask[i, start_j:end_j] = True + + # Применяем маску: области вне трапеции помечаются как NaN (для визуализации) + Temperature[~mask] = np.nan + + # 3. Визуализация Дня 0 + + X_COORD = np.linspace(0, length_bottom, N_X) + Z_COORD = np.linspace(-depth_max, 0, N_Z) + + fig, ax = plt.subplots(figsize=(10, 5)) + fig.suptitle(f'Начальное состояние моделирования (День 0)', fontsize=14) + + # Настройка цветовой карты для NaN + cmap_base = plt.colormaps['RdYlBu'] + cmap_custom = cmap_base.copy() + cmap_custom.set_bad('lightgray') + + im = ax.imshow(Temperature, + extent=[0, length_bottom, -depth_max, 0], + origin='upper', + cmap=cmap_custom, + aspect='auto', + vmin=T_initial - 1, # Устанавливаем Vmin/Vmax для старта + vmax=T_initial + 1) + + # Наложение контура трапеции + ax.contour(X_COORD, Z_COORD, mask.astype(int), levels=[0.5], colors='k', linewidths=1.5, linestyles='--') + + ax.set_title(f'Начальная температура: {T_initial:.1f} °C') + ax.set_xlabel('Длина (X), м') + ax.set_ylabel('Глубина (Z), м') + + cbar = fig.colorbar(im, ax=ax, orientation='vertical', fraction=0.04, pad=0.04) + cbar.set_label('Температура, °C') + + plt.tight_layout() + plt.show() + + # 4. Возврат данных для дальнейших расчетов + return { + 'Temperature_Initial': Temperature, + 'Mask': mask, + 'DX': DX, + 'DZ': DZ, + 'N_X': N_X, + 'N_Z': N_Z + } + +# ---------------------------------------------------------------------- +## 🚀 Пример использования +# ---------------------------------------------------------------------- + +# ВХОДНЫЕ ПАРАМЕТРЫ: +MAX_DEPTH = 2.0 # Глубина 2 м +WIDTH_BOTTOM = 22.0 # Ширина на дне 22 м +WIDTH_TOP = 10.0 # Ширина на поверхности 10 м +INITIAL_TEMP = 5.0 # Начальная температура грунта 5 °C +CELL_SIZE = 0.1 # Размер ячейки 10 см + +# Выполнение инициализации и визуализация +initial_data = initialize_trapezoid_simulation( + depth_max=MAX_DEPTH, + length_bottom=WIDTH_BOTTOM, + length_top=WIDTH_TOP, + T_initial=INITIAL_TEMP, + dz_dx=CELL_SIZE +) + +print("\n--- Сводка по инициализации ---") +print(f"Размеры сетки (Z x X): {initial_data['N_Z']} x {initial_data['N_X']}") +print(f"Размер ячейки: {initial_data['DX']} м") + +# Теперь initial_data можно передать в цикл моделирования +# (который мы создавали ранее), чтобы начать расчеты. \ No newline at end of file diff --git a/12gui.py b/12gui.py new file mode 100644 index 0000000..b28a075 --- /dev/null +++ b/12gui.py @@ -0,0 +1,100 @@ +import numpy as np +import matplotlib.pyplot as plt +from matplotlib import cm +import h5py +import os + +def visualize_daily_profile(filename, day_number): + """ + Считывает 2D-профиль температуры для указанного дня из HDF5-файла + и визуализирует его. + + :param filename: Имя HDF5-файла с результатами моделирования. + :param day_number: Номер дня (индекс профиля) для визуализации. + Начинается с 0. + """ + if not os.path.exists(filename): + print(f"ОШИБКА: Файл '{filename}' не найден.") + return + + try: + with h5py.File(filename, 'r') as f: + # 1. Чтение метаданных + DZ = f.attrs['DZ'] + DX = f.attrs['DX'] + + # 2. Чтение основных наборов данных + temp_dset = f['temperature_profiles'] + mask_read = f['mask'][:] + + # Проверка границ дня + if day_number < 0 or day_number >= temp_dset.shape[0]: + print(f"ОШИБКА: День {day_number} находится вне диапазона.") + print(f"Доступный диапазон дней: 0 до {temp_dset.shape[0] - 1}.") + return + + # 3. Извлечение данных для конкретного дня + T_profile = temp_dset[day_number, :, :] + + # 4. Расчет координат + N_Z, N_X = T_profile.shape + X_COORD = np.linspace(0, N_X * DX, N_X) + Z_COORD = np.linspace(0, N_Z * DZ, N_Z) * -1 # Глубина отрицательна + + # 5. Определение диапазона цветов + # Читаем все данные для правильного Vmin/Vmax (это может быть медленно для очень больших файлов) + T_all = temp_dset[:].flatten() + T_min = np.nanmin(T_all) + T_max = np.nanmax(T_all) + + # 6. Настройка цветовой карты + cmap_base = plt.colormaps['RdYlBu'] + cmap_custom = cmap_base.copy() + cmap_custom.set_bad('lightgray') # Области вне трапеции (NaN) + + # 7. Визуализация + + fig, ax = plt.subplots(figsize=(10, 5)) + fig.suptitle(f'Профиль температуры грунта - День {day_number}', fontsize=14) + + im = ax.imshow(T_profile, + extent=[0, N_X * DX, -N_Z * DZ, 0], + origin='upper', + cmap=cmap_custom, + aspect='auto', + vmin=T_min, + vmax=T_max) + + # Наложение контура трапеции + ax.contour(X_COORD, Z_COORD, mask_read.astype(int), levels=[0.5], colors='k', linewidths=1.5, linestyles='--') + + ax.set_title(f'Температура на поверхности: {T_profile[0, int(N_X/2)]:.2f} °C') + ax.set_xlabel('Длина, м') + ax.set_ylabel('Глубина, м') + + # Добавление цветовой шкалы + cbar = fig.colorbar(im, ax=ax, orientation='vertical', fraction=0.04, pad=0.04) + cbar.set_label('Температура, °C') + + plt.tight_layout() + plt.show() + + except Exception as e: + print(f"Произошла ошибка при обработке данных HDF5: {e}") + +# ---------------------------------------------------------------------- +# 🌟 ПРИМЕР ИСПОЛЬЗОВАНИЯ ИНТЕРФЕЙСА +# ---------------------------------------------------------------------- + +FILENAME = 'temperature_simulation_results.hdf5' + +# Пример 1: Профиль в разгар зимы (День 180) +print("Визуализация дня 180 (Пик холода)...") +visualize_daily_profile(FILENAME, 180) + +# Пример 2: Профиль в конце моделирования (День 364) +print("\nВизуализация дня 364 (Конец года)...") +visualize_daily_profile(FILENAME, 364) + +# Пример 3: Попытка визуализировать несуществующий день +# visualize_daily_profile(FILENAME, 400) \ No newline at end of file diff --git a/2.py b/2.py new file mode 100644 index 0000000..c39454c --- /dev/null +++ b/2.py @@ -0,0 +1,47 @@ +import numpy as np +import matplotlib.pyplot as plt + +# Define the dimensions of the trapezoid +base1 = 5 +base2 = 3 +height = 4 + +# Calculate the width of the rectangle that can be cut from each side of the trapezoid +rect_width = (base1 + base2) / 2 + +# Cut off two rectangles from the trapezoid +trap_points = np.array([[0, 0], [base1, 0], [base1, height], [0, height]]) +rect_points = np.array([[0, 0], [rect_width, 0], [rect_width, height], [0, height]]) +trap_cut_points = np.array([[rect_width, 0], [base2, 0], [base2, height], [rect_width, height]]) + +# Plot the original trapezoid and cut off rectangles +plt.fill(trap_points[:, 0], trap_points[:, 1], color='gray') +plt.fill(rect_points[:, 0], rect_points[:, 1], color='blue') +plt.fill(trap_cut_points[:, 0], trap_cut_points[:, 1], color='blue') + +# Calculate the size of the remaining triangle +triangle_width = base2 - rect_width +triangle_height = (base2 * height) / base1 + +# Cut off the triangle from the trapezoid +tri_points = np.array([[rect_width, 0], [base2, 0], [(base2 + rect_width) / 2, height]]) +tri_cut_points = np.array([[(base2 + rect_width) / 2, 0], [(base2 + rect_width) / 2, triangle_height], [rect_width, triangle_height]]) + +# Plot the remaining triangle and cut off triangles +plt.fill(tri_points[:, 0], tri_points[:, 1], color='green') +plt.fill(tri_cut_points[:, 0], tri_cut_points[:, 1], color='green') + +# Calculate the size of the small squares +small_square_size = min(rect_width, triangle_height) / 2 + +# Cut off the small squares from the rectangle and triangle +rect_small_squares_points = np.array([[0, 0], [small_square_size, 0], [small_square_size, small_square_size], [0, small_square_size]]) +tri_small_squares_points = np.array([[(base2 + rect_width) / 2 - small_square_size, small_square_size], [(base2 + rect_width) / 2, 0], [(base2 + rect_width) / 2 - small_square_size, 0]]) + +# Plot the small squares +plt.fill(rect_small_squares_points[:, 0], rect_small_squares_points[:, 1], color='red') +plt.fill(tri_small_squares_points[:, 0], tri_small_squares_points[:, 1], color='red') + +# Show the plot +plt.axis('scaled') +plt.show() diff --git a/3.py b/3.py new file mode 100644 index 0000000..b9028a7 --- /dev/null +++ b/3.py @@ -0,0 +1,51 @@ +import matplotlib.pyplot as plt +import matplotlib.patches as patches + +def draw_trapezoid(a, b, h): + fig, ax = plt.subplots() + + # Рисуем трапецию + trapezoid = patches.Polygon([(0, 0), (a, 0), (b, h), (0, h)], closed=True, fill=None, edgecolor='r') + ax.add_patch(trapezoid) + + # Разбиваем трапецию на квадраты + split_trapezoid(a, b, h, ax) + + # Устанавливаем пределы осей + ax.set_xlim(-1, max(a, b) + 1) + ax.set_ylim(-1, h + 1) + ax.set_aspect('equal') + + plt.show() + +def split_trapezoid(a, b, h, ax): + if a == 0 or b == 0 or h == 0: + return + + # Найдите самый большой квадрат, который можно вписать в трапецию + largest_square_side = h + + # Поместите квадрат в трапецию + place_square(largest_square_side, 0, 0, ax) + + # Разделите оставшуюся часть трапеции + remaining_a = a - largest_square_side + remaining_b = b - largest_square_side + + # Повторите процесс для новых трапеций + if remaining_a > 0: + split_trapezoid(remaining_a, b, h, ax) + if remaining_b > 0: + split_trapezoid(a, remaining_b, h, ax) + +def place_square(side, x, y, ax): + # Функция для помещения квадрата в трапецию + square = patches.Rectangle((x, y), side, side, linewidth=1, edgecolor='b', facecolor='none') + ax.add_patch(square) + +# Пример использования +a = 10 # Длина верхнего основания трапеции +b = 20 # Длина нижнего основания трапеции +h = 5 # Высота трапеции + +draw_trapezoid(a, b, h) diff --git a/4.py b/4.py new file mode 100644 index 0000000..268aec6 --- /dev/null +++ b/4.py @@ -0,0 +1,52 @@ +import matplotlib.pyplot as plt +import matplotlib.patches as patches + +def draw_trapezoid(a, b, h): + fig, ax = plt.subplots() + + # Рисуем трапецию + trapezoid = patches.Polygon([(0, 0), (a, 0), (b, h), (0, h)], closed=True, fill=None, edgecolor='r') + ax.add_patch(trapezoid) + + # Разбиваем трапецию на квадраты + split_trapezoid(a, b, h, ax, 0, 0) + + # Устанавливаем пределы осей + ax.set_xlim(-1, max(a, b) + 1) + ax.set_ylim(-1, h + 1) + ax.set_aspect('equal') + + plt.show() + +def split_trapezoid(a, b, h, ax, x_offset, y_offset): + if a <= 0 or b <= 0 or h <= 0: + return + + # Найдите самый большой квадрат, который можно вписать в трапецию + largest_square_side = min(a, b, h) + + # Поместите квадрат в трапецию + place_square(largest_square_side, x_offset, y_offset, ax) + + # Разделите оставшуюся часть трапеции + remaining_a = a - largest_square_side + remaining_b = b - largest_square_side + remaining_h = h - largest_square_side + + # Повторите процесс для новых трапеций + if remaining_a > 0 and remaining_h > 0: + split_trapezoid(remaining_a, b, remaining_h, ax, x_offset + largest_square_side, y_offset) + if remaining_b > 0 and remaining_h > 0: + split_trapezoid(a, remaining_b, remaining_h, ax, x_offset, y_offset + largest_square_side) + +def place_square(side, x, y, ax): + # Функция для помещения квадрата в трапецию + square = patches.Rectangle((x, y), side, side, linewidth=1, edgecolor='b', facecolor='none') + ax.add_patch(square) + +# Пример использования +a = 10 # Длина верхнего основания трапеции +b = 20 # Длина нижнего основания трапеции +h = 5 # Высота трапеции + +draw_trapezoid(a, b, h) diff --git a/5.py b/5.py new file mode 100644 index 0000000..c5ca0b0 --- /dev/null +++ b/5.py @@ -0,0 +1,55 @@ +import matplotlib.pyplot as plt +import numpy as np + +# Функция для создания координат трапеции +def trapezoid(a, b, h): + # Точки четырехугольника трапеции + x = [-(a/2), -(b/2), b/2, a/2, -(a/2)] + y = [0, h, h, 0, 0] + return x, y + +# Функция для рисования квадратов внутри трапеции +def draw_squares_in_trapezoid(a, b, h, square_size): + fig, ax = plt.subplots() + + # Координаты трапеции + x_trap, y_trap = trapezoid(a, b, h) + + # Рисуем трапецию + ax.plot(x_trap, y_trap, 'b') + + # Высота и шаги по оси y + current_y = 0 + while current_y + square_size <= h: + # Находим ширину трапеции на уровне current_y + width_at_y = b + (a - b) * (current_y / h) + + # Количество квадратов в текущем ряду + num_squares_in_row = int(width_at_y // square_size) + + # Начальная точка для отрисовки квадратов по оси x + start_x = -(num_squares_in_row * square_size) / 2 + + # Рисуем квадраты в ряду + for i in range(num_squares_in_row): + square = plt.Rectangle((start_x + i * square_size, current_y), square_size, square_size, + edgecolor='black', facecolor='none') + ax.add_patch(square) + + # Переходим на следующий ряд + current_y += square_size + + ax.set_aspect('equal') + plt.xlim(-a / 2 - 1, a / 2 + 1) + plt.ylim(0, h + 1) + plt.title("Разбиение трапеции на квадраты") + plt.grid(True) + plt.show() + +# Задаем размеры трапеции и квадрата +a = 10 # длина большего основания +b = 6 # длина меньшего основания +h = 8 # высота +square_size = 1 # сторона квадрата + +draw_squares_in_trapezoid(a, b, h, square_size) diff --git a/6.py b/6.py new file mode 100644 index 0000000..73c997c --- /dev/null +++ b/6.py @@ -0,0 +1,61 @@ +import matplotlib.pyplot as plt +import numpy as np + +def draw_trapezoid_with_squares(a, b, h, square_size): + """ + Рисует трапецию с квадратами внутри. + + Параметры: + a (float): Верхнее основание трапеции. + b (float): Нижнее основание трапеции. + h (float): Высота трапеции. + square_size (float): Сторона квадрата. + """ + + # Функция для вычисления ширины трапеции на уровне y + def width_at_height(y): + return b - (b - a) * (y / h) + + # Параметры для построения графика + fig, ax = plt.subplots() + + # Стартовая высота + y = 0 + + # Проходим по каждому уровню, начиная с нижнего + while y < h: + # Вычисляем ширину трапеции на текущем уровне + current_width = width_at_height(y) + + # Определяем левый и правый край на уровне + left_x = -(current_width / 2) + right_x = current_width / 2 + + # Заполняем уровень квадратами + x = left_x + while x + square_size <= right_x: + # Рисуем квадрат + square = plt.Rectangle((x, y), square_size, square_size, edgecolor='black', facecolor='blue', fill=True) + ax.add_patch(square) + x += square_size + + # Если осталась неполная часть, рисуем неполный квадрат + if x < right_x: + square = plt.Rectangle((x, y), right_x - x, square_size, edgecolor='black', facecolor='blue', fill=True) + ax.add_patch(square) + + # Переходим на следующий уровень + y += square_size + + # Рисуем саму трапецию + trapezoid = np.array([[-b/2, 0], [b/2, 0], [a/2, h], [-a/2, h], [-b/2, 0]]) + ax.plot(trapezoid[:, 0], trapezoid[:, 1], color='black') + + # Настройки графика + ax.set_aspect('equal') + plt.xlim(-b/2 - 1, b/2 + 1) + plt.ylim(0, h + square_size) + plt.show() + +# Пример использования +draw_trapezoid_with_squares(a=6, b=10, h=8, square_size=1) diff --git a/7-1.py b/7-1.py new file mode 100644 index 0000000..480792c --- /dev/null +++ b/7-1.py @@ -0,0 +1,16 @@ + +import numpy as np +import matplotlib.pyplot as plt + +# Define the dimensions of the trapezoid +base1 = 5 +base2 = 3 +height = 4 + +# Plot the trapezoid +trap_points = np.array([[0, 0], [base1, 0], [base1, height], [0, height]]) +plt.fill(trap_points[:, 0], trap_points[:, 1], color='gray') + +# Show the plot +plt.axis('scaled') +plt.show() diff --git a/7.py b/7.py new file mode 100644 index 0000000..c76a58b --- /dev/null +++ b/7.py @@ -0,0 +1,47 @@ +import numpy as np +import matplotlib.pyplot as plt + +# Define the dimensions of the trapezoid +base1 = 5 +base2 = 3 +height = 4 + +# Calculate the width of the rectangle that can be cut from each side of the trapezoid +rect_width = (base1 + base2) / 2 + +# Cut off two rectangles from the trapezoid +trap_points = np.array([[0, 0], [base1, 0], [base1, height], [0, height]]) +rect_points = np.array([[0, 0], [rect_width, 0], [rect_width, height], [0, height]]) +trap_cut_points = np.array([[rect_width, 0], [base2, 0], [base2, height], [rect_width, height]]) + +# Plot the original trapezoid and cut off rectangles +plt.fill(trap_points[:, 0], trap_points[:, 1], color='gray') +plt.fill(rect_points[:, 0], rect_points[:, 1], color='blue') +plt.fill(trap_cut_points[:, 0], trap_cut_points[:, 1], color='blue') + +# Calculate the size of the remaining triangle +triangle_width = base2 - rect_width +triangle_height = (base2 * height) / base1 + +# Cut off the triangle from the trapezoid +tri_points = np.array([[rect_width, 0], [base2, 0], [(base2 + rect_width) / 2, height]]) +tri_cut_points = np.array([[(base2 + rect_width) / 2, 0], [(base2 + rect_width) / 2, triangle_height], [rect_width, triangle_height]]) + +# Plot the remaining triangle and cut off triangles +plt.fill(tri_points[:, 0], tri_points[:, 1], color='green') +plt.fill(tri_cut_points[:, 0], tri_cut_points[:, 1], color='green') + +# Calculate the size of the small squares +small_square_size = min(rect_width, triangle_height) / 2 + +# Cut off the small squares from the rectangle and triangle +rect_small_squares_points = np.array([[0, 0], [small_square_size, 0], [small_square_size, small_square_size], [0, small_square_size]]) +tri_small_squares_points = np.array([[(base2 + rect_width) / 2 - small_square_size, small_square_size], [(base2 + rect_width) / 2, 0], [(base2 + rect_width) / 2 - small_square_size, 0]]) + +# Plot the small squares +plt.fill(rect_small_squares_points[:, 0], rect_small_squares_points[:, 1], color='red') +plt.fill(tri_small_squares_points[:, 0], tri_small_squares_points[:, 1], color='red') + +# Show the plot +plt.axis('scaled') +plt.show() \ No newline at end of file diff --git a/8.py b/8.py new file mode 100644 index 0000000..051dde0 --- /dev/null +++ b/8.py @@ -0,0 +1,75 @@ +import numpy as np +import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d.art3d import Poly3DCollection +import matplotlib.colors as mcolors + +# Определяем новые параметры трапеции +height = 200000 # Высота трапеции увеличена до 200000 см +top_width = 8 # Ширина верхней стороны +bottom_width = 12 # Ширина нижней стороны +depth = 8 # Глубина трапеции + +# Генерация температуры на каждом уровне z (реверсированная) +def calculate_temperature(z): + # Температура изменяется от 0°C у основания до 100°C на вершине + return 100 * (z / height) + +# Сетка для разбиения трапеции на кубы +# Чтобы избежать слишком больших затрат памяти, увеличим шаг кубов до, например, 10000 см. +x_step, y_step, z_step = 1000, 1000, 10000 +x_range = np.arange(0, bottom_width, x_step) +y_range = np.arange(0, depth, y_step) +z_range = np.arange(0, height, z_step) + +fig = plt.figure(figsize=(10, 8)) +ax = fig.add_subplot(111, projection='3d') + +# Нормализация и палитра цветов +cmap = plt.get_cmap("coolwarm") +norm = mcolors.Normalize(vmin=0, vmax=100) + +# Функция для добавления куба к визуализации +def add_cube(ax, x, y, z, temperature): + vertices = [ + [x, y, z], [x+x_step, y, z], [x+x_step, y+y_step, z], [x, y+y_step, z], # нижняя грань + [x, y, z+z_step], [x+x_step, y, z+z_step], [x+x_step, y+y_step, z+z_step], [x, y+y_step, z+z_step] # верхняя грань + ] + edges = [ + [vertices[j] for j in [0, 1, 2, 3]], # нижняя грань + [vertices[j] for j in [4, 5, 6, 7]], # верхняя грань + [vertices[j] for j in [0, 1, 5, 4]], # боковая грань + [vertices[j] for j in [2, 3, 7, 6]], # боковая грань + [vertices[j] for j in [0, 3, 7, 4]], # передняя грань + [vertices[j] for j in [1, 2, 6, 5]] # задняя грань + ] + + # Определяем цвет в зависимости от температуры + color = cmap(norm(temperature)) + + ax.add_collection3d(Poly3DCollection(edges, color=color, edgecolor='black', linewidths=0.1, alpha=0.7)) + +# Заполняем трапецию кубами +for z in z_range: + # Линейная интерполяция для ширины на каждом уровне высоты + width = top_width + (bottom_width - top_width) * (height - z) / height + x_min = (bottom_width - width) / 2 + x_max = x_min + width + for x in np.arange(x_min, x_max, x_step): + for y in y_range: + temperature = calculate_temperature(z) + add_cube(ax, x, y, z, temperature) + +# Настройки графика +ax.set_xlabel("X") +ax.set_ylabel("Y") +ax.set_zlabel("Z") +ax.set_xlim(0, bottom_width) +ax.set_ylim(0, depth) +ax.set_zlim(0, height) + +# Создаём цветовую шкалу +mappable = plt.cm.ScalarMappable(cmap=cmap, norm=norm) +mappable.set_array([]) +plt.colorbar(mappable, ax=ax, label="Температура (°C)") + +plt.show() diff --git a/9.py b/9.py new file mode 100644 index 0000000..6daf428 --- /dev/null +++ b/9.py @@ -0,0 +1,37 @@ +import numpy as np +import csv + +# Параметры трапеции +height = 200000 # Высота трапеции +top_width = 8 # Ширина верхней стороны +bottom_width = 12 # Ширина нижней стороны +depth = 8 # Глубина трапеции + +# Функция для вычисления температуры в зависимости от высоты z +def calculate_temperature(z): + # Температура изменяется от 0°C у основания до 100°C на вершине + return 100 * (z / height) + +# Имя файла для сохранения данных +filename = "trapezoid_cubes_data.csv" + +# Открываем файл для записи +with open(filename, mode='w', newline='') as file: + writer = csv.writer(file) + # Записываем заголовки столбцов + writer.writerow(["x", "y", "z", "temperature"]) + + # Заполняем трапецию кубиками 1x1x1 см + for z in range(height): + # Линейная интерполяция для ширины на каждом уровне высоты + width = top_width + (bottom_width - top_width) * (height - z) / height + x_min = (bottom_width - width) / 2 + x_max = x_min + width + temperature = calculate_temperature(z) + + for x in range(int(x_min), int(x_max)): + for y in range(depth): + # Записываем координаты центра кубика и его температуру + writer.writerow([x + 0.5, y + 0.5, z + 0.5, temperature]) + +print(f"Данные успешно сохранены в файл {filename}")