Skip to content

Instantly share code, notes, and snippets.

@villares
Forked from berinhard/symmetry.py
Created June 27, 2019 13:27
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 villares/042eea8a178622e9f13ec00b5b1cead5 to your computer and use it in GitHub Desktop.
Save villares/042eea8a178622e9f13ec00b5b1cead5 to your computer and use it in GitHub Desktop.
Pythonic Symmetry
# Author: Berin
# Sketches repo: https://github.com/berinhard/sketches
from collections import namedtuple
from abc import ABCMeta, abstractmethod
WHITE = color(235, 235, 235)
BLACK = color(27, 27, 27)
BLUE = color(55,189,182)
def setup():
stroke(BLACK)
size(600, 600)
class Quadrant:
__metaclass__ = ABCMeta
def prepare(self):
"""
Places the coordinates system to the quadrant
"""
pushMatrix()
self.place()
def release(self):
"""
Restores the coordinates system back to 0,0
"""
popMatrix()
@abstractmethod
def place(self):
pass
@classmethod
def get_quadrants(cls):
"""
Factory method to return the 4 quadrants
"""
return []
def __enter__(self):
self.prepare()
def __exit__(self, *args, **kwargs):
self.release()
class RotationalQuadrant(Quadrant):
def __init__(self, x, y, rot_angle):
self.x, self.y = x, y
self.rot_angle = rot_angle
def place(self):
translate(self.x, self.y)
rotate(self.rot_angle)
@classmethod
def get_quadrants(cls):
return [
cls(0, 0, rot_angle=0), # Q1
cls(width, 0, rot_angle=HALF_PI), # Q2
cls(width, height, rot_angle=PI), # Q3
cls(0, height, rot_angle=3 * HALF_PI), # Q4
]
class SymmetricQuadrant(Quadrant):
def __init__(self, x, y, x_scale=1, y_scale=1):
self.x, self.y = x, y
self.x_scale, self.y_scale = x_scale, y_scale
def place(self):
translate(self.x, self.y)
scale(self.x_scale, self.y_scale)
@classmethod
def get_quadrants(cls):
return [
cls(0, 0), # Q1
cls(width, 0, x_scale=-1), # Q2
cls(width, height, x_scale=-1, y_scale=-1), # Q3
cls(0, height, y_scale=-1), # Q4
]
def pattern(w, h):
p1, p2, p3 = PVector(0, 0), PVector(0, h), PVector(w, h)
p4 = PVector.lerp(p1, p3, 0.5)
p5 = PVector.lerp(p1, p2, 0.5)
p6 = PVector.lerp(p1, PVector(w, 0), 0.5)
strokeWeight(3)
fill(BLUE)
triangle(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y)
fill(WHITE)
triangle(p1.x, p1.y, p3.x, p3.y, w, 0)
fill(BLUE)
triangle(p6.x, p6.y, p4.x, p4.y, p3.x, p3.y)
fill(WHITE)
triangle(p3.x, p3.y, p4.x, p4.y, p5.x, p5.y)
fill(BLACK)
triangle(p6.x, p6.y, p4.x, p4.y, p5.x, p5.y)
quadrants = []
def draw():
background(WHITE)
w, h = width, height
for quadrant in quadrants:
with quadrant:
pattern(w/2, h/2)
if quadrants:
strokeWeight(0.5)
line(0, h / 2, w, h / 2)
line(w / 2, 0, w / 2, h)
else:
pattern(w, h)
def keyPressed():
global quadrants
if key == '1':
quadrants = RotationalQuadrant.get_quadrants()
elif key == '2':
quadrants = SymmetricQuadrant.get_quadrants()
else:
quadrants = []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment