# Whereas, when still the starfish is sitting still it is fat # and contains softer colors. When clicked, the starfish becomes # a large, slow ameoba which shows similar lighting. numberOfSides = 10 theAngle = 0 import math def rotateX(x, y, angle): return (x*math.cos(angle)-y*math.sin(angle)) def rotateY(x, y, angle): return (y*math.cos(angle)+x*math.sin(angle)) def makePoint(x, y): data = [] data.append(x) data.append(y) return data def getX(p): if len(p) == 2: return p[0] print "Error: not a point" def getY(p): if len(p) == 2: return p[1] print "Error: not a point" def setX(p, newX): p = makePoint(newX, getY(p)) def setY(p, newY): p = makePoint(getX(p), newY) def makeString(numPoints, radius): cx = 50 cy = 50 data = [numPoints] for a in range(0, numPoints): data.append(makePoint(cx+radius*math.cos(a*2*math.pi/numPoints), cy+radius*math.sin(a*2*math.pi/numPoints))) return data def getNum(s): if len(s) > 0: return s[0] print "Error: not a string" def stringPoint(s, i): if i >= 0: if i < len(s)-1: return s[i+1] print "stringPoint Error: out of range" error def setStrPoint(s, i, newP): if i >= 0: if i < len(s)-1: s[i+1] = newP def drawLine(p1, p2): g.line(int(getX(p1)), int(getY(p1)), int(getX(p2)), int(getY(p2))) def drawString(s, color): g.pen(color) for a in range(0, getNum(s)-1): sa = stringPoint(s,a+1) drawLine(sa, stringPoint(s,a)) g.setPixel(int(getX(sa)-1), int(getY(sa)), 100) g.setPixel(int(getX(sa)+1), int(getY(sa)), 100) g.setPixel(int(getX(sa)), int(getY(sa)-1), 100) g.setPixel(int(getX(sa)), int(getY(sa)+1), 100) g.setPixel(int(getX(sa)-1), int(getY(sa)), 100) sa = stringPoint(s,0) g.setPixel(int(getX(sa)+1), int(getY(sa)), 100) g.setPixel(int(getX(sa)), int(getY(sa)-1), 100) g.setPixel(int(getX(sa)), int(getY(sa)+1), 100) drawLine(sa, stringPoint(s,getNum(s)-1)) def sqr(x): return x*x def pointInScreen(p): retval = p if getX(p) < 0: setX(retval, 0) if getX(p) > 100: setX(retval, 100) if getY(p) < 0: setY(retval, 0) if getY(p) > 100: setY(retval, 100) return retval def pullStringPoint(s, i, focusPoint, strength): p = stringPoint(s, i) length = math.sqrt(sqr(getX(p)-getX(focusPoint))+sqr(getY(p)-getY(focusPoint))) attract = sqr(length)*strength/1000 if attract > 50: attract = 50 normal = makePoint(0,0) if length <> 0: normal = makePoint((getX(focusPoint)-getX(p))/length, (getY(focusPoint)-getY(p))/length) newP = pointInScreen(makePoint(getX(p)+attract*getX(normal),getY(p)+attract*getY(normal))) setStrPoint(s, i, newP) def stretchString(s, numSides, radius, strength): jump = int(getNum(s)/numSides) off = jump/2 for a in range(0, numSides): i = off+a*jump focusPoint = makePoint(50+radius*math.cos(theAngle+a*2*math.pi/numSides),50+ radius*math.sin(theAngle+a*2*math.pi/numSides)) pullStringPoint(s, i, focusPoint, strength) def stretchString2(s, numSides, radius, strength): jump = int(getNum(s)/numSides) off = int(jump/2+getNum(s)/2) for a in range(0, numSides): i = int(off+a*jump)%int(getNum(s)) focusPoint = makePoint(50+radius*math.cos(theAngle+a*2*math.pi/numSides),50+ radius*math.sin(theAngle+a*2*math.pi/numSides)) pullStringPoint(s, i, focusPoint, strength) def conformString(s, strength): for a in range(0, getNum(s)): pullStringPoint(s, a, stringPoint(s, (a+getNum(s)+1)%getNum(s)), strength) pullStringPoint(s, a, stringPoint(s, (a+getNum(s)-1)%getNum(s)), strength) def attractString(s, p, strength): for a in range(0, getNum(s)): pullStringPoint(s, a, p, strength) str = [] str.append(makeString(numberOfSides, 40)) mouP = makePoint(50,50) while 1: oldMouP = mouP mouP = pointInScreen(makePoint(g.getMouse(1), g.getMouse(2))) mouP = makePoint(50+(getX(mouP)-50)*1.0, 50+(getY(mouP)-50)*1.0) mouV = makePoint(getX(mouP)-getX(oldMouP), getY(mouP)-getY(oldMouP)) velo = math.sqrt(sqr(getX(mouV)) + sqr(getY(mouV))) theAngle = theAngle + (1.0/150.0)*velo g.norefresh() g.paper(0) for strnum in range(0, len(str)): drawString(str[strnum], 20+int(velo)) if g.getMouse(3) <> 0: stretchString2(str[strnum], getNum(str[strnum]), 75, 1.0) if g.getMouse(3) == 0: stretchString(str[strnum], getNum(str[strnum])/2, 75, 2.0) conformString(str[strnum], 1.0) attractString(str[strnum], mouP, 1.0+5*(100-g.getMouse(3))/100) g.refresh()