Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > HTML и CSS
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.11.2024, 05:25   #121
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Столбы 1
Код:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from skimage import measure
import os

def generate_tube_field(shape, num_tubes, tube_length, tube_radius):
    array = np.zeros(shape, dtype=float)
    for _ in range(num_tubes):
        x, y = np.random.randint(0, shape[0]), np.random.randint(0, shape[1])
        z = 0
        for _ in range(tube_length):
            if 0 <= x < shape[0] and 0 <= y < shape[1] and 0 <= z < shape[2]:
                for i in range(-tube_radius, tube_radius + 1):
                    for j in range(-tube_radius, tube_radius + 1):
                        if i ** 2 + j ** 2 <= tube_radius ** 2:
                            xi = np.clip(x + i, 0, shape[0] - 1)
                            yi = np.clip(y + j, 0, shape[1] - 1)
                            array[xi, yi, z] = 1.0
            z += 1
    return array

# Параметры
shape = (64, 64, 64)  # Размеры 3D массива
num_tubes = 10  # Количество труб
tube_length = 64  # Длина труб
tube_radius = 3  # Радиус труб

# Генерация 3D-поля с трубами
tube_field = generate_tube_field(shape, num_tubes, tube_length, tube_radius)

# Создание изосурфейса из 3D-поля
verts, faces, _, _ = measure.marching_cubes(tube_field, level=0.5)

# Сохранение изосурфейса в OBJ файл
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
filename = os.path.join(desktop_path, "tube.obj")
with open(filename, "w") as f:
    for j, vert in enumerate(verts):
        f.write(f"v {vert[0]} {vert[1]} {vert[2]}\n")
    for face in faces:
        f.write(f"f {face[0]+1} {face[1]+1} {face[2]+1}\n")
print(f"Model saved as {filename}")

# Визуализация
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], faces, verts[:, 2], color='r', alpha=0.5)
plt.show()
MakarovDs вне форума Ответить с цитированием
Старый 02.11.2024, 05:34   #122
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Столбы щебёнок
Код:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import random
from scipy.interpolate import interp1d
import os
import math

# Генерация поверхности кожи
def generate_skin_surface(xmin, xmax, ymin, ymax, zmin, zmax, nx, ny):
    x = np.linspace(xmin, xmax, nx)
    y = np.linspace(ymin, ymax, ny)
    X, Y = np.meshgrid(x, y)
    Z = np.ones(X.shape) * zmin
    return X, Y, Z

def generate_hair(X, Y, Z, num_hairs, hair_length, hair_radius):
    hair_x_tube = []
    hair_y_tube = []
    hair_z_tube = []

    for _ in range(num_hairs):
        hair_x = random.uniform(X.min(), X.max())
        hair_y = random.uniform(Y.min(), Y.max())
        hair_z = Z.min()

        hair_t = np.linspace(0, 1, 100)
        hair_x_interp = np.linspace(hair_x, hair_x, 100)
        hair_y_interp = np.linspace(hair_y, hair_y, 100)
        hair_z_interp = np.linspace(hair_z, hair_z + hair_length, 100)

        hair_theta = np.linspace(0, 2*np.pi, 100)

        hair_x_tube_local = []
        hair_y_tube_local = []
        hair_z_tube_local = []

        for i in range(len(hair_x_interp)):
            for j in range(len(hair_theta)):
                hair_x_tube_local.append(hair_x_interp[i] + hair_radius * np.cos(hair_theta[j]))
                hair_y_tube_local.append(hair_y_interp[i] + hair_radius * np.sin(hair_theta[j]))
                hair_z_tube_local.append(hair_z_interp[i])

        hair_x_tube.extend(hair_x_tube_local)
        hair_y_tube.extend(hair_y_tube_local)
        hair_z_tube.extend(hair_z_tube_local)

        # Добавить пустые значения для разделения труб
        hair_x_tube.extend([np.nan]*len(hair_theta))
        hair_y_tube.extend([np.nan]*len(hair_theta))
        hair_z_tube.extend([np.nan]*len(hair_theta))

    # Сделать трубы более округлыми
    for i in range(len(hair_x_tube)):
        if not np.isnan(hair_x_tube[i]):
            hair_x_tube[i] += random.uniform(-0.1, 0.1)
            hair_y_tube[i] += random.uniform(-0.1, 0.1)

    return hair_x_tube, hair_y_tube, hair_z_tube

# Визуализация поверхности и волос
def visualize_surface_and_hair(X, Y, Z, hair_x, hair_y, hair_z):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.5)

    num_hairs = len(hair_x) // 100
    for i in range(num_hairs):
        hair_x_local = hair_x[i*100:(i+1)*100]
        hair_y_local = hair_y[i*100:(i+1)*100]
        hair_z_local = hair_z[i*100:(i+1)*100]
        ax.plot(hair_x_local, hair_y_local, hair_z_local, 'k-')

    plt.show()

# Сохранение файла
def save_file(X, Y, Z, hair_x, hair_y, hair_z):
    desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
    filename = os.path.join(desktop_path, "skin_and_hair.obj")
    with open(filename, "w") as f:
        for i in range(X.shape[0]):
            for j in range(X.shape[1]):
                f.write(f"v {X[i, j]} {Z[i, j]} {Y[i, j]}\n")
        for i in range(len(hair_x)):
            f.write(f"v {hair_x[i]} {hair_z[i]} {hair_y[i]}\n")
        for i in range(X.shape[0] - 1):
            for j in range(X.shape[1] - 1):
                f.write(f"f {i * X.shape[1] + j + 1} {(i + 1) * X.shape[1] + j + 1} {(i + 1) * X.shape[1] + j + 2}\n")
                f.write(f"f {i * X.shape[1] + j + 1} {(i + 1) * X.shape[1] + j + 2} {i * X.shape[1] + j + 2}\n")
        num_hairs = len(hair_x) // 100
        for i in range(num_hairs):
            for j in range(100):
                idx1 = i * 100 + j
                idx2 = i * 100 + (j + 1) % 100
                idx3 = (i + 1) * 100 + (j + 1) % 100
                idx4 = (i + 1) * 100 + j

                f.write(f"f {X.shape[0] * X.shape[1] + idx1 + 1} {X.shape[0] * X.shape[1] + idx2 + 1} {X.shape[0] * X.shape[1] + idx3 + 1}\n")
                f.write(f"f {X.shape[0] * X.shape[1] + idx1 + 1} {X.shape[0] * X.shape[1] + idx3 + 1} {X.shape[0] * X.shape[1] + idx4 + 1}\n")
    print(f"Файл сохранен как {filename}")

# Основная функция
def main():
    X, Y, Z = generate_skin_surface(-10, 10, -10, 10, 0, 10, 100, 100)
    num_hairs = random.randint(3, 120)
    hair_length = 5
    hair_radius = 0.1
    hair_x, hair_y, hair_z = generate_hair(X, Y, Z, num_hairs, hair_length, hair_radius)
    visualize_surface_and_hair(X, Y, Z, hair_x, hair_y, hair_z)
    save_file(X, Y, Z, hair_x, hair_y, hair_z)

if __name__ == "__main__":
    main()
MakarovDs вне форума Ответить с цитированием
Старый 02.11.2024, 18:58   #123
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Просто шумовая равномерная поверхность
Код:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import random

# Генерация поверхности
def generate_surface(xmin, xmax, ymin, ymax, zmin, zmax, nx, ny):
    x = np.linspace(xmin, xmax, nx)
    y = np.linspace(ymin, ymax, ny)
    x, y = np.meshgrid(x, y)
    z = np.random.uniform(zmin, zmax, size=(ny, nx))
    return x, y, z

# Генерация волос
def generate_hair(x, y, z, length, thickness):
    hair_x = []
    hair_y = []
    hair_z = []
    for i in range(len(x)):
        for j in range(len(y)):
            if np.random.uniform(0, 1) < 0.1:  # вероятность появления волоса
                hair_x.append(x[i, j])
                hair_y.append(y[i, j])
                hair_z.append(z[i, j] + np.random.uniform(0, length))
                for k in range(int(length / thickness)):
                    hair_x.append(x[i, j])
                    hair_y.append(y[i, j])
                    hair_z.append(z[i, j] + (k + 1) * thickness)
    return hair_x, hair_y, hair_z

# Генерация труб
def generate_tube(x, y, z, radius, length):
    tube_x = []
    tube_y = []
    tube_z = []
    theta = np.linspace(0, 2*np.pi, 100)
    for i in range(5):  # генерируем 5 труб
        for k in range(int(length / 0.1)):
            for l in range(len(theta)):
                tube_x.append(x[50, 50] + radius * np.cos(theta[l]))
                tube_y.append(y[50, 50] + radius * np.sin(theta[l]))
                tube_z.append(z[50, 50] + k * 0.1)
    return tube_x, tube_y, tube_z

# Создание меша для труб
def create_mesh(tube_x, tube_y, tube_z):
    vertices = []
    faces = []
    theta = np.linspace(0, 2*np.pi, 100)
    for i in range(len(tube_x) // len(theta) - 1):
        for j in range(len(theta) - 1):
            idx1 = i * len(theta) + j
            idx2 = (i + 1) * len(theta) + j
            idx3 = (i + 1) * len(theta) + (j + 1)
            idx4 = i * len(theta) + (j + 1)
            vertices.append([[tube_x[idx1], tube_y[idx1], tube_z[idx1]],
                            [tube_x[idx2], tube_y[idx2], tube_z[idx2]],
                            [tube_x[idx3], tube_y[idx3], tube_z[idx3]]])
            vertices.append([[tube_x[idx1], tube_y[idx1], tube_z[idx1]],
                            [tube_x[idx3], tube_y[idx3], tube_z[idx3]],
                            [tube_x[idx4], tube_y[idx4], tube_z[idx4]]])
    return vertices, faces

# Визуализация поверхности и волос
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x, y, z = generate_surface(-10, 10, -10, 10, 0, 1, 100, 100)
tube_x, tube_y, tube_z = generate_tube(x, y, z, 0.1, 5)
vertices, faces = create_mesh(tube_x, tube_y, tube_z)

ax.plot_surface(x, y, z, cmap='viridis', alpha=0.5)
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
mesh = Poly3DCollection(vertices, facecolors='b', alpha=0.5)
ax.add_collection3d(mesh)

# Сохранение файла в OBJ
import os
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
filename = os.path.join(desktop_path, "surface_with_tube.obj")
with open(filename, "w") as f:
    for i in range(len(x)):
        for j in range(len(y)):
            f.write(f"v {x[i, j]} {y[i, j]} {z[i, j]}\n")
    for i in range(len(vertices)):
        f.write(f"v {vertices[i][0]} {vertices[i][1]} {vertices[i][2]}\n")
    for i in range(len(x) - 1):
        for j in range(len(y) - 1):
            f.write(f"f {i * len(y) + j + 1} {(i + 1) * len(y) + j + 1} {(i + 1) * len(y) + j + 2}\n")
            f.write(f"f {i * len(y) + j + 1} {(i + 1) * len(y) + j + 2} {i * len(y) + j + 2}\n")
    for i in range(len(faces)):
        f.write(f"f {faces[i][0] + 1 + len(x) * len(y)} {faces[i][1] + 1 + len(x) * len(y)} {faces[i][2] + 1 + len(x) * len(y)}\n")
print(f"Файл сохранен как {filename}")

plt.show()
MakarovDs вне форума Ответить с цитированием
Старый 02.11.2024, 22:56   #124
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Столбы 2
Код:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from skimage import measure
import os

def generate_tube_field(shape, num_tubes, tube_length, tube_radius):
    array = np.zeros(shape, dtype=float)
    for _ in range(num_tubes):
        x, y = np.random.randint(0, shape[0]), np.random.randint(0, shape[1])
        z = 0
        while z < tube_length:
            if 0 <= x < shape[0] and 0 <= y < shape[1] and 0 <= z < shape[2]:
                # Создайте двумерную гауссову функцию для круглого поперечного сечения
                xx, yy = np.meshgrid(np.arange(shape[0]) - x, np.arange(shape[1]) - y)
                gaussian = (1 / (2 * np.pi * tube_radius ** 2)) * np.exp(-(xx ** 2 + yy ** 2) / (2 * tube_radius ** 2))
                array[z, :, :] += gaussian
            z += 1
    return array

# Параметры
shape = (64, 64, 64) 
num_tubes = 10  
tube_length = 64  
tube_radius = 3  

# Создайте трехмерное поле с помощью круглых трубок
tube_field = generate_tube_field(shape, num_tubes, tube_length, tube_radius)

# Создание изоповерхности из трехмерного поля
verts, faces, _, _ = measure.marching_cubes(tube_field, level=0.5 * np.max(tube_field))

# Сохраните изурфейса в OBJ-файл
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
filename = os.path.join(desktop_path, "round_tube.obj")
with open(filename, "w") as f:
    for j, vert in enumerate(verts):
        f.write(f"v {vert[0]:.4f} {vert[1]:.4f} {vert[2]:.4f}\n")
    for face in faces:
        f.write(f"f {face[0]+1} {face[1]+1} {face[2]+1}\n")
print(f"Model saved as {filename}")

# визуализация
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], faces, verts[:, 2], color='r', alpha=0.5)
plt.show()

Последний раз редактировалось MakarovDs; 02.11.2024 в 23:58.
MakarovDs вне форума Ответить с цитированием
Старый 02.11.2024, 23:51   #125
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Столбы 3
Код:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from skimage import measure
import os

def generate_tube_field(shape, num_tubes, tube_length, tube_radius, branch_prob=0.2):
    array = np.zeros(shape, dtype=float)
    for _ in range(num_tubes):
        x, y = np.random.randint(0, shape[0]), np.random.randint(0, shape[1])
        z = 0
        direction = np.random.choice([-1, 1], 2)
        while z < tube_length:
            if 0 <= x < shape[0] and 0 <= y < shape[1] and 0 <= z < shape[2]:
                # Создайте двумерную гауссову функцию для круглого поперечного сечения
                xx, yy = np.meshgrid(np.arange(shape[0]) - x, np.arange(shape[1]) - y)
                gaussian = (1 / (2 * np.pi * tube_radius ** 2)) * np.exp(-(xx ** 2 + yy ** 2) / (2 * tube_radius ** 2))
                array[z, :, :] += gaussian

                # Проверьте, следует ли нам разветвляться
                if np.random.rand() < branch_prob and z > 0:
                    new_direction = np.random.choice([-1, 1], 2)
                    if np.abs(new_direction - direction).sum() == 2:  # Убедитесь, что новое направление перпендикулярно текущему
                        direction = new_direction
                        x, y = x + direction[0] * tube_radius, y + direction[1] * tube_radius

            z += 1
    return array

# Параметры
shape = (64, 64, 64)  # Размеры трехмерного поля
num_tubes = 10  # Количество трубок
tube_length = 64  # Длина труб
tube_radius = 3  # Радиус труб
branch_prob = 0.2  # Вероятность ветвления по каждому z-индексу

# Создайте трехмерное поле с помощью круглых и разветвляющихся трубок
tube_field = generate_tube_field(shape, num_tubes, tube_length, tube_radius, branch_prob)

# Создание изоповерхности из трехмерного поля
verts, faces, _, _ = measure.marching_cubes(tube_field, level=0.5 * np.max(tube_field))

# Сохраните изурфейс в OBJ-файл
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
filename = os.path.join(desktop_path, "branching_tubes.obj")
with open(filename, "w") as f:
    for j, vert in enumerate(verts):
        f.write(f"v {vert[0]:.4f} {vert[1]:.4f} {vert[2]:.4f}\n")
    for face in faces:
        f.write(f"f {face[0]+1} {face[1]+1} {face[2]+1}\n")
print(f"Model saved as {filename}")

# Визуализация
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], faces, verts[:, 2], color='r', alpha=0.5)
plt.show()

Последний раз редактировалось MakarovDs; 03.11.2024 в 16:16.
MakarovDs вне форума Ответить с цитированием
Старый 03.11.2024, 00:08   #126
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Noodle биом как в майнкрафте
Код:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from skimage import measure
import os

