Last active
March 2, 2018 06:12
-
-
Save kernalphage/c4ce02a92e782b53ef0b271a0a59b60c to your computer and use it in GitHub Desktop.
crosshatching in processing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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