def generate(self, params): chains = [] directionalWind = random.uniform(-params.maxWind, params.maxWind) for blade in range(params.blades): chain1 = [] chain2 = [] x = random.random() * self.width mh = random.random() * params.maxHeight if params.dWind: w = random.random() * directionalWind else: w = random.uniform(-params.maxWind, params.maxWind) h = 0 thickness = self.thickness for step in range(self.steps): chain1.append((x, h)) chain2.append((x + thickness, h)) h += mh / self.steps x += w w *= 1.5 thickness *= (1.0 - 1. / self.steps) chain2.reverse() chains.append(Chains.Spline(chain1)) chains.append(Chains.Spline(chain2)) return chains
def generate(self, params): random.seed(params.seed) # Make the shape (centered on 0,0 and a radius from 0 to 1.) rotateAngle = 360. / params.points polygon = [] for point in range(params.points): angle = radians(rotateAngle * point) radius = .5 + (random.random() - .5) * (params.randomness / 100.) polygon.append((cos(angle) * radius, sin(angle) * radius)) # Treat the points in the polygon as base points for splines if params.interp > 0: polygon.append(polygon[0]) polygon = Chains.Spline(polygon, expansion=params.interp) # Grow/shrink and rotate polygon scaleFactor = (params.r2 - params.r1) / params.polygons chains = [] for i in range(params.polygons): angle = params.rotation * i scale = params.r1 + i * scaleFactor chains.append( Chains.scale(Chains.rotate([polygon], angle), [scale, scale])[0]) # Center based on user coordinates chains = Chains.transform(chains, (params.xCenter, params.yCenter)) return chains
def save(params, sandable, chains, name): params.sandable = sandable with open("%s%s.sand" % (STORE_PATH, name), 'wb') as f: pickle.dump(params, f) boundingBox = [(0.0, 0.0), (TABLE_WIDTH, TABLE_LENGTH)] Chains.saveImage(chains, boundingBox, "%s%s.png" % (STORE_PATH, name), int(IMAGE_WIDTH / 2), int(IMAGE_HEIGHT / 2), IMAGE_TYPE)
def run(self, chains, box, feed, tableUnits, machUnits, wait=False): chains = Chains.bound(chains, box) chains = Chains.convertUnits(chains, tableUnits, machUnits) chains = Chains.round(chains, 2) self.command('run', { 'chains': chains, 'wait': wait, 'feed': feed, 'units': machUnits })
def generate(self, params): if not params.angleRate: raise SandException("Sample Rate cannot be zero") xC, yC = params.xCenter, params.yCenter chain = Chains.spiral(xC, yC, params.r1, params.r2, params.turns, params.angleRate, params.angleStart, params.base, params.fill) if params.fitToTable: chain = Chains.circleToTable(chain, self.width, self.length) return [chain]
def test(): from Connectable import Connectable class A(Connectable): sockets = { 'out': ['1'], } def _update(self): self._outputs['1'] = 1 return pass a = A() from Passer import Passer class B(Passer): sockets = { 'in': ['1'], 'out': ['1'], } pass b = B() class C(Connectable): sockets = { 'in': ['in3'], 'out': ['out'], } def _update(self): self._outputs['out'] = self._inputs['in3'] return pass c = C() from Node import Node n1 = Node( None, a, '1' ) n2 = Node( '1', b, '1' ) n3 = Node( 'in3', c, None ) from Chain import Chain ch = Chain() ch.append( n1 ) ch.append( n2 ) ch.append( n3 ) from Chains import Chains cs = Chains() cs.add( ch ) r = Runner() r( cs ) assert c.getOutput( 'out' ) == 1 return
def generate(self, params): self.x = 0.0 self.y = 0.0 self.dx = 1.0 self.dy = 0.0 self.chain = [(self.x, self.y)] self.dragon(params.depth, 0) bounds = [(params.xOffset, params.yOffset), (params.xOffset + params.width, params.yOffset + params.length)] if params.fit: return Chains.fit([self.chain], bounds) return Chains.autoScaleCenter([self.chain], bounds)
def detect_outlier_XStream(X): rows = len(X) outlierLabels = [1 for i in range(rows)] k = 50 nchains = 50 depth = 10 cf = Chains(k=k, nchains=nchains, depth=depth) cf.fit(X) anomalyscores = -cf.score(X) return outlierLabels
def generate(self, params): # Get the number of teeth, renormalize based on common divisor, calculate radii teeth = params.teeths teeth = [t for t in teeth if t] if len(teeth) == 0: raise SandException( "There needs to be at least one number for Wheel Teeth") teeth[0] = abs(teeth[0]) gcd = abs(self.gcdList(teeth)) teeth = [int(tooth / gcd) for tooth in teeth] radii = [tooth / (2.0 * pi) for tooth in teeth] # Ratios are all relative to the inner most gear which is 1 ratios = [0] * len(teeth) tp = len(teeth) - 1 ratios[tp] = 1.0 while tp > 0: tp -= 1 ratios[tp] = ratios[tp + 1] * float(teeth[tp + 1]) / teeth[tp] # Number of points is based on the lowest common multiple of all of the teeth points = self.lcmList(teeth) resolution = params.resolution if points * params.resolution < self.MAX_POINTS else self.MAX_POINTS / float( points) points = int(points * resolution) mult = (2.0 * pi) / float( params.resolution * min([abs(t) for t in teeth])) chain = [] for tooth in range(points + 1): a = 0.0 x, y = params.xCenter, params.yCenter for r, rat in zip(radii, ratios): a += rat * tooth * mult x += r * cos(a) y += r * sin(a) chain.append((x, y)) chains = Chains.autoScaleCenter( [chain], [(params.xCenter - params.radius, params.yCenter - params.radius), (params.xCenter + params.radius, params.yCenter + params.radius)]) if params.fitToTable: chains = [ Chains.circleToTable(c, self.width, self.length) for c in chains ] return chains
def generate(self, params): self.chain = [] xi = 1.0 # params.width xj = 0.0 yi = 0.0 yj = 1.0 # params.length self._hilbert(0.0, 0.0, xi, xj, yi, yj, params.depth) bounds = [(params.xOffset, params.yOffset), (params.xOffset + params.width, params.yOffset + params.length)] if params.fit: return Chains.fit([self.chain], bounds) chains = [self.chain] if params.round: chains = Chains.splines(chains) return Chains.autoScaleCenter(chains, bounds)
def generate(self, params): if not params.angleRate: params.angleRate = 15.0 radius = min(params.width / params.cols, params.length / params.rows) * sqrt(2.0) * .5 * params.sizeModifier rowSize, colSize = params.length / params.rows, params.width / params.cols rowHalf, colHalf = rowSize / 2, colSize / 2 chains = [] for row in range(params.rows): aE = 180 if row % 2 else 0 for col in range(params.cols): rev = params.cols - col - 1 if row % 2 else col xC = params.xCorner + rev * colSize + colHalf yC = params.yCorner + row * rowSize + rowHalf chain = Chains.spiral(xC, yC, 0, radius, params.turns, params.angleRate, angleEnd=aE) chains.append(chain) return chains
def generate(self, params): frequencies = params.frequencies amplitudes = params.amplitudes phases = params.phases fap = list(zip(frequencies, amplitudes, list(map(radians, phases)))) if params.innerRadius > params.outerRadius: params.innerRadius, params.outerRadius = params.outerRadius, params.innerRadius chain = [] if params.angleRate: xCenter = params.xCenter yCenter = params.yCenter thickness = params.outerRadius - params.innerRadius points = int(params.turns * 360.0 / params.angleRate) divisor = pow((points * abs(params.angleRate)) / 360.0, params.base) for point in range(points): angle = params.angleStart + radians(point * params.angleRate) radius = params.innerRadius + thickness * (pow( ((point * abs(params.angleRate)) / 360.0), params.base) / divisor) for f, a, p in fap: radius += sin(angle * f + p) * a x = xCenter + (cos(angle) * radius) y = yCenter + (sin(angle) * radius) chain.append((x, y)) if params.fitToTable: chain = Chains.circleToTable(chain, self.width, self.length) return [chain]
def generate(self, params): chain = [] if params.steps > 0: steps = params.steps innerRate = (params.innerRadius2 - params.innerRadius1) / steps outerRate = (params.outerRadius2 - params.outerRadius1) / steps else: innerRate = outerRate = 0.0 steps = 1 angleStart = params.angleStart angle = 360.0 / params.points self.xCenter = params.xCenter self.yCenter = params.yCenter for step in range(steps): innerRadius = params.innerRadius1 + innerRate * step outerRadius = params.outerRadius1 + outerRate * step for point in range(params.points): innerAngle = angleStart + angle * point outerAngle = innerAngle + (angle / 2.0) chain.append(self._point(innerAngle, innerRadius)) chain.append(self._point(outerAngle, outerRadius)) chain.append(self._point(angleStart, innerRadius)) angleStart += params.angleShift if params.fitToTable: chain = Chains.circleToTable(chain, self.width, self.length) return [chain]
def generate(self, params): random.seed(params.seed) knots = [] attempts = 200 knotTurns = 6 while len(knots) < params.knots and attempts > 0: r = random.random() * params.rKnot x = params.xOffset + r + random.random() * (params.width - (2 * r)) y = params.yOffset + r + random.random() * (params.length - (2 * r)) # Check for circular overlap for knot in knots: if self._overlap(x, y, r, knot): attempts -= 1 break else: knots.append(((x, y), r)) knots.sort(key=lambda chain: chain[0][0]) chains = self._grid(params) for c, s in knots: self._knot(chains, c, s) chains.insert(0, Chains.spiral(c[0], c[1], 0., s, knotTurns)) chains.insert(len(knots), [(params.xOffset + params.width, params.yOffset)]) return chains
def generate(self, params): xCenter = params.xCenter yCenter = params.yCenter radius = params.radius reduction = params.reductionRate angleOffset = params.petalWidth / 2. def pnt(angle, radius): x = cos(radians(angle)) * radius y = sin(radians(angle)) * radius return x, y angle = 0. chain = [(xCenter, yCenter)] for i in range(params.iterations): x, y = pnt(angle - angleOffset, radius) chain.append((x + xCenter, y + yCenter)) x, y = pnt(angle + angleOffset, radius) chain.append((x + xCenter, y + yCenter)) chain.append((xCenter, yCenter)) angle += params.angle radius *= reduction chains = [chain] if params.round: chains = Chains.splines(chains) return chains
def chainsToThr(chains, minLength=.05): """ Convert chains to theta,radius array """ extents = Chains.calcExtents(chains) xr = extents[1][0] - extents[0][0] yr = extents[1][1] - extents[0][1] rng = .5 * max(xr, yr) xl, yl = extents[0][0] + xr / 2, extents[0][1] + yr / 2 results = [] x0, y0 = None, None for chain in chains: for x, y in chain: x1, y1 = (x - xl) / rng, (y - yl) / rng if x0 is not None: xd, yd = x1 - x0, y1 - y0 # Interpolate the line into minLength units if the line is too large. # This is done to create "straight lines" in polar coordinates. length = sqrt(xd * xd + yd * yd) if length > minLength: add = 1 + ceil(length / minLength) xs, ys = xd / add, yd / add for i in range(1, add): results.append(thetaRadius(x0 + xs * i, y0 + ys * i)) results.append(thetaRadius(x1, y1)) x0, y0 = x1, y1 return results
def generate(self, params): xCenter = params.xCenter yCenter = params.yCenter points = int(params.turns * 360.0 / params.angleRate) size = params.radius / sqrt(params.turns * 360.0) chain1, chain2 = [], [] for point in range(points, 0, -1): angle = point * params.angleRate radius = size * sqrt(angle) angle = radians(params.angleStart + angle) chain1.append( (xCenter + cos(angle) * radius, yCenter + sin(angle) * radius)) chain2.append( (xCenter - cos(angle) * radius, yCenter - sin(angle) * radius)) if params.fill: results = [] for p1, p2 in zip(chain1, chain2): results.append(p1) results.append(p2) else: results = chain1 + chain2[::-1] if params.fitToTable: results = Chains.circleToTable(results, self.width, self.length) return [results]
def generate(self, params): x0 = 0.1 y0 = 0.0 z0 = 0.0 h = params.h a = params.a b = params.b c = params.c chain = [] for i in range(params.points): x1 = x0 + h * a * (y0 - x0) y1 = y0 + h * (x0 * (b - z0) - y0) z1 = z0 + h * (x0 * y0 - c * z0) x0, y0, z0 = x1, y1, z1 if math.isinf(x0) or math.isnan(x0) or math.isinf( y0) or math.isnan(y0): break chain.append((x0, y0)) # Rescale chain extents = [(params.xOffset, params.yOffset), (params.xOffset + params.width, params.yOffset + params.length)] return Chains.fit([chain], extents)
def generate(self, params): if not params.angleRate: params.angleRate = 15.0 chains = [] for ring in range(params.rings): if ring > 0: ringRadius = ring * params.radius * 2.0 ringCircumfrence = 2.0 * pi * ringRadius spiralCount = int(ringCircumfrence / (2.0 * params.radius)) anglePerSpiral = 360.0 / spiralCount angleEnd = 45.0 + anglePerSpiral else: ringRadius = 0. spiralCount = 1 anglePerSpiral = 0. angleEnd = 0. for spiral in range(spiralCount): xC = params.xCenter + cos(radians( spiral * anglePerSpiral)) * ringRadius yC = params.yCenter + sin(radians( spiral * anglePerSpiral)) * ringRadius aE = 0 if spiral == spiralCount - 1 else angleEnd + 360. * spiral / spiralCount chains.append( Chains.spiral(xC, yC, 0., params.radius * params.factor, params.turns, angleRate=params.angleRate, angleEnd=aE)) return chains
def generate(self, params): chain = [] if params.innerRadius > params.outerRadius: params.innerRadius, params.outerRadius = params.outerRadius, params.innerRadius if params.angleRate: xCenter = params.xCenter yCenter = params.yCenter k = params.petals / 2.0 thickness = params.outerRadius - params.innerRadius lines = params.turns points = int(360.0 / params.angleRate) angleStart = radians(params.angleStart) for line in range(lines): inRadius = params.innerRadius outRadius = thickness * float(line) / float(lines) for point in range(points): angle = radians(point * params.angleRate) radius = inRadius + outRadius * abs(sin(k * angle)) angle += angleStart x = xCenter + (cos(angle) * radius) y = yCenter + (sin(angle) * radius) chain.append((x, y)) angleStart += radians(params.angleShift) if params.fitToTable: chain = Chains.circleToTable(chain, self.width, self.length) return [chain]
def generate(self, params): chain = [] background = [] filename = params.filename multiplier = self.multiplier xc, yc = self.xc, self.yc aplus = radians(params.rotation) if filename.endswith('.thr'): chain = loadThr(filename, xc, yc, aplus, multiplier) if params.background == 'Spiral': turns = int(self.multiplier / self.ballSize) background = Chains.spiral(xc, yc, self.multiplier, 0, turns=turns, angleRate=7.) elif params.background == 'Full Spiral': turns = int(self.fullRadius / self.ballSize) background = Chains.spiral(xc, yc, self.fullRadius, 0, turns=turns, angleRate=7.) return [background, chain]
def generate(self, params): xCenter = params.xCenter yCenter = params.yCenter angleRate = params.angleRate points = int(params.turns * 360.0 / angleRate) curveAngle = radians(angleRate * params.curveFactor) growth = .2 * params.scaleFactor angleGrowth = 1.0 + params.logGrowth * .01 def pnt(angle, offset): radius = exp((angle + offset) * growth) + params.innerRadius if radius > self.maxRadius: raise OverflowError() x = xCenter + cos(angle) * radius y = yCenter + sin(angle) * radius return (x, y) chain = [] for point in range(points): pchain = [] angle = radians(point * angleRate) angleRate *= angleGrowth try: pchain.append(pnt(angle, 0)) pchain.append(pnt(angle - curveAngle, -.5 * pi)) pchain.append(pnt(angle - curveAngle, -1.5 * pi)) pchain.append(pnt(angle - 2. * pi, 0.)) nchain = Chains.Spline(pchain) chain += nchain nchain.reverse() chain += nchain except OverflowError: break if params.fitToTable: chain = Chains.circleToTable(chain, self.width, self.length) return [chain]
def generate(self, params): rakeSize = self.ballSize * params.rakeSize seed(params.seed) rocks = [(params.width * random(), params.length * random()) for n in range(params.rocks)] # Draw rocks chains = [] for rock in rocks: rockSize = uniform(params.minRockSize, params.maxRockSize) # draw inside tight 16 lpi spiral chain = Chains.spiral(rock[0], rock[1], 0., rockSize, 10) # draw outside loose ball lpi spiral ending on left side chain += Chains.spiral(rock[0], rock[1], rockSize, rockSize + rakeSize, params.rakeSize) chains.append(chain) return Chains.scanalize(chains, params.xOffset, params.yOffset, params.width, params.length, 1.0 / params.ballSize)
def generate(self, params): chains = [] filename = params.filename if filename.endswith('.dxf'): cam.read_DXF(filename) elif filename.endswith('.svg'): cam.read_SVG(filename) else: return chains for layer in range((len(cam.boundarys) - 1), -1, -1): if cam.toolpaths[layer] == []: path = cam.boundarys[layer] else: path = cam.toolpaths[layer] for segment in range(len(path)): chain = [] for vertex in range(0, len(path[segment])): x = path[segment][vertex][cam.X] y = path[segment][vertex][cam.Y] chain.append((x, y)) chains.append(chain) chains = Chains.autoScaleCenter(chains, [(0.0, 0.0), (params.width, params.length)]) if params.iterations: import shrinky newChains = chains for chain in shrinky.shrinky(chains, params.iterations, -params.decrement): newChains += chain else: newChains = chains return Chains.scanalize(newChains, params.xOffset, params.yOffset, params.width, params.length, 1.0 / params.ballSize)
def generate(self, params): random.seed(params.seed) chain = [(0.0, 0.0), (1.0, 0.0)] point0 = None for depth in range(params.depth): newChain = [] for point1 in chain: if not point0: point0 = point1 newChain.append(point1) elif random.random() < params.branchProbability: length = sqrt( (point1[0] - point0[0])**2.0 + (point1[1] - point0[1])**2.0) * params.percent midpoint = (point0[0] + (point1[0] - point0[0]) / 2.0, point0[1] + (point1[1] - point0[1]) / 2.0) polyCenter = (midpoint[0] + random.random() * length, midpoint[1] + random.random() * length) newChain += self._makePolygon( midpoint, polyCenter, int(3.0 + random.random() * 6.0)) else: newChain.append(point1) chain = newChain # Mirror and rotate the chain 6 times backwards = chain[:] backwards.reverse() chain += [(p[0], -p[1]) for p in backwards] chains = [] for angle in range(0, 360, 60): chains += Chains.transform(Chains.rotate([chain], angle), (params.xCenter, params.yCenter)) if params.round: chains = Chains.splines(chains) return Chains.autoScaleCenter(chains, self.table)
def generate(self, params): # Compile the rules rules = {} for key in params.keys(): if key.startswith('rule'): values = getattr(params, key).split('=') if len(values) == 2: rules[values[0]] = values[1] # Convert the axiom into fully expanded string path = self._iterateAxiom(params.axiom, rules, params.repetitions) # Convert the axiom into a polyline polyline = PolyLine() polyline.turn(params.heading) methods = { 'F': lambda: polyline.forward(1.0), 'A': lambda: polyline.forward(1.0), 'B': lambda: polyline.forward(1.0), '-': lambda: polyline.turn(-params.angle), '+': lambda: polyline.turn(params.angle), '|': lambda: polyline.turn(180.0), '[': lambda: polyline.push(), ']': lambda: polyline.pop(), } for char in path: if char in methods: methods[char]() chains = [polyline.points] if params.round: chains = Chains.splines(chains) bounds = [(params.xOrigin, params.yOrigin), (params.width, params.length)] return Chains.autoScaleCenter(chains, bounds)
def _drawRandom(self): boundingBox = [(0.0, 0.0), (TABLE_WIDTH, TABLE_LENGTH)] while True: if self._state == self.HALT: return drawer = drawers[random.randint(0, len(drawers)-1)] sand = sandableFactory(drawer, TABLE_WIDTH, TABLE_LENGTH, BALL_SIZE, TABLE_UNITS) params = Params(sand.editor) params.randomize(sand.editor) try: chains = sand.generate(params) pchains = Chains.convertUnits(chains, TABLE_UNITS, MACHINE_UNITS) pchains = Chains.bound(chains, boundingBox) t, d, p = Chains.estimateMachiningTime(pchains, MACHINE_FEED, MACHINE_ACCEL) if DRAW_TIME_MIN <= t <= DRAW_TIME_MAX: break logging.info("Tried %s but time was %d:%02d" % (sand, int(t/60), int(t) % 60)) except Exception as e: logging.warning("Tried %s but failed with %s" % (sand, e)) logging.info("Drawing %s, estimated time %d:%02d" % (sand, int(t/60), int(t) % 60)) History.save(params, drawer, chains, "lastdemo") with mach.mach() as e: e.run(chains, boundingBox, MACHINE_FEED, TABLE_UNITS, MACHINE_UNITS)
def generate(self, params): chains = [ self._arms(params.xCenter, params.yCenter, params.innerRadius, params.outerRadius, params.cwArms, -params.cwAngular, params.points), self._arms(params.xCenter, params.yCenter, params.innerRadius, params.outerRadius, params.ccwArms, params.ccwAngular, params.points) ] if params.fitToTable: chains = [ Chains.circleToTable(c, self.width, self.length) for c in chains ] return chains
def generate(self, params): results = [] lines = params.text.split('\n') lineOffset = params.yOffset chains = None for lineNumber, line in enumerate(lines): if chains and len(chains) and len( chains[-1]) and lineNumber > 0 and lineNumber < len(lines): chains[-1].append((chains[-1][-1][0], lineOffset)) chains = self._getTextChains(line.strip(), params.font, height=params.cHeight) if params.origin == 'Center': extents = Chains.calcExtents(chains) xOffset = (extents[0][0] - extents[1][0]) / 2.0 else: xOffset = 0 chains = Chains.transform(chains, (xOffset, lineOffset)) results += chains lineOffset -= params.cHeight * params.lineSpacing extents = Chains.calcExtents(results) if params.rotate != 0.: results = Chains.transform( results, (extents[0][0] - extents[1][0], extents[0][1] - extents[1][1])) results = Chains.rotate(results, params.rotate) extents = Chains.calcExtents(results) if params.origin == 'Center': results = Chains.transform(results, (params.xOffset - extents[0][0] + (extents[0][0] - extents[1][0]) / 2., params.yOffset - extents[0][1] + (extents[0][1] - extents[1][1]) / 2.)) else: results = Chains.transform(results, (params.xOffset - extents[0][0], params.yOffset - extents[0][1])) return results
def draw(self, chain, repeat=1): self.ms.update(self.ms.ST_RUNNING, 'Drawing %04d' % self.frameNumber) if self.eraser and not self.previewMode: self.drawInSand(self.eraser) targetFrameNumber = self.frameNumber + repeat if self.previewMode: pic = Chains.makeRealisticImage(chain, self.boundingBox, MOVIE_WIDTH, MOVIE_HEIGHT) while self.frameNumber < targetFrameNumber: self.ms.update(self.ms.ST_RUNNING, 'Saving Frame %04d' % self.frameNumber) pic.save(TMP_PATH + (MOVIE_FORMAT % (self.frameNumber)), "PNG") self.frameNumber += 1 else: self.drawInSand(chain) while self.frameNumber < targetFrameNumber: self.ms.update(self.ms.ST_RUNNING, 'Photographing Frame %04d' % self.frameNumber) camera.capture("%sIMG_%04d.jpg" % (TMP_PATH, self.frameNumber)) self.frameNumber += 1