Flat - Polyline

Imports

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

Functions

This section defines functions that will be used later.

# Display a flat page here in the notebook
def show(page):
    display(SVG(page.svg()))
       
# 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)
        page.place(line)

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

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)

print(coords_x)
print(coords_y)
[ 10.  86. 162. 238. 314. 390.]
[ 10.  86. 162. 238. 314. 390.]

Draw a polyline on the grid

The Polyline object from the bezmerizing library takes a list of points as argument and will be feed into flats polyline() function.

# 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 polyline betweeen points
pline = Polyline([[coords_x[0], coords_y[1]], [coords_x[2], coords_y[0]], [coords_x[5], coords_y[4]]])
fig = shape().stroke(rgb(0, 0, 0)).nofill().width(1)

# Feed the polyline pline into flat's polyline function
page.place(fig.polyline(pline))

# Feed the page into the show() function to display it inside the notebook
show(page)
_images/flat_03_polyline_10_0.svg

Function to get the coordinates

Accessing the points like pline = Polyline([[coords_x[0], coords_y[1]], [coords_x[2], coords_y[0]], [coords_x[5], coords_y[4]]]) is a little bit too much writing, especially when the line becomes more complex. For that the following function should make it easier. It takes just the indices like [0, 1] and returns coordinates like [10, 86].

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
# Test the function

# If only one index is given, it has to be inside a list
# The coordinates have to be in a list as well

coords = indices_to_coordinates([[0, 1]], [coords_x, coords_y])
print(coords)
[[10.0, 86.0]]
# Test with more points
points = [[0, 1], [2, 0], [5, 4]]
coords = indices_to_coordinates(points, [coords_x, coords_y])

print(coords)
[[10.0, 86.0], [162.0, 10.0], [390.0, 314.0]]

Draw a polyline on the grid with the indices_to_coordinates function

# 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 polyline betweeen points
points = [[0, 1], [2, 0], [5, 4]]
# Translate the points into coordinates
coords = indices_to_coordinates(points, [coords_x, coords_y])
# Feed the coordinates into the Polyline object
pline = Polyline(coords)
fig = shape().stroke(rgb(0, 0, 0)).nofill().width(1)

# Feed the polyline pline into flat's polyline function
page.place(fig.polyline(pline))

# Feed the page into the show() function to display it inside the notebook
show(page)
_images/flat_03_polyline_16_0.svg