def generate_tube_field(shape, num_tubes, tube_length, tube_radius):
    array = np.zeros(shape, dtype=float)
    for _ in range(num_tubes):
        # Параметры кривой
        x0, y0, z0 = np.random.randint(0, shape[0]), np.random.randint(0, shape[1]), np.random.randint(0, shape[2])
        r = np.random.randint(10, 20)  # радиус окружности
        theta = np.linspace(0, 2 * np.pi, tube_length)

        # Создаем кривую
        x = x0 + r * np.cos(theta)
        y = y0 + r * np.sin(theta)
        z = np.linspace(z0, z0 + tube_length, tube_length)

        # Заполняем массив
        for i in range(tube_length):
            if 0 <= x[i] < shape[0] and 0 <= y[i] < shape[1] and 0 <= z[i] < shape[2]:
                # Создайте двумерную гауссову функцию для круглого поперечного сечения
                xx, yy = np.meshgrid(np.arange(shape[0]) - x[i], np.arange(shape[1]) - y[i])
                gaussian = (1 / (2 * np.pi * tube_radius ** 2)) * np.exp(-(xx ** 2 + yy ** 2) / (2 * tube_radius ** 2))
                array[int(z[i]), :, :] += gaussian
    return array

# Параметры
shape = (64, 64, 64)  # Размеры трехмерного массива
num_tubes = 5  # Количество трубок
tube_length = 64  # Длина труб
tube_radius = 3  # Радиус труб

# Создание трехмерного поля круглых трубок
tube_field = generate_tube_field(shape, num_tubes, tube_length, tube_radius)

# Создание изоповерхности из трехмерного поля
verts, faces, _, _ = measure.marching_cubes(tube_field, level=0.5 * np.max(tube_field))

# Сохраните изурфейс в OBJ-файл
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
filename = os.path.join(desktop_path, "round_tube.obj")
with open(filename, "w") as f:
    for j, vert in enumerate(verts):
        f.write(f"v {vert[0]:.4f} {vert[1]:.4f} {vert[2]:.4f}\n")
    for face in faces:
        f.write(f"f {face[0]+1} {face[1]+1} {face[2]+1}\n")
print(f"Model saved as {filename}")

# Визуализация 
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], faces, verts[:, 2], color='r', alpha=0.5)
plt.show()

Последний раз редактировалось MakarovDs; 03.11.2024 в 16:14.
MakarovDs вне форума Ответить с цитированием
Старый 03.11.2024, 19:14   #127
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Решил сделать свой конвертер картинки в OBJ карту но получилось не то что нужно:
Код:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from skimage import measure
import os

def generate_surface(image_path, shape):
    # Чтение изображения
    image = np.array(plt.imread(image_path))

    # Преобразование изображения в черно-белое
    image_gray = np.dot(image[...,:3], [0.2989, 0.5870, 0.1140])

    # Создаем 3D массив для поверхности
    surface = np.zeros(shape, dtype=float)

    # Генерируем поверхность на основе изображения
    for x in range(shape[0]):
        for y in range(shape[1]):
            pixel_value = image_gray[x, y]
            height = 1.0 - pixel_value  # чем темнее пиксель, тем выше бугор
            surface[x, y, int(height * shape[2])] = 1.0

    return surface

def save_surface_to_obj(surface, filename):
    # Создание изосурфейса
    verts, faces, _, _ = measure.marching_cubes(surface, level=0.5)

    # Сохранение изосурфейса в OBJ файл
    with open(filename, "w") as f:
        for j, vert in enumerate(verts):
            f.write(f"v {vert[0]} {vert[1]} {vert[2]}\n")
        for face in faces:
            f.write(f"f {face[0]+1} {face[1]+1} {face[2]+1}\n")

def visualize_surface(surface):
    # Создание изосурфейса
    verts, faces, _, _ = measure.marching_cubes(surface, level=0.5)

    # Визуализация
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_trisurf(verts[:, 0], verts[:, 1], faces, verts[:, 2], color='r', alpha=0.5)
    plt.show()

# Параметры
image_path = r"Путь к файлу"
shape = (64, 64, 64)  # Размеры 3D массива
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
filename = os.path.join(desktop_path, "surface.obj")

# Генерация поверхности
surface = generate_surface(image_path, shape)

