Skip to content

Instantly share code, notes, and snippets.

@nomelif
Last active March 25, 2017 20:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nomelif/d199a1f265892047f47e7a4682df54ee to your computer and use it in GitHub Desktop.
Save nomelif/d199a1f265892047f47e7a4682df54ee to your computer and use it in GitHub Desktop.
# Polygon generator for python3 using numpy.
# Released under the MIT lisence
# Copyright (c) 2017 Théo Friberg & Roope Salmi
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# Usage:
# python3 polygon.py <image width> <ratio> <points> <samples> <generations> <outfile>
# Eg.
# python3 polygon.py 200 0.5 3 100 100 test.png
# Would create a 200x200 image of a triangle with the ratio 1/2 and save it to test.png. It would be the result of running 100 points around for 100 generations.
import numpy as np # Used for vector math acceleration
from PIL import Image # Used to save the image to disk
from sys import argv # Used to read the arguments
# We begin by parsing the arguments
image_side = int(argv[1])
jump_length = float(argv[2])
corner_qty = int(argv[3])
samples = int(argv[4])
generations = int(argv[5])
output_file = argv[6]
# We are going to use a carthesian coordinate system where the origin is at the center of the image and the image spans the x and y ranges from -1 to 1.
def to_image_coordinates(point):
"""Transform a coordinate pair in the space ]-1, 1[ to the space ]0, image_side["""
floating_position = (point + 1) * image_side / 2
return floating_position.astype(np.int64)
# We calculate the positions of the corners
corner_angles = np.arange(int(corner_qty)) * np.pi * 2 / int(corner_qty)
corner_coordinates = np.zeros((corner_qty, 2))
corner_coordinates[np.arange(corner_qty), [0]*corner_qty] = np.cos(corner_angles)
corner_coordinates[np.arange(corner_qty), [1]*corner_qty] = np.sin(corner_angles)
# Create the image (we are only going to track hit quantities for now, it will be later normalized into color space)
image = np.zeros((image_side, image_side))
# Create the array of points we are going to keep track of.
# We lazily initialize it into a square
points = (np.random.rand(samples*2).reshape(samples, 2) - 1) * 2
for iteration in range(generations):
image[np.maximum(0, np.minimum(to_image_coordinates(points).transpose()[1], image_side-1)), np.maximum(np.minimum(to_image_coordinates(points).transpose()[0], image_side-1), 0)] += 1 # Transpose because NumPy expects a list of x-coordinates and a list of y-coordinates.
# The minimum is to avoid rounding errors
# Pick a list of random targets
# Pick a list of indices
indices = np.minimum((np.random.rand(samples)*corner_qty).astype(np.int64), corner_qty - 1) # Weed out the (un)lucky exact one from the rng
targets = corner_coordinates[indices]
# Update the positions
points += (targets - points) * jump_length
# Normalize the image
image = np.uint8(image / np.max(image)* 255)
Image.fromarray(image).save(output_file)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment