<s> from visual import * <EOL> print ( """<STR_LIT>""" ) <EOL> scene . title = "<STR_LIT>" <EOL> restlength = <NUM_LIT> <EOL> m = <NUM_LIT> * restlength <EOL> g = <NUM_LIT> <EOL> dt = <NUM_LIT> <EOL> k = <NUM_LIT:3> <EOL> damp = ( <NUM_LIT:1> - <NUM_LIT:0> ) ** dt <EOL> nspheres = <NUM_LIT:3> <EOL> floor = <NUM_LIT:0> <EOL> band = curve ( x = arange ( - <NUM_LIT:1> , <NUM_LIT:1> , restlength ) , <EOL> y = <NUM_LIT:1> , <EOL> radius = <NUM_LIT> <EOL> ) <EOL> band . p = band . pos * <NUM_LIT:0> <EOL> spheres = [ ] <EOL> for i in range ( nspheres ) : <EOL> s = sphere ( pos = scene . mouse . getclick ( ) . pos , <EOL> radius = <NUM_LIT> , <EOL> color = ( abs ( sin ( i ) ) , cos ( i ) ** <NUM_LIT:2> , ( i % <NUM_LIT:10> ) / <NUM_LIT> ) ) <EOL> spheres . append ( s ) <EOL> while True : <EOL> rate ( <NUM_LIT:1.0> / dt ) <EOL> if scene . mouse . clicked : <EOL> i = len ( spheres ) <EOL> s = sphere ( pos = scene . mouse . getclick ( ) . pos , <EOL> radius = <NUM_LIT> , <EOL> color = ( abs ( sin ( i ) ) , cos ( i ) ** <NUM_LIT:2> , ( i % <NUM_LIT:10> ) / <NUM_LIT> ) ) <EOL> spheres . append ( s ) <EOL> if floor : <EOL> below = less ( band . pos [ : , <NUM_LIT:1> ] , - <NUM_LIT:1> ) <EOL> band . p [ : , <NUM_LIT:1> ] = where ( below , <NUM_LIT:0> , band . p [ : , <NUM_LIT:1> ] ) <EOL> band . pos [ : , <NUM_LIT:1> ] = where ( below , - <NUM_LIT:1> , band . pos [ : , <NUM_LIT:1> ] ) <EOL> band . p = band . p * damp <EOL> band . pos = band . pos + band . p / m * dt <EOL> band . p [ : , <NUM_LIT:1> ] = band . p [ : , <NUM_LIT:1> ] - m * g * dt <EOL> length = ( band . pos [ <NUM_LIT:1> : ] - band . pos [ : - <NUM_LIT:1> ] ) <EOL> dist = sqrt ( sum ( length * length , - <NUM_LIT:1> ) ) <EOL> force = k * ( dist - restlength ) <EOL> force = length / dist [ : , newaxis ] * force [ : , newaxis ] <EOL> band . p [ : - <NUM_LIT:1> ] = band . p [ : - <NUM_LIT:1> ] + force * dt <EOL> band . p [ <NUM_LIT:1> : ] = band . p [ <NUM_LIT:1> : ] - force * dt <EOL> c = clip ( dist / restlength * <NUM_LIT:0.5> , <NUM_LIT:0> , <NUM_LIT:2> ) <EOL> band . red [ <NUM_LIT:1> : ] = where ( less ( c , <NUM_LIT:1> ) , c , <NUM_LIT:1> ) <EOL> band . green [ <NUM_LIT:1> : ] = where ( less ( c , <NUM_LIT:1> ) , c , <NUM_LIT:2> - c ) <EOL> band . blue [ <NUM_LIT:1> : ] = where ( less ( c , <NUM_LIT:1> ) , <NUM_LIT:1> , <NUM_LIT:2> - c ) <EOL> for s in spheres : <EOL> dist = mag ( band . pos - s . pos ) [ : , newaxis ] <EOL> inside = less ( dist , s . radius ) <EOL> if sometrue ( inside ) : <EOL> R = ( band . pos - s . pos ) / dist <EOL> surface = s . pos + ( s . radius ) * R <EOL> band . pos = surface * inside + band . pos * ( <NUM_LIT:1> - inside ) <EOL> pdotR = sum ( asarray ( band . p ) * asarray ( R ) , - <NUM_LIT:1> ) <EOL> band . p = band . p - R * pdotR [ : , newaxis ] * inside </s>
