Skip to content

Instantly share code, notes, and snippets.

@kernalphage
Last active March 2, 2018 06:12
Show Gist options
  • Save kernalphage/c4ce02a92e782b53ef0b271a0a59b60c to your computer and use it in GitHub Desktop.
Save kernalphage/c4ce02a92e782b53ef0b271a0a59b60c to your computer and use it in GitHub Desktop.
crosshatching in processing
def TriSign(a,b,c):
return (a.x - c.x) * (b.y- c.y) - (a.y-c.y) * (b.x-c.x)
class pLine:
def __init__(self, x1,y1,x2,y2):
self.a = PVector(x1,y1)
self.b = PVector(x2,y2)
def pnorm(self):
ret = (self.a - self.b)
ret.normalize()
ret.rotate(3.141/2)
return ret
def pdraw(self,dest = None):
if dest:
dest.line(self.a.x, self.a.y, self.b.x, self.b.y)
else:
line(self.a.x, self.a.y, self.b.x, self.b.y)
def intersect(self, other):
(a,b,c,d) = (self.a, self.b, other.a, other.b)
a1 = TriSign(a,b,d)
a2 = TriSign(a,b,c)
if a1*a2 < 0.0:
a3 = TriSign(c,d,a)
a4 = a3+a2-a1
if a3*a4 < 0.0:
t = a3 / (a3 - a4)
p = a + t * (b-a)
return (t,p)
return False
def __str__(self):
return str(self.a) + " " + str(self.b)
class hatch:
# <---0--->
def __init__(self, cx,cy, rx,ry):
self.north = pLine(cx,cy,rx,ry)
(dx, dy) = (rx-cx, ry-cy)
self.south = pLine(cx,cy, cx - dx, cy-dy);
def pdraw(self, dest = None):
self.north.pdraw(dest)
self.south.pdraw(dest)
def clipHatch(self, other):
intersect = self.north.intersect(other)
tn,ts = (1,1)
if intersect:
tn,p = intersect
self.north.b = p
intersect = self.south.intersect(other)
if intersect:
ts,p = intersect
self.south.b = p
return (tn,ts)
class patch:
def __init__(self, c, e, hatches):
self.axis = hatch(c.x, c.y, e.x,e.y)
self.tn = 1
self.ts = 1
shortaxis = (c-e)
nn = (c - e)
nn.rotate(3.141/2)
hatchDist = nn.mag()
self.hatches = []
for i in range(-hatches,1+hatches):
nc = PVector.lerp(c,e, ((1.*i)/hatches))
m = hatch(nc.x , nc.y, nc.x + nn.x, nc.y + nn.y)
self.hatches.append(((1.*i)/hatches, m))
def pdraw(self,dest= None ):
for h in self.hatches:
h[1].pdraw(dest)
def clipPatch(self, other):
#todo keep this tn,ts ongoing?
(tn, ts) = self.axis.clipHatch(other)
self.tn = min(self.tn, tn)
self.ts = min(self.ts, ts)
self.hatches = [h for h in self.hatches if h[0] < tn and h[0] > -ts]
for i in range(len(self.hatches)):
self.hatches[i][1].clipHatch(other)
def finalize(self, zones):
for h in self.hatches:
loca, locb, locc = hash(h[1].north.a), hash(h[1].north.b), hash(h[1].south.b)
zones.setdefault(loca,[]).append(h[1].north)
zones.setdefault(locb,[]).append(h[1].north)
zones.setdefault(locb,[]).append(h[1].south)
zones.setdefault(locc,[]).append(h[1].south)
# TODO: implement distance map
buckets = 600
zone = {}
def hash(p):
#return (1,1)
return (int(p.x/buckets), int(p.y/buckets))
def neighbors(p):
if (type(p) is PVector):
p = hash(p)
hood = [ (p[0] + x, p[1] + y) for x in range(-1,2) for y in range(-1, 2)]
flatten = lambda l: [item for sublist in l for item in sublist]
return flatten([zone.get(n,[]) for n in hood])
### end todo
pg = [];
def setup():
size(600, 600)
global pg
pg = createGraphics(600,600)
(top,left,right,bottom) = (100, 100, 500, 500)
sz = 70
border = []
border.append(pLine(top, left, top, right))
border.append(pLine(top, left, bottom, left))
border.append(pLine(top, right, bottom, right))
border.append(pLine(bottom, left, bottom, right))
c = PVector(random(left,right),random(top,bottom))
toggle = False
def draw():
global c
global toggle
global zone
global sz
stroke(0)
if(mousePressed and sz > 0):
if not toggle:
#toggle = True
while True:
mouse = c + PVector(random(-sz,sz),random(-sz,sz))
if mouse.x > 0 and mouse.x < 600 and mouse.y > 0 and mouse.y < 600:
break;
p = patch(c, mouse, 4)
for b in border:
p.clipPatch(b)
b.pdraw(pg)
for n in neighbors(c):
p.clipPatch(n)
p.finalize(zone)
p.pdraw()
c = mouse
else:
toggle = False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment