6 crimes
6 crimes

Reputation: 3

Machine Generation of Art Patterns in Vector Fields

I am trying to rewrite this article:We draw, programming. Machine-generated generation of artistic patterns in vector fields (Russian language) from pseudo-code in Python. I am new to ML, hence the following question arises: How to build a grid of angles and output it through PyCharm? I am at this stage:

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

width = 100
height = 100

left_x = int(width * -0.5)
right_x = int(width * 1.5)
top_y = int(height * -0.5)
bottom_y = int(height * 1.5)

resolution = int(width * 0.01)

num_columns = int((right_x - left_x) / resolution)
num_rows = int((bottom_y - top_y) / resolution)

grid=np.ndarray((num_columns, num_rows))
grid[:,:]=math.pi * 0.25

In this code, I create a grid array in which 200 rows and 200 columns, into which the angle 'default_angle' is inserted. Please tell me whether I’m moving in the right direction and how to "draw" a grid, as in an attached link. So far I think I need to use matplotlib.

Upvotes: -1

Views: 73

Answers (2)

Zaraki Kenpachi
Zaraki Kenpachi

Reputation: 5730

You need to make several steps to recreate this:

  1. create vector field based on some function or equation
  2. normalize arrows for proper display
  3. draw line 3.1. set starting parameters 3.2. set while out condition 3.3. calculate new position based on angle from starting point 3.4. get new position index --> net new angle 3.5. update starting positions
  4. draw vector field and line

import numpy as np import matplotlib.pyplot as plt

size = 50
X = np.arange(1, size, 1)
Y = np.arange(1, size, 1)
U, V = np.meshgrid(X, Y)

# Normalize the arrows:
U = U / np.sqrt(U**2 + V**2)
V = V / np.sqrt(U**2 + V**2)

# create angles field
data = []
for i in np.linspace(0, 180, Y.shape[0]):
    data.append([i]*X.shape[0])

angle = np.array(data)

# set starting parameters
x_start_position = 2
y_start_position = 2
step_length = 1.0
point_angle = angle[x_start_position, y_start_position]
line_coordinates = [[x_start_position, y_start_position]]

# collect line points for each step
while x_start_position >= 2:

    # calculate tep based on angle
    x_step = step_length * np.cos(point_angle*np.pi/180)
    y_step = step_length * np.sin(point_angle*np.pi/180)

    # calculate new position
    x_new_position = x_start_position + x_step
    y_new_position = y_start_position + y_step

    # get array index of new position
    x_new_index = int(x_new_position)
    y_new_index = int(y_new_position)

    # get new angle
    point_angle = angle[y_new_index, x_new_index]

    # update start position
    x_start_position = x_new_position
    y_start_position = y_new_position

    # collect results
    line_coordinates.append([x_new_position, y_new_position])

# set line coordinates
line_data = np.array(line_coordinates)
x_line = line_data[:,0]
y_line = line_data[:,1]

# plot field
plt.quiver(X, Y, U, V, color='black', angles=angle, width=0.005)
# plot line
plt.plot(x_line, y_line, '-', color='red')
plt.show()

Output:

enter image description here

Upvotes: 0

Kresten
Kresten

Reputation: 1888

I believe you need to take a look at meshgrid from numpy

from the meshgrid documentation examples:

x = np.arange(-5, 5, 0.1)
y = np.arange(-5, 5, 0.1)
xx, yy = np.meshgrid(x, y, sparse=True)
z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
h = plt.contourf(x,y,z)

Edit. After seeing you r link a better resource is the matplotlib quiver demo

import matplotlib.pyplot as plt
import numpy as np

X = np.arange(-10, 10, 1)
Y = np.arange(-10, 10, 1)
U, V = np.meshgrid(X, Y)

fig, ax = plt.subplots()
q = ax.quiver(X, Y, U, V)
ax.quiverkey(q, X=0.3, Y=1.1, U=10,
             label='Quiver key, length = 10', labelpos='E')

plt.show()

Upvotes: 1

Related Questions