# Сохранение поверхности в OBJ файл
save_surface_to_obj(surface, filename)

# Визуализация поверхности
visualize_surface(surface)

print(f"Model saved as {filename}")

Потому что все эти конвертеры они под одну копирку сделаны, и делают просто шум вместо того что-бы сделать лабиринт:

Последний раз редактировалось MakarovDs; 03.11.2024 в 19:24.
MakarovDs вне форума Ответить с цитированием
Старый 03.11.2024, 20:21   #128
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Бэкрумс процедурная генерация но только на одном уровне.
Код:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from skimage import measure
from scipy.spatial import Delaunay
import os

# Функция для генерации 3D-поля с триангуляцией Делоне
def generate_delaunay_field(shape):
    array = np.zeros(shape, dtype=float)

    # Генерация кубов на фиксированной высоте
    points = []
    for _ in range(10):
        x = np.random.randint(10, shape[0] - 10)
        y = np.random.randint(10, shape[1] - 10)
        points.append([x, y, shape[2] // 2])  # Генерируем кубы на фиксированной высоте
        generate_cube(array, (x, y, shape[2] // 2), np.random.randint(4, 8))

    # Генерация коридоров между кубами
    for i in range(len(points) - 1):
        dx = points[i+1][0] - points[i][0]
        dy = points[i+1][1] - points[i][1]
        dz = 0  # Коридоры генерируются на фиксированной высоте
        length = int(np.sqrt(dx**2 + dy**2))
        for j in range(length):
            new_x = int(points[i][0] + j * dx // length)
            new_y = int(points[i][1] + j * dy // length)
            new_z = int(points[i][2])  # Коридоры генерируются на фиксированной высоте
            if 0 <= new_x < shape[0] and 0 <= new_y < shape[1] and 0 <= new_z < shape[2]:
                array[new_x, new_y, new_z] = 1.0
                # Делаем коридоры более жирными
                for k in range(-2, 3):
                    for l in range(-2, 3):
                        for m in range(-2, 3):
                            x1, y1, z1 = new_x + k, new_y + l, new_z + m
                            if 0 <= x1 < shape[0] and 0 <= y1 < shape[1] and 0 <= z1 < shape[2]:
                                array[x1, y1, z1] = 1.0

    return array

# Функция для генерации куба в заданной точке
def generate_cube(array, point, size):
    x, y, z = int(point[0]), int(point[1]), int(point[2])
    for i in range(-size, size+1):
        for j in range(-size, size+1):
            for k in range(-size, size+1):
                new_x, new_y, new_z = x + i, y + j, z + k
                if 0 <= new_x < array.shape[0] and 0 <= new_y < array.shape[1] and 0 <= new_z < array.shape[2]:
                    array[new_x, new_y, new_z] = 1.0

# Параметры
shape = (128, 128, 128)  # Размеры 3D массива

# Генерация 3D-поля с триангуляцией Делоне
delaunay_field = generate_delaunay_field(shape)

# Создание изосурфейса
verts, faces, _, _ = measure.marching_cubes(delaunay_field, level=0.5)

# Сохранение изосурфейса в OBJ файл
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
filename = os.path.join(desktop_path, "delaunay.obj")
with open(filename, "w") as f:
    for j, vert in enumerate(verts):
        f.write(f"v {vert[0]} {vert[1]} {vert[2]}\n")
    for face in faces:
        f.write(f"f {face[0]+1} {face[1]+1} {face[2]+1}\n")
print(f"Model saved as {filename}")

# Визуализация
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], verts[:, 2], color='r', alpha=0.5)
plt.show()
MakarovDs вне форума Ответить с цитированием
Старый 03.11.2024, 22:11   #129
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Мятые комнаты
Код:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from skimage import measure
from scipy.spatial import Delaunay
import os

# Функция для генерации 3D-поля с триангуляцией Делоне
def generate_delaunay_field(shape):
    array = np.zeros(shape, dtype=float)

    # Генерация кубов на фиксированной высоте
    points = []
    for _ in range(10):
        x = np.random.randint(10, shape[0] - 10)
        y = np.random.randint(10, shape[1] - 10)
        size = np.random.randint(4, 8)
        points.append([x, y, shape[2] // 2])  # Генерируем кубы на фиксированной высоте
        generate_cube(array, (x, y, shape[2] // 2), size)

    # Генерация коридоров между кубами
    for i in range(len(points) - 1):
        dx = points[i+1][0] - points[i][0]
        dy = points[i+1][1] - points[i][1]
        dz = 0  # Коридоры генерируются на фиксированной высоте
        length = int(np.sqrt(dx**2 + dy**2))
        for j in range(length):
            new_x = int(points[i][0] + j * dx // length)
            new_y = int(points[i][1] + j * dy // length)
            new_z = int(points[i][2])  # Коридоры генерируются на фиксированной высоте
            if 0 <= new_x < shape[0] and 0 <= new_y < shape[1] and 0 <= new_z < shape[2]:
                array[new_x, new_y, new_z] = 1.0
                # Делаем коридоры более жирными
                for k in range(-2, 3):
                    for l in range(-2, 3):
                        for m in range(-2, 3):
                            x1, y1, z1 = new_x + k, new_y + l, new_z + m
                            if 0 <= x1 < shape[0] and 0 <= y1 < shape[1] and 0 <= z1 < shape[2]:
                                array[x1, y1, z1] = 1.0

    return array

# Функция для генерации куба в заданной точке
def generate_cube(array, point, size):
    x, y, z = int(point[0]), int(point[1]), int(point[2])
    for i in range(-size, size+1):
        for j in range(-size, size+1):
            for k in range(-size, size+1):
                new_x, new_y, new_z = x + i, y + j, z + k
                if 0 <= new_x < array.shape[0] and 0 <= new_y < array.shape[1] and 0 <= new_z < array.shape[2]:
                    array[new_x, new_y, new_z] = 1.0

# Параметры
shape = (128, 128, 128)  # Размеры 3D массива

# Генерация 3D-поля с триангуляцией Делоне
delaunay_field = generate_delaunay_field(shape)

# Создание изосурфейса
verts, faces, _, _ = measure.marching_cubes(delaunay_field, level=0.5)
verts = verts + np.random.normal(0, 0.5, verts.shape)

# Сохранение изосурфейса в OBJ файл
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
filename = os.path.join(desktop_path, "delaunay.obj")
with open(filename, "w") as f:
    for j, vert in enumerate(verts):
        f.write(f"v {vert[0]} {vert[1]} {vert[2]}\n")
    for face in faces:
        f.write(f"f {face[0]+1} {face[1]+1} {face[2]+1}\n")
print(f"Model saved as {filename}")

# Визуализация
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], verts[:, 2], color='r', alpha=0.5)
plt.show()
MakarovDs вне форума Ответить с цитированием
Старый 04.11.2024, 01:54   #130
MakarovDs
Форумчанин
 
Аватар для MakarovDs
 
Регистрация: 10.01.2020
Сообщений: 337
По умолчанию

Короче я придумал свой тип фракталов так и будем их называть фракталы Макарова

Фракталы Макарова - это фракталы элементы самоподобия которых при каждой последующей итерации выбирают случайное самоподобие из последовательности самоподобий.

К примеру имеется последовательность фигур - 1)Квадрат 2)Круг 3)Ромб и скажем 123 итераций, 32 итерации - квадрат, 42 итерации - круг, 49 итерация - Ромб.

Код:
<html>
<head>
  <style>
    #tree {
      position: relative;
      cursor: pointer;
    }
  </style>
  <title>Дерево Пифагора</title>
  <center>
    <script type="text/javascript">
      // функция рисует под углом angle линию из указанной точки длиной ln
      function drawLine(x, y, ln, angle) {
        context.moveTo(x, y);
        context.lineTo(Math.round(x + ln * Math.cos(angle)), Math.round(y - ln * Math.sin(angle)));
      }

      // функция рисует квадрат
      function drawSquare(x, y, ln) {
        context.beginPath();
        context.rect(x, y, ln, ln);
        context.stroke();
      }

      // функция рисует круг
      function drawCircle(x, y, ln) {
        context.beginPath();
        context.arc(x, y, ln / 2, 0, 2 * Math.PI);
        context.stroke();
      }

      // функция рисует ромб
      function drawRhomb(x, y, ln) {
        context.beginPath();
        context.moveTo(x, y - ln / 2);
        context.lineTo(x + ln / 2, y);
        context.lineTo(x, y + ln / 2);
        context.lineTo(x - ln / 2, y);
        context.closePath();
        context.stroke();
      }

      // функция рисует дерево
      function drawTree(x, y, ln, minLn, angle) {
        if (ln > minLn) {
          ln = ln * 0.75;
          var random = Math.floor(Math.random() * 3); // случайный выбор самоподобия
          var figures = [drawSquare, drawCircle, drawRhomb]; // последовательность самоподобий
          figures[random](x, y, ln); // рисуем фигуру
          x = Math.round(x + ln * Math.cos(angle));
          y = Math.round(y - ln * Math.sin(angle));
          drawTree(x, y, ln, minLn, angle + Math.PI / 4);
          drawTree(x, y, ln, minLn, angle - Math.PI / 4);
        }
      }

      // Инициализация переменных
      function init() {
        var canvas = document.getElementById("tree"),
          x = 20 + (canvas.width / 2),
          y = -250 + canvas.height, // положение ствола
          ln = 120, // начальная длина линии
          minLn = 5; // минимальная длина линии
        canvas.width = 650; // ширина холста
        canvas.height = 600; // высота холста
        context = canvas.getContext('2d');

        context.fillStyle = '#fff'; // цвет фона
        context.strokeStyle = '#020'; // цвет линий
        context.fillRect(0, 0, canvas.width, canvas.height);
        context.lineWidth = 2; // ширина линий
        context.beginPath();
        drawTree(x, y, ln, minLn, Math.PI / 2);
        context.stroke();
      }

      function moveI() {
        intervalID = setInterval(init, 1000);
      }

      function moveII() {
        clearInterval(intervalID, 1000);
      }

      let intervalID;

      function MoveRight() {
        let start = Date.now();

        let timerI = setInterval(function() {
          let timePassed = Date.now() - start;

          tree.style.right = timePassed / 6 + 'px';

          if (timePassed > 2000) clearInterval(timerI);

        }, 20);
      }

      function MoveLeft() {
        let startI = Date.now();

        let timer = setInterval(function() {
          let timePassedI = Date.now() - startI;

          tree.style.left = timePassedI / 6 + 'px';

          if (timePassedI > 2000) clearInterval(timer);

        }, 20);
      }
    </script>
  </center>
</head>
<body>
  <table width="100%" border="1" cellspacing="1" cellpadding="4">
    <caption align="bottom"></caption>
    <tr>
      <th><input type="text" id="name" placeholder="положение ствола" onclick="(tree)"></th>
      <th><input type="text" id="nameI" placeholder="минимальная длина линии" onclick=""></th>
      <th><input type="text" id="nameII" placeholder="начальная длина линии" onclick="(this.innerHTML)"></th>
    </tr>
  </table>

  <table width="100%" border="1" cellspacing="1" cellpadding="4">
    <caption align="bottom">Generator Fractals</caption>
    <tr>
      <td>
        <button onclick="moveI()">Start Random Fractals</button>
        <button onclick="moveII()">Stop Random Fractals</button>
        <button onclick="MoveRight()">right</button>
        <button onclick="MoveUp()">Up</button>
        <button onclick="MoveDown()">Down</button>
        <button onclick="MoveLeft()">left</button>
      </td>
    </tr>
  </table>
  <br>
  <canvas id="tree"></canvas>
</body>
</html>

Последний раз редактировалось MakarovDs; 04.11.2024 в 01:57.
MakarovDs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
помогите с генератором слов Мой повелитель Общие вопросы C/C++ 6 27.02.2016 23:46
Зарубежные микроконтроллеры с встроенным ШИМ-генератором MyLastHit Компьютерное железо 6 22.10.2013 14:33
написание генератора фракталов Жюлиа kyzmich2370 Visual C++ 1 06.11.2012 09:57
Помогите с генератором чисел на Pascal vadmaruschak Помощь студентам 6 13.09.2009 17:06
Игры фракталов на VB Kail Свободное общение 1 29.05.2009 09:30