Eliguli / NYU-CAS-Meows-Corp-Association

1 stars 0 forks source link

Visualisation #5

Open Eliguli opened 1 week ago

Eliguli commented 1 week ago

Contour Set

import numpy as np
import matplotlib.pyplot as plt

def interpolate_color(start_color, end_color, t):
    return tuple(start_color[i] + t * (end_color[i] - start_color[i]) for i in range(3))

def reverse_color(color):
    return tuple(reversed(color))

def draw_binary_tree(ax, x, y, length, depth, max_depth):
    if depth > max_depth:
        return
    child_y = y - length
    length *= 1.05
    child_offset = 0.5 / (2 ** depth)

    left_x = x - child_offset
    right_x = x + child_offset

    start_color = (0, 0, 1)
    mid_color = (0.5, 0.5, 0.5)
    end_color = (0.5, 0, 0.5)

    if depth < max_depth / 2:
        color = interpolate_color(start_color, mid_color, 2 * depth / max_depth)
    else:
        color = interpolate_color(mid_color, end_color, 2 * depth / max_depth - 1)

    ax.plot([x, left_x], [y, child_y], color=color)
    ax.plot([x, right_x], [y, child_y], color=color)

    draw_binary_tree(ax, left_x, child_y, length, depth + 1, max_depth)
    draw_binary_tree(ax, right_x, child_y, length, depth + 1, max_depth)

def draw_tree(ax, x, y, length, angle, depth, max_depth):
    if depth > max_depth:
        return

    # Calculate the end point of the branch
    end_x = x + length * np.cos(angle)
    end_y = y - length * np.sin(angle)

    # Color changes from blue at the top to grey and then purple at the bottom
    start_color = (0, 0, 1)
    mid_color = (0.5, 0.5, 0.5)
    end_color = (0.5, 0, 0.5)

    if depth < max_depth / 2:
        color = reverse_color(interpolate_color(start_color, mid_color, 2 * depth / max_depth))
    else:
        color = reverse_color(interpolate_color(mid_color, end_color, 2 * depth / max_depth - 1))

    # Draw the branch
    ax.plot([x, end_x], [y, end_y], color=color)

    # Draw the left and right subtrees
    draw_tree(ax, end_x, end_y, length * 0.7, angle + np.pi / 6, depth + 1, max_depth)
    draw_tree(ax, end_x, end_y, length * 0.7, angle - np.pi / 6, depth + 1, max_depth)

fig, axs = plt.subplots(1, 2, figsize=(24, 12))
axs[0].set_aspect('equal')
axs[0].axis('off')

# Initial parameters for the binary tree
x = 0.5
y = 1
length = 0.1
max_depth = 5

draw_binary_tree(axs[0], x, y, length, 0, max_depth)

axs[1].set_aspect('equal')
axs[1].axis('off')

# Initial parameters for the other tree
x = 0.5
y = 1
length = 0.2
angle = np.pi / 2
max_depth = 5

draw_tree(axs[1], x, y, length, angle, 0, max_depth)

plt.show()

image

Sierpinski Polygon Fractal


import matplotlib.pyplot as plt
import numpy as np

def draw_pentagon(ax, center, size, rotation=0):
    angle = np.pi / 5  # 36 degrees in radians
    vertices = []
    for i in range(5):
        x = center[0] + size * np.sin((2 * i + 1) * angle + rotation)
        y = center[1] + size * np.cos((2 * i + 1) * angle + rotation)
        vertices.append((x, y))
    vertices.append(vertices[0])  # Close the pentagon

    ax.plot(*zip(*vertices), 'k-')
    return vertices

def draw_surrounding_pentagons(ax, center, size, pad, depth):
    if depth == 0:
        return

    # Factor and new size calculation for the initial center pentagon
    fact = 0
    new_size = size / (2 + fact + (np.sqrt(5) - 1) / 2)

    vertices = draw_pentagon(ax, center, new_size)

    # Calculate the centers and sizes for the surrounding pentagons
    for i in range(5):
        # Midpoint of the edge of the central pentagon
        mid_x = (vertices[i][0] + vertices[i+1][0]) / 2
        mid_y = (vertices[i][1] + vertices[i+1][1]) / 2

        # Reflection of the center of the inner pentagon through the midpoint of each edge
        new_center_x = (2 * mid_x - center[0]) * (1 + pad * 0.5)
        new_center_y = (2 * mid_y - center[1]) * (1 + pad * 0.5)

        # Rotation for the outer pentagon
        rotation = np.pi / 5  # Rotate by 36 degrees

        draw_pentagon(ax, (new_center_x, new_center_y), new_size, rotation)

        # Recursive call for the next level of surrounding pentagons
        draw_surrounding_pentagons(ax, (new_center_x, new_center_y), new_size, 0, depth-1)

fig, ax = plt.subplots(figsize=(12, 12))
ax.set_aspect('equal')
ax.axis('off')

# Parameters
center = (0, 0)
size = 1
pad = 0
depth = 6  # Number of recursive levels

draw_surrounding_pentagons(ax, center, size, pad, depth)

plt.show()

image

Pythagoras Tree

pythagoras_tree.py

import matplotlib.pyplot as plt
import numpy as np

def draw_polygon(ax, vertices, color):
    polygon = plt.Polygon(vertices, closed=True, edgecolor='black', facecolor=color)
    ax.add_patch(polygon)

def tree(ax, x1, y1, x2, y2, angle, depth, max_depth):
    color = (0.3, 0.2 + depth / 18, 0.1)
    if depth >= max_depth:
        # Draw a square at the last level
        dx = x2 - x1
        dy = y2 - y1
        x3 = x2 - dy
        y3 = y2 + dx
        x4 = x1 - dy
        y4 = y1 + dx
        draw_polygon(ax, [[x1, y1], [x2, y2], [x3, y3], [x4, y4]], color)
        return

    dx = x2 - x1
    dy = y2 - y1
    x3 = x2 - dy
    y3 = y2 + dx
    x4 = x1 - dy
    y4 = y1 + dx

    # Adjust x5 and y5 accordingly
    d = np.sqrt((x3 - x4) ** 2 + (y3 - y4) ** 2) * np.cos(angle)
    theta = np.arctan2(dy, dx)

    x5 = x4 + d * np.cos(angle + theta)
    y5 = y4 + d * np.sin(angle + theta)

    draw_polygon(ax, [[x1, y1], [x2, y2], [x3, y3], [x4, y4]], color)
    draw_polygon(ax, [[x3, y3], [x4, y4], [x5, y5]], color)

    d *= np.cos(angle)

    tree(ax, x4, y4, x5, y5, angle, depth + 1, max_depth)
    tree(ax, x5, y5, x3, y3, angle, depth + 1, max_depth)

coordinates.py

import numpy as np

def leftmost_x_coordinate(x1, y1, x2, y2, angle, depth, max_depth):
    if depth >= max_depth:
        dx = x2 - x1
        dy = y2 - y1
        x3 = x2 - dy
        x4 = x1 - dy
        return min(x1, x2, x3, x4)

    dx = x2 - x1
    dy = y2 - y1
    x3 = x2 - dy
    y3 = y2 + dx
    x4 = x1 - dy
    y4 = y1 + dx

    d = np.sqrt((x3 - x4) ** 2 + (y3 - y4) ** 2) * np.cos(angle)
    theta = np.arctan2(dy, dx)

    x5 = x4 + d * np.cos(angle + theta)
    y5 = y4 + d * np.sin(angle + theta)

    leftmost_child_1 = leftmost_x_coordinate(x4, y4, x5, y5, angle, depth + 1, max_depth)
    leftmost_child_2 = leftmost_x_coordinate(x5, y5, x3, y3, angle, depth + 1, max_depth)

    return min(x1, x2, x3, x4, leftmost_child_1, leftmost_child_2)

def rightmost_x_coordinate(x1, y1, x2, y2, angle, depth, max_depth):
    if depth >= max_depth:
        dx = x2 - x1
        dy = y2 - y1
        x3 = x2 - dy
        x4 = x1 - dy
        return max(x1, x2, x3, x4)

    dx = x2 - x1
    dy = y2 - y1
    x3 = x2 - dy
    y3 = y2 + dx
    x4 = x1 - dy
    y4 = y1 + dx

    d = np.sqrt((x3 - x4) ** 2 + (y3 - y4) ** 2) * np.cos(angle)
    theta = np.arctan2(dy, dx)

    x5 = x4 + d * np.cos(angle + theta)
    y5 = y4 + d * np.sin(angle + theta)

    rightmost_child_1 = rightmost_x_coordinate(x4, y4, x5, y5, angle, depth + 1, max_depth)
    rightmost_child_2 = rightmost_x_coordinate(x5, y5, x3, y3, angle, depth + 1, max_depth)

    return max(x1, x2, x3, x4, rightmost_child_1, rightmost_child_2)

def topmost_y_coordinate(x1, y1, x2, y2, angle, depth, max_depth):
    if depth >= max_depth:
        dx = x2 - x1
        dy = y2 - y1
        y3 = y2 + dx
        y4 = y1 + dx
        return max(y1, y2, y3, y4)

    dx = x2 - x1
    dy = y2 - y1
    x3 = x2 - dy
    y3 = y2 + dx
    x4 = x1 - dy
    y4 = y1 + dx

    d = np.sqrt((x3 - x4) ** 2 + (y3 - y4) ** 2) * np.cos(angle)
    theta = np.arctan2(dy, dx)

    x5 = x4 + d * np.cos(angle + theta)
    y5 = y4 + d * np.sin(angle + theta)

    topmost_child_1 = topmost_y_coordinate(x4, y4, x5, y5, angle, depth + 1, max_depth)
    topmost_child_2 = topmost_y_coordinate(x5, y5, x3, y3, angle, depth + 1, max_depth)

    return max(y1, y2, y3, y4, topmost_child_1, topmost_child_2)

draw_tree.py


import matplotlib.pyplot as plt
import numpy as np
from pythagoras_tree import tree
from coordinates import leftmost_x_coordinate, rightmost_x_coordinate, topmost_y_coordinate

rad = 30
x_min = 1500
y_min = -6000
max_depth = 8

angle = np.radians(rad)
leftmost_x = leftmost_x_coordinate(-x_min, y_min, x_min, y_min, angle, 0, max_depth)
print("Leftmost x-coordinate:", leftmost_x)

rightmost_x = rightmost_x_coordinate(-x_min, y_min, x_min, y_min, angle, 0, 8)
print("Rightmost x-coordinate:", rightmost_x)

topmost_y = topmost_y_coordinate(-x_min, y_min, x_min, y_min, angle, 0, 8)
print("Topmost y-coordinate:", topmost_y)

fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.set_axis_off()
fig.set_size_inches(10, 10)
ax.set_xlim(leftmost_x, rightmost_x)
ax.set_ylim(y_min, topmost_y)

tree(ax=ax, x1=-x_min, y1=y_min, x2=x_min, y2=y_min, angle=angle, depth=0, max_depth=max_depth)

plt.show()

image image

Eliguli commented 1 week ago

Sierpinski Pentagons with Paddings

import matplotlib.pyplot as plt
import numpy as np

def draw_pentagon(ax, center, size, rotation=0):
    angle = np.pi / 5  # 36 degrees in radians
    vertices = []
    for i in range(5):
        x = center[0] + size * np.sin((2 * i + 1) * angle + rotation)
        y = center[1] + size * np.cos((2 * i + 1) * angle + rotation)
        vertices.append((x, y))
    vertices.append(vertices[0])  # Close the pentagon

    ax.plot(*zip(*vertices), 'k-')
    return vertices

def draw_surrounding_pentagons(ax, center, size, pad, depth):
    if depth == 0:
        return

    # Factor and new size calculation for the initial center pentagon
    fact = center[0] * pad
    new_size = size / (2 + fact + (np.sqrt(5) - 1) / 2)

    vertices = draw_pentagon(ax, center, new_size)
    new_size *= 0.95

    # Calculate the centers and sizes for the surrounding pentagons
    for i in range(5):
        # Midpoint of the edge of the central pentagon
        mid_x = (vertices[i][0] + vertices[i+1][0]) / 2
        mid_y = (vertices[i][1] + vertices[i+1][1]) / 2

        # Reflection of the center of the inner pentagon through the midpoint of each edge
        new_center_x = (2 * mid_x - center[0]) * (1 + pad * 0.5)
        new_center_y = (2 * mid_y - center[1]) * (1 + pad * 0.5)

        # Rotation for the outer pentagon
        rotation = np.pi / 5  # Rotate by 36 degrees

        draw_pentagon(ax, (new_center_x, new_center_y), new_size, rotation)

        # Recursive call for the next level of surrounding pentagons
        draw_surrounding_pentagons(ax, (new_center_x, new_center_y), new_size, 0, depth-1)

fig, ax = plt.subplots(figsize=(12, 12))
ax.set_aspect('equal')
ax.axis('off')

# Parameters
center = (0, 0)
size = 1
pad = 0.05
depth = 4  # Number of recursive levels

draw_surrounding_pentagons(ax, center, size, pad, depth)

plt.show()

image

Eliguli commented 1 week ago

Python Code for Simple Mandelbrot Set MandelbrotSet.py

import numpy as np
import matplotlib.pyplot as plt

def mandelbrot(c, max_iter):
    z = c
    for n in range(max_iter):
        if abs(z) > 2:
            return n
        z = z*z + c
    return max_iter

def mandelbrot_set(xmin, xmax, ymin, ymax, width, height, max_iter):
    r1 = np.linspace(xmin, xmax, width)
    r2 = np.linspace(ymin, ymax, height)
    n3 = np.empty((width, height))
    for i in range(width):
        for j in range(height):
            n3[i, j] = mandelbrot(r1[i] + 1j*r2[j], max_iter)
    return (r1, r2, n3)

def display_mandelbrot(xmin, xmax, ymin, ymax, width=800, height=800, max_iter=256):
    r1, r2, n3 = mandelbrot_set(xmin, xmax, ymin, ymax, width, height, max_iter)
    plt.imshow(n3.T, cmap='twilight', extent=[xmin, xmax, ymin, ymax])
    plt.colorbar()
    plt.title('Mandelbrot Set')
    plt.xlabel('Re')
    plt.ylabel('Im')
    plt.show()

# Example usage
display_mandelbrot(-2.0, 1.0, -1.5, 1.5)

image

Python Jupyter Code for Mandelbrot Sets Mandelbrot.ipynb

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

def mandelbrot(c, max_iter):
    z = c
    for n in range(max_iter):
        if abs(z) > 2:
            return n
        z = z*z + c
    return max_iter

def mandelbrot_set(xmin, xmax, ymin, ymax, width, height, max_iter):
    r1 = np.linspace(xmin, xmax, width)
    r2 = np.linspace(ymin, ymax, height)
    n3 = np.empty((width, height))
    for i in range(width):
        for j in range(height):
            n3[i, j] = mandelbrot(r1[i] + 1j*r2[j], max_iter)
    return (r1, r2, n3)

def display_mandelbrot(ax, x_center, y_center, zoom, width=800, height=800):
    max_iter = int(256 * zoom)
    x_width = 3.0 / zoom
    y_height = 3.0 / zoom
    xmin_new = x_center - x_width / 2
    xmax_new = x_center + x_width / 2
    ymin_new = y_center - y_height / 2
    ymax_new = y_center + y_height / 2

    r1, r2, n3 = mandelbrot_set(xmin_new, xmax_new, ymin_new, ymax_new, width, height, max_iter)

    ax.clear()
    ax.imshow(n3.T, cmap='twilight', extent=[xmin_new, xmax_new, ymin_new, ymax_new])
    ax.set_title('Mandelbrot Set')
    ax.set_xlabel('Re')
    ax.set_ylabel('Im')
    plt.draw()

# Initial display parameters
x_center, y_center, zoom = -0.5, 0.0, 1.0

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.4)

# Display the initial Mandelbrot set
display_mandelbrot(ax, x_center, y_center, zoom)

# Create sliders for zoom and translations
axzoom = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor='lightgoldenrodyellow')
zoom_slider = Slider(axzoom, 'Zoom', 1, 100, valinit=zoom, valstep=1)

axtrans_x = plt.axes([0.25, 0.25, 0.65, 0.03], facecolor='lightgoldenrodyellow')
trans_x_slider = Slider(axtrans_x, 'Translate X', -2.0, 2.0, valinit=x_center, valstep=0.01)

axtrans_y = plt.axes([0.25, 0.2, 0.65, 0.03], facecolor='lightgoldenrodyellow')
trans_y_slider = Slider(axtrans_y, 'Translate Y', -1.5, 1.5, valinit=y_center, valstep=0.01)

def update(val):
    zoom = zoom_slider.val
    x_center = trans_x_slider.val
    y_center = trans_y_slider.val
    display_mandelbrot(ax, x_center, y_center, zoom)

zoom_slider.on_changed(update)
trans_x_slider.on_changed(update)
trans_y_slider.on_changed(update)

plt.show()

image image