Flat - Fancy Curve


from flat import document, shape, rgb, rgba
from bezmerizing import Path, Polyline
from IPython.display import SVG, display
import numpy as np
import random
import itertools
from sympy.utilities.iterables import multiset_permutations


This section defines functions that will be used later.

# Display a flat page here in the notebook
def show(page):
# Draw a grid of horizontal and vertical lines based on 
# given coordinates
def draw_grid(page, x_coords, y_coords, color=rgb(200, 200, 200)):
    # Get minimum and maximum values 
    min_x, max_x = min(x_coords), max(x_coords)
    min_y, max_y = min(y_coords), max(y_coords)
    # Draw vertical lines
    for x in list(x_coords):
        line = shape().stroke(color).line(x, min_y, x, max_y)

    # Draw horizontal lines
    for y in list(y_coords):
        line = shape().stroke(color).line(min_x, y, max_x, y)

# Translate a list of points into a list of coordinates
def indices_to_coordinates(list_of_indices, coordinates):
    c = []
    for index in list_of_indices:
        x = coordinates[0][index[0]]
        y = coordinates[1][index[1]]
        c.append([x, y])
    return c

Flat Document

The following code defines the general setup of the document. It has width and height and a margin. The size of the grid is calculated as the size of the document minus the margin on all sides of the document.

# Width and height of the document
width, height = 400, 400

# Margin between border of the document and
# border of the grid
margin = 10

# Size of the grid
grid_width = width - 2*margin
grid_height = height - 2*margin

# Create the document
d = document(width, height, 'pt')

Grid Definition

The grid is defined through the number of points on the x and y axis. In the next step the coordinates for each point are calculated. This is done with the linspace() function from Numpy (np). It distributes the points on a given range, in this case the size of the grid. It also takes the margin into account.

# Number of points per row 
# (number of cells = row -1)
grid_x = 6
grid_y = 6

# Create coordinates
coords_x = np.linspace(margin, margin+grid_width, grid_x)
coords_y = np.linspace(margin, margin+grid_height, grid_y)

[ 10.  86. 162. 238. 314. 390.]
[ 10.  86. 162. 238. 314. 390.]

Fancy curve

See the bezmerizing demo for a description of the fancy curve.

# Add a page to the document
page = d.addpage()

# Call the function to draw a grid
# As input it takes the list of coordinates defined above
draw_grid(page, coords_x, coords_y)

# Draw a path betweeen points
# Fancy curve requires the first and last points to be duplicated
# (or replaced by close values)
points = [[0, 2], [0, 2], [1, 1], [2, 4], [3, 2], [4, 2], [5, 3], [5, 3]]

# Translate the points into coordinates
coords = indices_to_coordinates(points, [coords_x, coords_y])

# Create a fance line

thicknesses = (np.sin(np.linspace(0, np.pi*4, 100))+1) * 6

pline = Polyline(coords).fancy_curve(thicknesses=thicknesses, samples_per=24)

fig = shape().fill(rgb(0, 0, 0)).nostroke()


# Feed the page into the show() function to display it inside the notebook