def blockCreate(LoC, color): #initialize fill fill = Image.open("img" + os.sep + "block_%s.png" % color) fillX, fillY = fill.size fillL = fill.load() #initialize LoC L = len(LoC) minX, minY = maxX, maxY = LoC[0] for (x, y) in LoC: minX = min(minX, x) maxX = max(maxX, x) minY = min(minY, y) maxY = max(maxY, y) #initialize block img = Image.new("RGBA", (maxX - minX, maxY - minY), (255, 255, 255, 255)) imgL = img.load() for i in xrange(maxX - minX): for j in xrange(maxY - minY): r, g, b, alpha = fillL[(i + minX) % fillX, (j + minY) % fillY] for k in xrange(L): if p.det(LoC[k], LoC[(k + 1) % L], p.vadd((i, j), (minX, minY))) > 0: alpha = 0 break imgL[i, j] = (r, g, b, alpha) return img
def exitMe(self, wp, i): epsilon = 2 P = self.LoC[i] Q = self.LoC[(i + 1) % len(self.LoC)] R = (wp.x, wp.y) nextR = p.vadd(R, wp.v) det = p.det(P, Q, R) d = p.dist(P, Q) # check edge collision checkDist = (d * (wp.r - wp.maxSpeed - epsilon) <= det <= d * (wp.r + epsilon))
def collision(self, wp): #check if in bounding box if not (self.minX - wp.r <= wp.x <= self.maxX + wp.r and self.minY - wp.r <= wp.y <= self.maxY + wp.r): return False epsilon = 2 L = len(self.LoC) if self.inMe: inside = True #still inside for i in xrange(L): P = self.LoC[i] Q = self.LoC[(i + 1) % L] R = (wp.x, wp.y) nextR = p.vadd((wp.x, wp.y), wp.v) det = p.det(P, Q, nextR) #if moving away from wall, continue if p.det(P, Q, R) >= det: continue inside &= (det <= p.dist(P, Q) * (epsilon - wp.r)) if not inside: break #to retain values of P, Q if inside: return True #because collision #otherwise check for internal reflection base = p.vsub(Q, P) if not p.refract(wp.v, base, self.rIndex, 1): wp.v = p.reflect(wp.v, base) return True #otherwise if not complete exit, return collision true if det < p.dist(P, Q) * wp.r: return True #otherwise complete exit, change angle self.inMe = False wp.v = p.fixNorm(p.refract(wp.v, p.vsub((0, 0), base), self.rIndex, 1), wp.maxSpeed) return False else: #check each individual side for i in xrange(L): if self.checkEdgeCollision(wp, i): return True for i in xrange(L): if self.checkVertexCollision(wp, i): return True return False
def checkEdgeCollision(self, wp, i): epsilon = 2 P = self.LoC[i] Q = self.LoC[(i + 1) % len(self.LoC)] R = (wp.x, wp.y) nextR = p.vadd(R, wp.v) det = p.det(P, Q, R) d = p.dist(P, Q) # check edge collision checkDist = (d * (wp.r - wp.maxSpeed - epsilon) <= det <= d * (wp.r + epsilon)) checkAngle1 = (p.distSq(P, Q) + p.distSq(Q, R) - p.distSq(P, R)) / p.dist(P, Q) / p.dist(Q, R) > 0 checkAngle2 = (p.distSq(P, Q) + p.distSq(P, R) - p.distSq(Q, R)) / p.dist(P, Q) / p.dist(P, R) > 0 checkDir = p.det(P, Q, R) + epsilon >= p.det(P, Q, nextR) if checkDist and checkAngle1 and checkAngle2 and checkDir: #move particle back to proper location self.calibrateParticleEdge(wp, P, Q, R) #calculate new velocity/gravity if wp.isParticle: self.particleEdgeCollision(wp, P, Q) else: self.waveEdgeCollision(wp, P, Q) wp.collision = (P, Q) return True