├── .gitignore ├── README.md ├── chp01_vectors ├── NOC_1_10_motion101_acceleration │ ├── NOC_1_10_motion101_acceleration.pyde │ └── mover.py ├── NOC_1_11_motion101_acceleration_array │ ├── NOC_1_11_motion101_acceleration_array.pyde │ └── mover.py ├── NOC_1_1_bouncingball_novectors │ └── NOC_1_1_bouncingball_novectors.pyde ├── NOC_1_2_bouncingball_vectors │ └── NOC_1_2_bouncingball_vectors.pyde ├── NOC_1_3_vector_subtraction │ └── NOC_1_3_vector_subtraction.pyde ├── NOC_1_4_vector_multiplication │ └── NOC_1_4_vector_multiplication.pyde ├── NOC_1_5_vector_magnitude │ └── NOC_1_5_vector_magnitude.pyde ├── NOC_1_6_vector_normalize │ └── NOC_1_6_vector_normalize.pyde ├── NOC_1_7_motion101 │ ├── NOC_1_7_motion101.pyde │ └── mover.py ├── NOC_1_8_motion101_acceleration │ ├── NOC_1_8_motion101_acceleration.pyde │ └── mover.py └── NOC_1_9_motion101_acceleration │ ├── NOC_1_9_motion101_acceleration.pyde │ └── mover.py ├── chp02_forces ├── Exercise_2_10_attractrepel │ ├── Exercise_2_10_attractrepel.pyde │ ├── attractor.py │ └── mover.py ├── Extra_instantforce │ ├── Extra_instantforce.pyde │ └── mover.py ├── NOC_02forces_many_attraction_3D │ ├── NOC_02forces_many_attraction_3D.pyde │ ├── attractor.py │ └── mover.py ├── NOC_02forces_many_mutual_boundaries │ ├── NOC_02forces_many_mutual_boundaries.pyde │ └── mover.py ├── NOC_2_1_forces │ ├── NOC_2_1_forces.pyde │ └── mover.py ├── NOC_2_2_forces_many │ ├── NOC_2_2_forces_many.pyde │ └── mover.py ├── NOC_2_3_forces_many_realgravity │ ├── NOC_2_3_forces_many_realgravity.pyde │ └── mover.py ├── NOC_2_4_forces_friction │ ├── NOC_2_4_forces_friction.pyde │ └── mover.py ├── NOC_2_4_forces_nofriction │ ├── NOC_2_4_forces_nofriction.pyde │ └── mover.py ├── NOC_2_5_fluidresistance │ ├── NOC_2_5_fluidresistance.pyde │ ├── liquid.py │ └── mover.py ├── NOC_2_5_fluidresistance_sequence │ ├── NOC_2_5_fluidresistance_sequence.pyde │ ├── liquid.py │ └── mover.py ├── NOC_2_6_attraction │ ├── NOC_2_6_attraction.pyde │ ├── attractor.py │ └── mover.py ├── NOC_2_7_attraction_many │ ├── NOC_2_7_attraction_many.pyde │ ├── attractor.py │ └── mover.py └── NOC_2_8_mutual_attraction │ ├── NOC_2_8_mutual_attraction.pyde │ └── mover.py ├── chp03_oscillation ├── AdditiveWave │ └── AdditiveWave.pyde ├── AttractionArrayWithOscillation │ ├── AttractionArrayWithOscillation.pyde │ ├── attractor.py │ ├── crawler.py │ └── oscillator.py ├── Exercise_3_01_exercise_baton │ └── Exercise_3_01_exercise_baton.pyde ├── Exercise_3_02_cannon │ ├── Exercise_3_02_cannon.pyde │ └── cannon_ball.py ├── Exercise_3_04_spiral │ └── Exercise_3_04_spiral.pyde ├── Exercise_3_05_asteroids │ ├── Exercise_3_05_asteroids.pyde │ └── spaceship.py ├── Exercise_3_10_OOPWave │ ├── Exercise_3_10_OOPWave.pyde │ └── wave.py ├── Exercise_3_11_AdditiveWave │ └── Exercise_3_11_AdditiveWave.pyde ├── Exercise_3_16_springs │ ├── Exercise_3_16_springs.pyde │ ├── mover.py │ └── spring.py ├── Exercise_3_16_springs_array │ ├── Exercise_3_16_springs_array.pyde │ ├── mover.py │ └── spring.py ├── ExtraOscillatingBody │ ├── ExtraOscillatingBody.pyde │ ├── attractor.py │ └── mover.py ├── ExtraOscillatingUpAndDown │ └── ExtraOscillatingUpAndDown.pyde ├── MultipleOscillations │ └── MultipleOscillations.pyde ├── NOC_03spring_exercise_sine │ └── NOC_03spring_exercise_sine.pyde ├── NOC_3_01_angular_motion │ └── NOC_3_01_angular_motion.pyde ├── NOC_3_02_forces_angular_motion │ ├── NOC_3_02_forces_angular_motion.pyde │ ├── attractor.py │ └── mover.py ├── NOC_3_03_pointing_velocity │ ├── NOC_3_03_pointing_velocity.pyde │ └── mover.py ├── NOC_3_04_PolarToCartesian │ └── NOC_3_04_PolarToCartesian.pyde ├── NOC_3_04_PolarToCartesian_trail │ └── NOC_3_04_PolarToCartesian_trail.pyde ├── NOC_3_05_simple_harmonic_motion │ └── NOC_3_05_simple_harmonic_motion.pyde ├── NOC_3_06_simple_harmonic_motion │ └── NOC_3_06_simple_harmonic_motion.pyde ├── NOC_3_07_oscillating_objects │ ├── NOC_3_07_oscillating_objects.pyde │ └── oscillator.py ├── NOC_3_08_static_wave_lines │ └── NOC_3_08_static_wave_lines.pyde ├── NOC_3_09_exercise_additive_wave │ └── NOC_3_09_exercise_additive_wave.pyde ├── NOC_3_09_wave │ └── NOC_3_09_wave.pyde ├── NOC_3_09_wave_a │ └── NOC_3_09_wave_a.pyde ├── NOC_3_09_wave_b │ └── NOC_3_09_wave_b.pyde ├── NOC_3_09_wave_c │ └── NOC_3_09_wave_c.pyde ├── NOC_3_10_PendulumExample │ ├── NOC_3_10_PendulumExample.pyde │ └── pendulum.py ├── NOC_3_10_PendulumExampleSimplified │ ├── NOC_3_10_PendulumExampleSimplified.pyde │ └── pendulum.py ├── NOC_3_11_spring │ ├── NOC_3_11_spring.pyde │ ├── mover.py │ └── spring.py └── OOPWaveParticles │ ├── OOPWaveParticles.pyde │ ├── particle.py │ └── wave.py ├── chp04_systems ├── CircleVsBlob │ ├── CircleVsBlob.pyde │ ├── blob.tif │ ├── circle.tif │ └── data │ │ ├── texture.gif │ │ ├── texture.png │ │ └── texture.psd ├── Exercise_4_03_MovingParticleSystem │ ├── Exercise_4_03_MovingParticleSystem.pyde │ ├── particle.py │ └── particle_system.py ├── Exercise_4_04_asteroids │ ├── Exercise_4_04_asteroids.pyde │ ├── particle.py │ ├── particle_system.py │ └── spaceship.py ├── Exercise_4_06_Shatter │ ├── Exercise_4_06_Shatter.pyde │ ├── particle.py │ └── particle_system.py ├── Exercise_4_10_particleintersection │ ├── Exercise_4_10_particleintersection.pyde │ ├── particle.py │ └── particle_system.py ├── Exercise_4_10_particlerepel │ ├── Exercise_4_10_particlerepel.pyde │ ├── particle.py │ └── particle_system.py ├── Exercise_4_12_ArrayofImages │ ├── Exercise_4_12_ArrayofImages.pyde │ ├── data │ │ ├── corona.png │ │ ├── emitter.png │ │ ├── particle.png │ │ ├── reflection.png │ │ ├── texture.png │ │ └── texture.psd │ ├── particle.py │ └── particle_system.py ├── NOC_4_01_SingleParticle │ ├── NOC_4_01_SingleParticle.pyde │ └── particle.py ├── NOC_4_01_SingleParticle_trail │ ├── NOC_4_01_SingleParticle_trail.pyde │ └── particle.py ├── NOC_4_02_ArrayListParticles │ ├── NOC_4_02_ArrayListParticles.pyde │ └── particle.py ├── NOC_4_03_ParticleSystemClass │ ├── NOC_4_03_ParticleSystemClass.pyde │ ├── particle.py │ └── particle_system.py ├── NOC_4_04_SystemofSystems │ ├── NOC_4_04_SystemofSystems.pyde │ ├── particle.py │ └── particle_system.py ├── NOC_4_05_ParticleSystemInheritancePolymorphism │ ├── NOC_4_05_ParticleSystemInheritancePolymorphism.pyde │ ├── confetti.py │ ├── particle.py │ └── particle_system.py ├── NOC_4_06_ParticleSystemForces │ ├── NOC_4_06_ParticleSystemForces.pyde │ ├── particle.py │ └── particle_system.py ├── NOC_4_07_ParticleSystemForcesRepeller │ ├── NOC_4_07_ParticleSystemForcesRepeller.pyde │ ├── particle.py │ ├── particle_system.py │ └── repeller.py ├── NOC_4_08_ParticleSystemSmoke │ ├── NOC_4_08_ParticleSystemSmoke.pyde │ ├── data │ │ ├── texture.png │ │ └── texture.psd │ ├── particle.py │ └── particle_system.py ├── NOC_4_08_ParticleSystemSmoke_b │ ├── NOC_4_08_ParticleSystemSmoke_b.pyde │ ├── data │ │ ├── texture.png │ │ └── texture.psd │ ├── particle.py │ └── particle_system.py ├── NOC_4_09_AdditiveBlending │ ├── NOC_4_09_AdditiveBlending.pyde │ ├── data │ │ ├── texture.png │ │ └── texture.psd │ ├── particle.py │ └── particle_system.py ├── ParticleSystemInheritance_pushpop │ ├── ParticleSystemInheritance_pushpop.pyde │ ├── particle.py │ ├── particle_child.py │ └── particle_system.py ├── simpleInheritance │ ├── circle.py │ ├── shape.py │ ├── simpleInheritance.pyde │ └── square.py └── simplePolymorphism │ ├── circle.py │ ├── shape.py │ ├── simplePolymorphism.pyde │ └── square.py ├── chp05_physicslibraries ├── CollisionsEqualMass │ ├── CollisionsEqualMass.pyde │ └── mover.py └── NOC_5_1_box2d_exercise │ ├── NOC_5_1_box2d_exercise.pyde │ └── box.py ├── chp06_agents ├── NOC_06_01_Seek │ ├── NOC_06_01_Seek.pyde │ └── vehicle.py ├── NOC_06_02_Arrive │ ├── NOC_06_02_Arrive.pyde │ └── Vehicle.py └── NOC_06_03_StayWithinWalls │ ├── NOC_06_03_StayWithinWalls.pyde │ └── Vehicle.py ├── chp07_CA ├── Exercise_7_01_WolframCA_randomizedrules │ ├── CA.py │ └── Exercise_7_01_WolframCA_randomizedrules.pyde ├── Figure_7_17_cells │ ├── Figure_7_17_cells.pyde │ └── cells.png ├── GameOfLifeWrapAround │ ├── GOL.py │ └── GameOfLifeWrapAround.pyde └── HexagonCells │ ├── GOL.py │ ├── HexagonCells.pyde │ └── cell.py └── introduction ├── Exercise_I_10_NoiseLandscape ├── Exercise_I_10_NoiseLandscape.pyde └── landscape.py ├── Exercise_I_1_WalkerTendsToDownRight ├── Exercise_I_1_WalkerTendsToDownRight.pyde └── walker.py ├── Exercise_I_9_Noise3D └── Exercise_I_9_Noise3D.pyde ├── Figure_I_2_BellCurve └── Figure_I_2_BellCurve.pyde ├── Figure_I_5_Noise1DGraph └── Figure_I_5_Noise1DGraph.pyde ├── Figure_I_6_RandomGraph └── Figure_I_6_RandomGraph.pyde ├── Gaussian2 └── Gaussian2.pyde ├── MonteCarloDistribution └── MonteCarloDistribution.pyde ├── MultipleProbability └── MultipleProbability.pyde ├── NOC_I_1_RandomWalkTraditional ├── NOC_I_1_RandomWalkTraditional.pyde └── walker.py ├── NOC_I_2_RandomDistribution └── NOC_I_2_RandomDistribution.pyde ├── NOC_I_3_RandomWalkTendsToRight ├── NOC_I_3_RandomWalkTendsToRight.pyde └── walker.py ├── NOC_I_4_Gaussian └── NOC_I_4_Gaussian.pyde ├── NOC_I_5_NoiseWalk ├── NOC_I_5_NoiseWalk.pyde └── walker.py ├── Noise1D └── Noise1D.pyde ├── Noise2D └── Noise2D.pyde ├── NoiseDistribution └── NoiseDistribution.pyde ├── NoiseWalkAcceleration ├── NoiseWalkAcceleration.pyde └── walker.py ├── NoiseWalkVelocity ├── NoiseWalkVelocity.pyde └── walker.py ├── NoiseWalk_Many ├── NoiseWalk_Many.pyde └── walker.py ├── RandomWalk ├── RandomWalk.pyde └── walker.py ├── RandomWalkLevy ├── RandomWalkLevy.pyde └── walker.py ├── RandomWalkNoise ├── RandomWalkNoise.pyde └── walker.py ├── RandomWalkPVector ├── RandomWalkPVector.pyde └── walker.py ├── RandomWalkTraditional2 ├── RandomWalkTraditional2.pyde └── walker.py ├── RandomWalkTraditional3 ├── RandomWalkTraditional3.pyde └── walker.py ├── RandomWalkTrail ├── RandomWalkTrail.pyde └── walker.py ├── RandomWalkTrailCurve ├── RandomWalkTrailCurve.pyde └── walker.py ├── SelfAvoidingWalk ├── SelfAvoidingWalk.pyde ├── goal.svg └── walker.py └── SimpleProbablility └── SimpleProbablility.pyde /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.pyc 3 | *.sublime* 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The-Nature-of-Code-Examples Python 2 | 3 | This is the repository for a Python port of [The Nature of Code book](http://natureofcode.com/). If you are looking for the book's raw content (text, illustrations, images, CSS, etc.), have a look at [The Nature of Code repo](https://github.com/shiffman/The-Nature-of-Code). 4 | 5 | The original [Processing](http://processing.org) examples [can be found here](https://github.com/shiffman/The-Nature-of-Code-Examples), along with a [list of other ports](https://github.com/shiffman/The-Nature-of-Code-Examples/blob/master/README.md). 6 | 7 | This port is made possible by [processing.py](https://github.com/jdf/processing.py). 8 | 9 | 10 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_10_motion101_acceleration/NOC_1_10_motion101_acceleration.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from mover import Mover 6 | 7 | 8 | def setup(): 9 | size(640, 360) 10 | global mover 11 | mover = Mover() 12 | 13 | 14 | def draw(): 15 | background(255) 16 | 17 | # Update the location 18 | mover.update() 19 | # Display the Mover 20 | mover.display() 21 | 22 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_10_motion101_acceleration/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A Mover object 5 | 6 | 7 | class Mover(object): 8 | 9 | def __init__(self): 10 | # The Mover tracks location, velocity, and acceleration 11 | # Start in the center 12 | self.location = PVector(width / 2, height / 2) 13 | self.velocity = PVector(0, 0) 14 | # The Mover's maximum speed 15 | self.topspeed = 5 16 | 17 | def update(self): 18 | # Compute a vector that points from location to mouse 19 | mouse = PVector(mouseX, mouseY) 20 | acceleration = PVector.sub(mouse, self.location) 21 | # Set magnitude of acceleration 22 | acceleration.setMag(0.2) 23 | 24 | # Velocity changes according to acceleration 25 | self.velocity.add(acceleration) 26 | # Limit the velocity by topspeed 27 | self.velocity.limit(self.topspeed) 28 | # Location changes by velocity 29 | self.location.add(self.velocity) 30 | 31 | def display(self): 32 | stroke(0) 33 | strokeWeight(2) 34 | fill(127) 35 | ellipse(self.location.x, self.location.y, 48, 48) 36 | 37 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_11_motion101_acceleration_array/NOC_1_11_motion101_acceleration_array.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Demonstration of the basics of motion with vector. 5 | # A "Mover" object stores location, velocity, and acceleration as vectors 6 | # The motion is controlled by affecting the acceleration (in this case 7 | # towards the mouse) 8 | 9 | from mover import Mover 10 | 11 | moverCount = 20 12 | movers = [] 13 | 14 | 15 | def setup(): 16 | size(640, 360) 17 | for i in range(moverCount): 18 | movers.append(Mover()) 19 | 20 | 21 | def draw(): 22 | background(255) 23 | for mover in movers: 24 | mover.update() 25 | mover.display() 26 | 27 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_11_motion101_acceleration_array/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | class Mover(object): 7 | 8 | def __init__(self): 9 | # The Mover tracks location, velocity, and acceleration 10 | # Start in the center 11 | self.location = PVector(random(width), random(height)) 12 | self.velocity = PVector(0, 0) 13 | # The Mover's maximum speed 14 | self.topspeed = 5 15 | 16 | def update(self): 17 | # Compute a vector that points from location to mouse 18 | mouse = PVector(mouseX, mouseY) 19 | acceleration = PVector.sub(mouse, self.location) 20 | # Set magnitude of acceleration 21 | # acceleration.setMag(0.2) 22 | acceleration.normalize() 23 | acceleration.mult(0.2) 24 | 25 | # Velocity changes according to acceleration 26 | self.velocity.add(acceleration) 27 | # Limit the velocity by topspeed 28 | self.velocity.limit(self.topspeed) 29 | # Location changes by velocity 30 | self.location.add(self.velocity) 31 | 32 | def display(self): 33 | stroke(0) 34 | strokeWeight(2) 35 | fill(127, 200) 36 | ellipse(self.location.x, self.location.y, 48, 48) 37 | 38 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_1_bouncingball_novectors/NOC_1_1_bouncingball_novectors.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Example 1-1: Bouncing Ball, no vectors 5 | 6 | x = 100 7 | y = 100 8 | xspeed = 2.5 9 | yspeed = 2 10 | 11 | 12 | def setup(): 13 | size(800, 200) 14 | smooth() 15 | 16 | 17 | def draw(): 18 | background(255) 19 | # Add the current speed to the location. 20 | global x, y, xspeed, yspeed 21 | x = x + xspeed 22 | y = y + yspeed 23 | if (x > width) or (x < 0): 24 | xspeed = xspeed * -1 25 | if (y > height) or (y < 0): 26 | yspeed = yspeed * -1 27 | # Display circle at x location 28 | stroke(0) 29 | strokeWeight(2) 30 | fill(127) 31 | ellipse(x, y, 48, 48) 32 | 33 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_2_bouncingball_vectors/NOC_1_2_bouncingball_vectors.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Example 1-2: Bouncing Ball, with PVector! 5 | 6 | 7 | def setup(): 8 | size(200, 200) 9 | background(255) 10 | global location, velocity 11 | location = PVector(100, 100) 12 | velocity = PVector(2.5, 5) 13 | 14 | 15 | def draw(): 16 | noStroke() 17 | fill(255, 10) 18 | rect(0, 0, width, height) 19 | 20 | # Add the current speed to the location. 21 | global location, velocity 22 | location.add(velocity) 23 | if (location.x > width) or (location.x < 0): 24 | velocity.x = velocity.x * -1 25 | if (location.y > height) or (location.y < 0): 26 | velocity.y = velocity.y * -1 27 | # Display circle at x location 28 | stroke(0) 29 | fill(175) 30 | ellipse(location.x, location.y, 16, 16) 31 | 32 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_3_vector_subtraction/NOC_1_3_vector_subtraction.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Example 1-3: Vector subtraction 5 | 6 | 7 | def setup(): 8 | size(640, 360) 9 | 10 | 11 | def draw(): 12 | background(255) 13 | 14 | mouse = PVector(mouseX, mouseY) 15 | center = PVector(width / 2, height / 2) 16 | mouse.sub(center) 17 | 18 | translate(width / 2, height / 2) 19 | strokeWeight(2) 20 | stroke(0) 21 | line(0, 0, mouse.x, mouse.y) 22 | 23 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_4_vector_multiplication/NOC_1_4_vector_multiplication.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Example 1-4: Vector multiplication 5 | 6 | 7 | def setup(): 8 | size(640, 360) 9 | smooth() 10 | 11 | 12 | def draw(): 13 | background(255) 14 | 15 | mouse = PVector(mouseX, mouseY) 16 | center = PVector(width / 2, height / 2) 17 | mouse.sub(center) 18 | 19 | # Multiplying a vector! The vector is now half its original size 20 | # (multiplied by 0.5). 21 | mouse.mult(0.5) 22 | 23 | translate(width / 2, height / 2) 24 | strokeWeight(2) 25 | stroke(0) 26 | line(0, 0, mouse.x, mouse.y) 27 | 28 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_5_vector_magnitude/NOC_1_5_vector_magnitude.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Example 1-5: Vector magnitude 5 | 6 | 7 | def setup(): 8 | size(640, 360) 9 | 10 | 11 | def draw(): 12 | background(255) 13 | 14 | mouse = PVector(mouseX, mouseY) 15 | center = PVector(width / 2, height / 2) 16 | mouse.sub(center) 17 | m = mouse.mag() 18 | fill(0) 19 | noStroke() 20 | rect(0, 0, m, 10) 21 | 22 | translate(width / 2, height / 2) 23 | stroke(0) 24 | strokeWeight(2) 25 | line(0, 0, mouse.x, mouse.y) 26 | 27 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_6_vector_normalize/NOC_1_6_vector_normalize.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Demonstration of normalizing a vector. 5 | # Normalizing a vector sets its length to 1. 6 | 7 | 8 | def setup(): 9 | size(640, 360) 10 | 11 | 12 | def draw(): 13 | background(255) 14 | 15 | # A vector that points to the mouse location 16 | mouse = PVector(mouseX, mouseY) 17 | # A vector that points to the center of the window 18 | center = PVector(width / 2, height / 2) 19 | # Subtract center from mouse which results in a vector that points from 20 | # center to mouse 21 | mouse.sub(center) 22 | 23 | # Normalize the vector 24 | mouse.normalize() 25 | 26 | # Multiply its length by 50 27 | mouse.mult(150) 28 | 29 | translate(width / 2, height / 2) 30 | # Draw the resulting vector 31 | stroke(0) 32 | strokeWeight(2) 33 | line(0, 0, mouse.x, mouse.y) 34 | 35 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_7_motion101/NOC_1_7_motion101.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from mover import Mover 6 | 7 | 8 | def setup(): 9 | size(640, 360) 10 | global mover 11 | mover = Mover() 12 | 13 | 14 | def draw(): 15 | background(255) 16 | 17 | mover.update() 18 | mover.checkEdges() 19 | mover.display() 20 | 21 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_7_motion101/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | class Mover(object): 7 | 8 | def __init__(self): 9 | self.location = PVector(random(width), random(height)) 10 | self.velocity = PVector(random(-2, 2), random(-2, 2)) 11 | 12 | def update(self): 13 | self.location.add(self.velocity) 14 | 15 | def display(self): 16 | stroke(0) 17 | strokeWeight(2) 18 | fill(127) 19 | ellipse(self.location.x, self.location.y, 48, 48) 20 | 21 | def checkEdges(self): 22 | if self.location.x > width: 23 | self.location.x = 0 24 | elif self.location.x < 0: 25 | self.location.x = width 26 | 27 | if self.location.y > height: 28 | self.location.y = 0 29 | elif self.location.y < 0: 30 | self.location.y = height 31 | 32 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_8_motion101_acceleration/NOC_1_8_motion101_acceleration.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from mover import Mover 6 | 7 | 8 | def setup(): 9 | size(640, 360) 10 | global mover 11 | mover = Mover() 12 | 13 | 14 | def draw(): 15 | background(255) 16 | 17 | mover.update() 18 | mover.checkEdges() 19 | mover.display() 20 | 21 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_8_motion101_acceleration/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | class Mover(object): 7 | 8 | def __init__(self): 9 | self.location = PVector(width / 2, height / 2) 10 | self.velocity = PVector(0, 0) 11 | self.acceleration = PVector(-0.001, 0.01) 12 | self.topspeed = 10 13 | 14 | def update(self): 15 | self.velocity.add(self.acceleration) 16 | self.velocity.limit(self.topspeed) 17 | self.location.add(self.velocity) 18 | 19 | def display(self): 20 | stroke(0) 21 | strokeWeight(2) 22 | fill(127) 23 | ellipse(self.location.x, self.location.y, 48, 48) 24 | 25 | def checkEdges(self): 26 | if self.location.x > width: 27 | self.location.x = 0 28 | elif self.location.x < 0: 29 | self.location.x = width 30 | 31 | if self.location.y > height: 32 | self.location.y = 0 33 | elif self.location.y < 0: 34 | self.location.y = height 35 | 36 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_9_motion101_acceleration/NOC_1_9_motion101_acceleration.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from mover import Mover 6 | 7 | def setup(): 8 | size(640, 360) 9 | global mover 10 | mover = Mover() 11 | 12 | 13 | def draw(): 14 | background(255) 15 | mover.update() 16 | mover.checkEdges() 17 | mover.display() 18 | 19 | -------------------------------------------------------------------------------- /chp01_vectors/NOC_1_9_motion101_acceleration/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | class Mover(object): 7 | 8 | def __init__(self): 9 | self.location = PVector(width / 2, height / 2) 10 | self.velocity = PVector(0, 0) 11 | self.topspeed = 6 12 | 13 | def update(self): 14 | self.acceleration = PVector.random2D() 15 | self.acceleration.mult(random(2)) 16 | self.velocity.add(self.acceleration) 17 | self.velocity.limit(self.topspeed) 18 | self.location.add(self.velocity) 19 | 20 | def display(self): 21 | stroke(0) 22 | strokeWeight(2) 23 | fill(127) 24 | ellipse(self.location.x, self.location.y, 48, 48) 25 | 26 | def checkEdges(self): 27 | if self.location.x > width: 28 | self.location.x = 0 29 | elif self.location.x < 0: 30 | self.location.x = width 31 | 32 | if self.location.y > height: 33 | self.location.y = 0 34 | elif self.location.y < 0: 35 | self.location.y = height 36 | 37 | -------------------------------------------------------------------------------- /chp02_forces/Exercise_2_10_attractrepel/Exercise_2_10_attractrepel.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from attractor import Attractor 8 | from mover import Mover 9 | 10 | max_movers = 20 11 | g = 1 12 | 13 | def setup(): 14 | size(640, 360) 15 | global a 16 | a = Attractor() 17 | 18 | global movers 19 | movers = [Mover(random(4, 12),random(width),random(height)) \ 20 | for i in range(max_movers)] 21 | 22 | def draw(): 23 | background(255) 24 | 25 | a.display() 26 | 27 | for mover in movers: 28 | for other_mover in movers: 29 | if mover != other_mover: 30 | force = other_mover.repel(mover) 31 | mover.applyForce(force) 32 | 33 | force = a.attract(mover) 34 | mover.applyForce(force) 35 | mover.update() 36 | mover.display() -------------------------------------------------------------------------------- /chp02_forces/Exercise_2_10_attractrepel/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.mass = m 10 | self.position = PVector(x, y) 11 | self.velocity = PVector(0, 0) 12 | self.acceleration = PVector(0,0) 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | fill(175, 200) 26 | ellipse(self.position.x, self.position.y, self.mass*2, self.mass*2) 27 | 28 | def repel(self, m, g=0.4): 29 | force = PVector.sub(self.position, m.position) 30 | distance = force.mag() 31 | distance = constrain(distance, 1.0, 10000.0) 32 | force.normalize(); 33 | 34 | strength = (g * self.mass * m.mass)/float(distance * distance) 35 | force.mult(-1*strength) 36 | return force 37 | 38 | def checkEdges(self): 39 | if self.position.x > width: 40 | self.position.x = width 41 | self.velocity.x *= -1 42 | elif selfself.position.x < 0: 43 | self.position.x = 0 44 | self.velocity.x *= -1 45 | 46 | if self.position.y > height: 47 | self.position.y = height 48 | self.velocity.y *= -1 49 | elif selfself.position.y < 0: 50 | self.position.y = 0 51 | self.velocity.y *= -1 -------------------------------------------------------------------------------- /chp02_forces/Extra_instantforce/Extra_instantforce.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | 9 | t = 0.0 10 | 11 | def setup(): 12 | size(640, 360) 13 | global m 14 | m = Mover() 15 | 16 | def draw(): 17 | background(255) 18 | 19 | global m, t 20 | 21 | wx = map(noise(t), 0, 1, -1, 1) 22 | wind = PVector(wx, 0) 23 | t += 0.01 24 | 25 | line(width/2, height/2, width/2 + wind.x*100, height/2 + wind.y*100) 26 | m.applyForce(wind) 27 | 28 | # Gravity 29 | gravity = PVector(0, 0.1) 30 | # m.applyForce(gravity); 31 | 32 | # Shake Force 33 | # m.shake(); 34 | 35 | # Boundary force 36 | if (m.position.x > width - 50): 37 | boundary = PVector(-1,0) 38 | m.applyForce(boundary) 39 | elif (m.position.x < 50): 40 | boundary = PVector(1, 0) 41 | m.applyForce(boundary) 42 | 43 | m.update() 44 | m.display() 45 | 46 | # m.checkEdges() 47 | 48 | def mousePressed(): 49 | cannon = PVector.random2D() 50 | cannon.mult(5) 51 | 52 | global m 53 | m.applyForce(cannon) -------------------------------------------------------------------------------- /chp02_forces/Extra_instantforce/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | 9 | def __init__(self): 10 | self.position = PVector(width/2.0, height/2.0) 11 | self.velocity = PVector(0, 0) 12 | self.acceleration = PVector(0,0) 13 | self.mass = 1 14 | 15 | def shake(self): 16 | force = PVector.random2D() 17 | force.mult(0.7) 18 | self.applyForce(force) 19 | 20 | def applyForce(self, force): 21 | f = PVector.div(force, self.mass) 22 | self.acceleration.add(f) 23 | 24 | def update(self): 25 | self.velocity.add(self.acceleration) 26 | self.position.add(self.velocity) 27 | self.acceleration.mult(0) 28 | 29 | self.velocity.mult(0.95) 30 | 31 | def display(self): 32 | stroke(0) 33 | strokeWeight(2) 34 | fill(127) 35 | ellipse(self.position.x, self.position.y, 48, 48) 36 | 37 | def checkEdges(): 38 | if (self.position.x > width): 39 | self.position.x = width 40 | self.velocity.x *= -1 41 | elif (self.position.x < 0): 42 | self.position.x = 0 43 | self.velocity.x *= -1 44 | 45 | if (self.position.y > height): 46 | self.position.y = width 47 | self.velocity.y *= -1 -------------------------------------------------------------------------------- /chp02_forces/NOC_02forces_many_attraction_3D/NOC_02forces_many_attraction_3D.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from attractor import Attractor 8 | from mover import Mover 9 | 10 | max_movers = 10 11 | angle = 0 12 | 13 | a = Attractor() 14 | 15 | def setup(): 16 | size(640, 360, P3D) 17 | background(255) 18 | 19 | global movers 20 | movers = [Mover(random(0.1, 2), random(-width/2, width/2), \ 21 | random(-height/2, height/2), random(-100,100)) \ 22 | for i in xrange(max_movers)] 23 | 24 | def draw(): 25 | global angle, a 26 | background(0) 27 | sphereDetail(8) 28 | lights() 29 | translate(width/2, height/2) 30 | 31 | rotateY(angle) 32 | 33 | a.display() 34 | 35 | for mover in movers: 36 | force = a.attract(mover) 37 | mover.applyForce(force) 38 | mover.update() 39 | mover.display() 40 | 41 | angle += 0.003 -------------------------------------------------------------------------------- /chp02_forces/NOC_02forces_many_attraction_3D/attractor.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | # A class for a draggable attractive body in our world 8 | 9 | class Attractor(object): 10 | 11 | def __init__(self): 12 | self.position = PVector(0, 0) # Position 13 | self.mass = 20 # Mass, tied to size 14 | self.g = 0.4; # Gravitational Constant 15 | 16 | def attract(self, m): 17 | force = PVector.sub(self.position, m.position) 18 | d = force.mag() 19 | d = constrain(d,5.0,25.0) 20 | 21 | force.normalize(); 22 | strength = (self.g * self.mass * m.mass)/float(d * d) 23 | force.mult(strength) 24 | 25 | return force 26 | 27 | def display(self): 28 | stroke(255) 29 | noFill() 30 | pushMatrix() 31 | translate(self.position.x, self.position.y, self.position.z) 32 | sphere(self.mass*2) 33 | popMatrix() 34 | -------------------------------------------------------------------------------- /chp02_forces/NOC_02forces_many_attraction_3D/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y, z): 9 | self.mass = m 10 | self.position = PVector(x, y, z) 11 | self.velocity = PVector(1, 0) 12 | self.acceleration = PVector(0,0) 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | noStroke() 25 | fill(255) 26 | pushMatrix() 27 | translate(self.position.x, self.position.y, self.position.z) 28 | sphere(self.mass*8) 29 | popMatrix() 30 | 31 | def checkEdges(self): 32 | if (self.position.x > width): 33 | self.position.x = 0 34 | elif (self.position.y < 0): 35 | self.position.y = width 36 | 37 | if (self.position.y > height): 38 | self.velocity.y *= -1 39 | self.position.y = height -------------------------------------------------------------------------------- /chp02_forces/NOC_02forces_many_mutual_boundaries/NOC_02forces_many_mutual_boundaries.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | g = 0.4 9 | max_movers = 20 10 | 11 | def setup(): 12 | size(640, 360) 13 | global movers 14 | 15 | movers = [Mover(random(1,2), random(width), random(height)) \ 16 | for i in xrange(max_movers)] 17 | 18 | def draw(): 19 | background(255) 20 | 21 | for mover in movers: 22 | for other_mover in movers: 23 | if other_mover != mover: 24 | force = other_mover.attract(mover) 25 | mover.applyForce(force) 26 | 27 | mover.boundaries() 28 | mover.update() 29 | mover.display() 30 | -------------------------------------------------------------------------------- /chp02_forces/NOC_02forces_many_mutual_boundaries/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.mass = m 10 | self.position = PVector(x, y) 11 | self.velocity = PVector(1, 0) 12 | self.acceleration = PVector(0,0) 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | fill(175, 200) 26 | ellipse(self.position.x, self.position.y, self.mass*16, self.mass*16) 27 | 28 | def attract(self, m, g=0.4): 29 | force = PVector.sub(self.position, m.position) 30 | distance = force.mag() 31 | distance = constrain(distance, 5.0, 25.0) 32 | force.normalize() 33 | 34 | strength = (g * self.mass * m.mass)/float(distance * distance) 35 | force.mult(strength) 36 | return force 37 | 38 | def boundaries(self): 39 | d = 50 40 | force = PVector(0, 0) 41 | 42 | if self.position.x < d: 43 | force.x = 1 44 | elif self.position.x > (width - d): 45 | force.x = -1 46 | 47 | if self.position.y < d: 48 | force.y = 1 49 | elif self.position.y > (height - d): 50 | force.y = -1 51 | 52 | force.normalize() 53 | force.mult(0.1) 54 | 55 | self.applyForce(force) 56 | -------------------------------------------------------------------------------- /chp02_forces/NOC_2_1_forces/NOC_2_1_forces.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | 9 | def setup(): 10 | size(640, 360) 11 | global m 12 | m = Mover() 13 | 14 | def draw(): 15 | background(255) 16 | 17 | wind = PVector(0.01, 0) 18 | gravity = PVector(0, 0.1) 19 | 20 | m.applyForce(wind) 21 | m.applyForce(gravity) 22 | 23 | m.update() 24 | m.display() 25 | m.checkEdges() 26 | -------------------------------------------------------------------------------- /chp02_forces/NOC_2_1_forces/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self): 9 | self.position = PVector(30, 30) 10 | self.velocity = PVector(0,0) 11 | self.acceleration = PVector(0,0) 12 | self.mass = 1 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | strokeWeight(2) 26 | fill(127) 27 | ellipse(self.position.x, self.position.y, 48, 48) 28 | 29 | def checkEdges(self): 30 | if (self.position.x > width): 31 | self.position.x = width 32 | self.velocity.x *= -1 33 | elif (self.position.x < 0): 34 | self.position.x = 0 35 | self.velocity.x *= -1 36 | 37 | if (self.position.y > height): 38 | self.position.y = height 39 | self.velocity.y *= -1 -------------------------------------------------------------------------------- /chp02_forces/NOC_2_2_forces_many/NOC_2_2_forces_many.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | 9 | def setup(): 10 | size(640, 360) 11 | global movers 12 | movers = [] 13 | for i in range(20): 14 | movers.append(Mover(random(0.1, 4), 0, 0)) 15 | 16 | def draw(): 17 | background(255) 18 | 19 | for m in movers: 20 | wind = PVector(0.01, 0) 21 | gravity = PVector(0, 0.1) 22 | 23 | m.applyForce(wind) 24 | m.applyForce(gravity) 25 | 26 | m.update() 27 | m.display() 28 | m.checkEdges() 29 | -------------------------------------------------------------------------------- /chp02_forces/NOC_2_2_forces_many/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.position = PVector(x, y) 10 | self.velocity = PVector(0,0) 11 | self.acceleration = PVector(0,0) 12 | self.mass = m 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | strokeWeight(2) 26 | fill(0, 127) 27 | ellipse(self.position.x, self.position.y, self.mass*16, self.mass*16) 28 | 29 | def checkEdges(self): 30 | if (self.position.x > width): 31 | self.position.x = width 32 | self.velocity.x *= -1 33 | elif (self.position.x < 0): 34 | self.position.x = 0 35 | self.velocity.x *= -1 36 | 37 | if (self.position.y > height): 38 | self.position.y = height 39 | self.velocity.y *= -1 -------------------------------------------------------------------------------- /chp02_forces/NOC_2_3_forces_many_realgravity/NOC_2_3_forces_many_realgravity.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | 9 | def setup(): 10 | size(640, 360) 11 | global movers 12 | movers = [] 13 | for i in range(20): 14 | movers.append(Mover(random(1, 4), 0, 0)) 15 | 16 | def draw(): 17 | background(255) 18 | 19 | for m in movers: 20 | wind = PVector(0.01, 0) 21 | gravity = PVector(0, 0.1*m.mass) 22 | 23 | m.applyForce(wind) 24 | m.applyForce(gravity) 25 | 26 | m.update() 27 | m.display() 28 | m.checkEdges() 29 | -------------------------------------------------------------------------------- /chp02_forces/NOC_2_3_forces_many_realgravity/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.position = PVector(x, y) 10 | self.velocity = PVector(0,0) 11 | self.acceleration = PVector(0,0) 12 | self.mass = m 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | strokeWeight(2) 26 | fill(0, 127) 27 | ellipse(self.position.x, self.position.y, self.mass*16, self.mass*16) 28 | 29 | def checkEdges(self): 30 | if (self.position.x > width): 31 | self.position.x = width 32 | self.velocity.x *= -1 33 | elif (self.position.x < 0): 34 | self.position.x = 0 35 | self.velocity.x *= -1 36 | 37 | if (self.position.y > height): 38 | self.position.y = height 39 | self.velocity.y *= -1 -------------------------------------------------------------------------------- /chp02_forces/NOC_2_4_forces_friction/NOC_2_4_forces_friction.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | 9 | def setup(): 10 | size(383, 200) 11 | randomSeed(1) 12 | 13 | global movers 14 | movers = [Mover(random(1, 4), random(width), 0) for i in range(5)] 15 | 16 | def draw(): 17 | background(255) 18 | 19 | for m in movers: 20 | 21 | wind = PVector(0.01, 0) 22 | gravity = PVector(0, 0.1*m.mass) 23 | 24 | c = 0.05 25 | friction = m.velocity.get() 26 | friction.mult(-1) 27 | friction.normalize() 28 | friction.mult(c) 29 | 30 | m.applyForce(friction) 31 | m.applyForce(wind) 32 | m.applyForce(gravity) 33 | 34 | m.update() 35 | m.display() 36 | m.checkEdges() 37 | -------------------------------------------------------------------------------- /chp02_forces/NOC_2_4_forces_friction/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.position = PVector(x, y) 10 | self.velocity = PVector(0,0) 11 | self.acceleration = PVector(0,0) 12 | self.mass = m 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | strokeWeight(2) 26 | fill(0, 127) 27 | ellipse(self.position.x, self.position.y, self.mass*16, self.mass*16) 28 | 29 | def checkEdges(self): 30 | if (self.position.x > width): 31 | self.position.x = width 32 | self.velocity.x *= -1 33 | elif (self.position.x < 0): 34 | self.position.x = 0 35 | self.velocity.x *= -1 36 | 37 | if (self.position.y > height): 38 | self.position.y = height 39 | self.velocity.y *= -1 -------------------------------------------------------------------------------- /chp02_forces/NOC_2_4_forces_nofriction/NOC_2_4_forces_nofriction.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | 9 | def setup(): 10 | size(383, 200) 11 | randomSeed(1) 12 | 13 | global movers 14 | movers = [Mover(random(1, 4), random(width), 0) for i in range(5)] 15 | 16 | def draw(): 17 | background(255) 18 | 19 | for m in movers: 20 | 21 | wind = PVector(0.01, 0) 22 | gravity = PVector(0, 0.1*m.mass) 23 | 24 | c = 0.05 25 | friction = m.velocity.get() 26 | friction.mult(-1) 27 | friction.normalize() 28 | friction.mult(c) 29 | 30 | # m.applyForce(friction) 31 | m.applyForce(wind) 32 | m.applyForce(gravity) 33 | 34 | m.update() 35 | m.display() 36 | m.checkEdges() 37 | -------------------------------------------------------------------------------- /chp02_forces/NOC_2_4_forces_nofriction/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.position = PVector(x, y) 10 | self.velocity = PVector(0,0) 11 | self.acceleration = PVector(0,0) 12 | self.mass = m 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | strokeWeight(2) 26 | fill(0, 127) 27 | ellipse(self.position.x, self.position.y, self.mass*16, self.mass*16) 28 | 29 | def checkEdges(self): 30 | if (self.position.x > width): 31 | self.position.x = width 32 | self.velocity.x *= -1 33 | elif (self.position.x < 0): 34 | self.position.x = 0 35 | self.velocity.x *= -1 36 | 37 | if (self.position.y > height): 38 | self.position.y = height 39 | self.velocity.y *= -1 -------------------------------------------------------------------------------- /chp02_forces/NOC_2_5_fluidresistance/NOC_2_5_fluidresistance.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | # Forces (Gravity and Fluid Resistence) with Vectors 8 | 9 | # Demonstration of multiple force acting on bodies (Mover class) 10 | # Bodies experience gravity continuously 11 | # Bodies experience fluid resistance when in "water" 12 | 13 | from mover import Mover 14 | from liquid import Liquid 15 | 16 | def setup(): 17 | size(640, 360) 18 | reset() 19 | 20 | global liquid 21 | liquid = Liquid(0, height/2, width, height/2, 0.1) 22 | 23 | def draw(): 24 | background(255) 25 | 26 | liquid.display() 27 | 28 | for mover in movers: 29 | 30 | # Is the Mover in the liquid? 31 | if liquid.contains(mover): 32 | # Calculate the drag force 33 | dragForce = liquid.drag(mover) 34 | # Apply the drag force 35 | mover.applyForce(dragForce) 36 | 37 | # Gravity is scaled by mass here! 38 | gravity = PVector(0, 0.1*mover.mass) 39 | # Apply gravity 40 | mover.applyForce(gravity) 41 | 42 | # update and display 43 | mover.update() 44 | mover.display() 45 | mover.checkEdges() 46 | 47 | fill(0) 48 | text("click mouse to reset", 10, 30) 49 | 50 | def mousePressed(): 51 | reset() 52 | 53 | def reset(): 54 | # restart all movers randomly 55 | global movers 56 | movers = [Mover(random(0.5, 3), 40 + i*70, 0) for i in range(9)] -------------------------------------------------------------------------------- /chp02_forces/NOC_2_5_fluidresistance/liquid.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Liquid(object): 8 | def __init__(self, x, y, w, h, c): 9 | self.x = x 10 | self.y = y 11 | self.w = w 12 | self.h = h 13 | self.c = c 14 | 15 | def contains(self, m): 16 | l = m.position 17 | return (l.x > self.x) and (l.x < (self.x + self.w)) and \ 18 | (l.y > self.y) and (l.y < (self.y + self.h)) 19 | 20 | def drag(self, m): 21 | """ 22 | Calculates the drag force 23 | """ 24 | speed = m.velocity.mag() 25 | dragMagnitude = self.c * speed * speed 26 | 27 | dragForce = m.velocity.get() 28 | dragForce.mult(-1) 29 | 30 | # dragForce.setMag(dragMagnitude) 31 | dragForce.normalize() 32 | dragForce.mult(dragMagnitude) 33 | return dragForce 34 | 35 | def display(self): 36 | noStroke() 37 | fill(50) 38 | rect(self.x, self.y, self.w, self.h) -------------------------------------------------------------------------------- /chp02_forces/NOC_2_5_fluidresistance/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.position = PVector(x, y) 10 | self.velocity = PVector(0,0) 11 | self.acceleration = PVector(0,0) 12 | self.mass = m 13 | 14 | def applyForce(self, force): 15 | # Newton's Second Law: F = M * A 16 | # or A = F / M 17 | 18 | # divide by mass 19 | f = PVector.div(force, self.mass) 20 | 21 | # accumulate all forces in a acceleration 22 | self.acceleration.add(f) 23 | 24 | def update(self): 25 | self.velocity.add(self.acceleration) 26 | self.position.add(self.velocity) 27 | self.acceleration.mult(0) 28 | 29 | def display(self): 30 | stroke(0) 31 | strokeWeight(2) 32 | fill(127, 200) 33 | ellipse(self.position.x, self.position.y, self.mass*16, self.mass*16) 34 | 35 | def checkEdges(self): 36 | # Bounce off the bottom of the window. 37 | if (self.position.y > height): 38 | self.position.y = height 39 | 40 | # A little dampening when hitting the bottom 41 | self.velocity.y *= -0.9 -------------------------------------------------------------------------------- /chp02_forces/NOC_2_5_fluidresistance_sequence/NOC_2_5_fluidresistance_sequence.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | # Forces (Gravity and Fluid Resistence) with Vectors 8 | 9 | # Demonstration of multiple force acting on bodies (Mover class) 10 | # Bodies experience gravity continuously 11 | # Bodies experience fluid resistance when in "water" 12 | 13 | from mover import Mover 14 | from liquid import Liquid 15 | 16 | def setup(): 17 | size(450, 450) 18 | randomSeed(1) 19 | reset() 20 | 21 | global liquid 22 | liquid = Liquid(0, height/2, width, height/2, 0.1) 23 | 24 | def draw(): 25 | background(255) 26 | 27 | liquid.display() 28 | 29 | for mover in movers: 30 | 31 | # Is the Mover in the liquid? 32 | if liquid.contains(mover): 33 | # Calculate the drag force 34 | dragForce = liquid.drag(mover) 35 | # Apply the drag force 36 | mover.applyForce(dragForce) 37 | 38 | # Gravity is scaled by mass here! 39 | gravity = PVector(0, 0.1*mover.mass) 40 | # Apply gravity 41 | mover.applyForce(gravity) 42 | 43 | # update and display 44 | mover.update() 45 | mover.display() 46 | mover.checkEdges() 47 | 48 | fill(255) 49 | # text("click mouse to reset", 10, 30) 50 | if (frameCount % 20 == 0): 51 | saveFrame("ch2_05_#####.png") 52 | 53 | def mousePressed(): 54 | reset() 55 | 56 | def reset(): 57 | # restart all movers randomly 58 | global movers 59 | movers = [Mover(random(0.5*2.25, 3*2.25), 20*2.25 + i*40*2.25, 0) for i in range(5)] -------------------------------------------------------------------------------- /chp02_forces/NOC_2_5_fluidresistance_sequence/liquid.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Liquid(object): 8 | def __init__(self, x, y, w, h, c): 9 | self.x = x 10 | self.y = y 11 | self.w = w 12 | self.h = h 13 | self.c = c 14 | 15 | def contains(self, m): 16 | l = m.position 17 | return (l.x > self.x) and (l.x < (self.x + self.w)) and \ 18 | (l.y > self.y) and (l.y < (self.y + self.h)) 19 | 20 | def drag(self, m): 21 | """ 22 | Calculates the drag force 23 | """ 24 | speed = m.velocity.mag() 25 | drawMagnitude = self.c * speed * speed 26 | 27 | dragForce = m.velocity.get() 28 | dragForce.mult(-1) 29 | 30 | # dragForce.setMag(dragMagnitude) 31 | dragForce.normalize() 32 | dragForce.mult(drawMagnitude) 33 | return dragForce 34 | 35 | def display(self): 36 | noStroke() 37 | fill(50) 38 | rect(self.x, self.y, self.w, self.h) -------------------------------------------------------------------------------- /chp02_forces/NOC_2_5_fluidresistance_sequence/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.position = PVector(x, y) 10 | self.velocity = PVector(0,0) 11 | self.acceleration = PVector(0,0) 12 | self.mass = m 13 | 14 | def applyForce(self, force): 15 | # Newton's Second Law: F = M * A 16 | # or A = F / M 17 | 18 | # divide by mass 19 | f = PVector.div(force, self.mass) 20 | 21 | # accumulate all forces in a acceleration 22 | self.acceleration.add(f) 23 | 24 | def update(self): 25 | self.velocity.add(self.acceleration) 26 | self.position.add(self.velocity) 27 | self.acceleration.mult(0) 28 | 29 | def display(self): 30 | stroke(0) 31 | strokeWeight(2) 32 | fill(127, 200) 33 | ellipse(self.position.x, self.position.y, self.mass*16, self.mass*16) 34 | 35 | def checkEdges(self): 36 | # Bounce off the bottom of the window. 37 | if (self.position.y > height): 38 | self.position.y = height 39 | 40 | # A little dampening when hitting the bottom 41 | self.velocity.y *= -0.9 -------------------------------------------------------------------------------- /chp02_forces/NOC_2_6_attraction/NOC_2_6_attraction.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | from attractor import Attractor 9 | 10 | def setup(): 11 | size(640, 360) 12 | 13 | global m 14 | m = Mover() 15 | 16 | global a 17 | a = Attractor() 18 | 19 | def draw(): 20 | background(255) 21 | 22 | force = a.attract(m) 23 | m.applyForce(force) 24 | m.update() 25 | 26 | a.drag() 27 | a.hover(mouseX, mouseY) 28 | 29 | a.display() 30 | m.display() 31 | 32 | def mousePressed(): 33 | a.clicked(mouseX, mouseY) 34 | 35 | def mouseReleased(): 36 | a.stopDragging() -------------------------------------------------------------------------------- /chp02_forces/NOC_2_6_attraction/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self): 9 | self.position = PVector(400, 50) 10 | self.velocity = PVector(1, 0) 11 | self.acceleration = PVector(0,0) 12 | self.mass = 1 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | strokeWeight(2) 26 | fill(127) 27 | ellipse(self.position.x, self.position.y, 16, 16) 28 | 29 | def checkEdges(self): 30 | if (self.position.x > width): 31 | self.position.x = 0 32 | elif (self.position.x < 0): 33 | self.position.x = width 34 | 35 | 36 | if (self.position.y > height): 37 | self.position.y = height 38 | 39 | self.velocity.y *= -1 -------------------------------------------------------------------------------- /chp02_forces/NOC_2_7_attraction_many/NOC_2_7_attraction_many.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | from attractor import Attractor 9 | 10 | def setup(): 11 | size(640, 360) 12 | 13 | global movers 14 | movers = [Mover(random(0.1, 2), random(width), random(height)) \ 15 | for i in range(10)] 16 | 17 | global a 18 | a = Attractor() 19 | 20 | def draw(): 21 | background(255) 22 | 23 | a.display() 24 | a.drag() 25 | a.hover(mouseX, mouseY) 26 | 27 | for mover in movers: 28 | force = a.attract(mover) 29 | mover.applyForce(force) 30 | 31 | mover.update() 32 | mover.display() 33 | 34 | def mousePressed(): 35 | a.clicked(mouseX, mouseY) 36 | 37 | def mouseReleased(): 38 | a.stopDragging() 39 | -------------------------------------------------------------------------------- /chp02_forces/NOC_2_7_attraction_many/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.mass = m 10 | self.position = PVector(x, y) 11 | self.velocity = PVector(1, 0) 12 | self.acceleration = PVector(0,0) 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | strokeWeight(2) 26 | fill(0, 100) 27 | ellipse(self.position.x, self.position.y, self.mass*25, self.mass*25) -------------------------------------------------------------------------------- /chp02_forces/NOC_2_8_mutual_attraction/NOC_2_8_mutual_attraction.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | from mover import Mover 8 | g = 0.4 9 | 10 | def setup(): 11 | size(640, 360) 12 | global movers 13 | movers = [Mover(random(0.1, 2),random(width),random(height)) \ 14 | for i in range(20)] 15 | 16 | def draw(): 17 | background(255) 18 | 19 | for mover in movers: 20 | for other_mover in movers: 21 | if (mover != other_mover): 22 | global g 23 | force = other_mover.attract(mover, g) 24 | mover.applyForce(force) 25 | 26 | mover.update() 27 | mover.display() -------------------------------------------------------------------------------- /chp02_forces/NOC_2_8_mutual_attraction/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, m, x, y): 9 | self.mass = m 10 | self.position = PVector(x, y) 11 | self.velocity = PVector(0, 0) 12 | self.acceleration = PVector(0,0) 13 | 14 | def applyForce(self, force): 15 | f = PVector.div(force, self.mass) 16 | self.acceleration.add(f) 17 | 18 | def update(self): 19 | self.velocity.add(self.acceleration) 20 | self.position.add(self.velocity) 21 | self.acceleration.mult(0) 22 | 23 | def display(self): 24 | stroke(0) 25 | strokeWeight(2) 26 | fill(0, 100) 27 | ellipse(self.position.x, self.position.y, self.mass*24, self.mass*24) 28 | 29 | def attract(self, m, g=0.4): 30 | force = PVector.sub(self.position, m.position) 31 | distance = force.mag() 32 | distance = constrain(distance, 5.0, 25.0) 33 | force.normalize(); 34 | 35 | strength = (g * self.mass * m.mass)/float(distance * distance) 36 | force.mult(strength) 37 | return force -------------------------------------------------------------------------------- /chp03_oscillation/AttractionArrayWithOscillation/AttractionArrayWithOscillation.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Attraction Array with Oscillating objects around each Crawler 8 | # Click and drag attractive body to move throughout space\ 9 | 10 | from attractor import Attractor 11 | from crawler import Crawler 12 | 13 | crawlers = [] 14 | crawlers_num = 6 15 | 16 | def setup(): 17 | size(640, 360) 18 | global a, crawlers, crawlers_num 19 | 20 | # Some random bodies 21 | crawlers = [Crawler() for i in range(crawlers_num)] 22 | 23 | # Create an attractive body 24 | a = Attractor(PVector(width/2, height/2), 20, 0.4) 25 | 26 | def draw(): 27 | background(255) 28 | global a, crawlers 29 | 30 | a.rollover(mouseX, mouseY) 31 | a.go() 32 | 33 | for crawler in crawlers: 34 | # Calculate a force exerted by "attractor" on "Crawler" 35 | f = a.attract(crawler) 36 | 37 | # Apply that force to the Crawler 38 | crawler.applyForce(f) 39 | 40 | # Update and render 41 | crawler.update() 42 | crawler.display() 43 | 44 | def mousePressed(): 45 | global a 46 | a.clicked(mouseX, mouseY) 47 | 48 | def mouseReleased(): 49 | global a 50 | a.stopDragging() -------------------------------------------------------------------------------- /chp03_oscillation/AttractionArrayWithOscillation/crawler.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from oscillator import Oscillator 8 | 9 | class Crawler(object): 10 | """ 11 | Attraction 12 | 13 | A class to describe a thing in our world, has vectors for position, 14 | velocity, and acceleration. 15 | Also includes scalar values for mass, maximum velocity, and elasticity. 16 | """ 17 | 18 | def __init__(self): 19 | self.acc = PVector() 20 | self.vel = PVector(random(-1, 1), random(-1, 1)) 21 | self.loc = PVector(random(width), random(height)) 22 | self.mass = random(8, 16) 23 | self.osc = Oscillator(self.mass*2) 24 | 25 | def applyForce(self, force): 26 | f = force.get() 27 | f.div(self.mass) 28 | self.acc.add(f) 29 | 30 | def update(self): 31 | 32 | # Method to update position 33 | self.vel.add(self.acc) 34 | self.loc.add(self.vel) 35 | 36 | # Multiplying by 0 sets the all the components to 0 37 | self.acc.mult(0) 38 | 39 | self.osc.update(self.vel.mag()/10) 40 | 41 | def display(self): 42 | # Method to display 43 | angle = self.vel.heading2D() 44 | 45 | pushMatrix() 46 | translate(self.loc.x, self.loc.y) 47 | rotate(angle) 48 | 49 | ellipseMode(CENTER) 50 | stroke(0) 51 | fill(175, 100) 52 | ellipse(0, 0, self.mass*2, self.mass*2) 53 | 54 | self.osc.display(self.loc) 55 | 56 | popMatrix() 57 | -------------------------------------------------------------------------------- /chp03_oscillation/AttractionArrayWithOscillation/oscillator.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Oscillator(object): 8 | """ 9 | Attraction Array with Oscillating objects around each thing 10 | """ 11 | 12 | def __init__(self, r): 13 | # Because we are going to oscillate along the x and y axis we can 14 | # use PVector for two angles, amplitudes, etc.! 15 | # Initialize randomly 16 | self.theta = 0 17 | self.amplitude = r 18 | 19 | def update(self, thetaVel): 20 | # Update self.theta and offset 21 | self.theta += thetaVel 22 | 23 | def display(self, pos): 24 | # Display based on a position 25 | x = map(cos(self.theta), -1, 1, 0, self.amplitude) 26 | 27 | stroke(0) 28 | fill(50) 29 | line(0, 0, x, 0) 30 | ellipse(x, 0, 8, 8) 31 | 32 | 33 | -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_01_exercise_baton/Exercise_3_01_exercise_baton.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | angle = 0 8 | 9 | def setup(): 10 | size(750, 150) 11 | smooth() 12 | 13 | def draw(): 14 | background(255) 15 | global angle 16 | 17 | fill(127) 18 | stroke(0) 19 | 20 | rectMode(CENTER) 21 | translate(width/2, height/2) 22 | rotate(angle) 23 | line(-50, 0, 50, 0) 24 | stroke(0) 25 | strokeWeight(2) 26 | fill(127) 27 | ellipse(50, 0, 16, 16) 28 | ellipse(-50, 0, 16, 16) 29 | 30 | angle += 0.05 31 | -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_02_cannon/Exercise_3_02_cannon.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from cannon_ball import CannonBall 8 | 9 | # All of this stuff should go into a Cannon class 10 | angle = -PI/4 11 | position = PVector(50, 300) 12 | shot = False 13 | 14 | def setup(): 15 | size(640, 360) 16 | 17 | global ball, position 18 | ball = CannonBall(position.x, position.y) 19 | 20 | def draw(): 21 | background(255) 22 | global angle, ball, position, shot 23 | 24 | pushMatrix() 25 | translate(position.x, position.y) 26 | rotate(angle) 27 | rect(0, -5, 50, 10) 28 | popMatrix() 29 | 30 | if shot: 31 | gravity = PVector(0, 0.2) 32 | ball.applyForce(gravity) 33 | ball.update() 34 | 35 | 36 | ball.display() 37 | 38 | if ball.position.y > height: 39 | ball = CannonBall(position.x, position.y) 40 | shot = False 41 | 42 | def keyPressed(): 43 | global angle, ball, shot 44 | 45 | if (key == CODED) and (keyCode == RIGHT): 46 | angle += 0.1 47 | 48 | elif (key == CODED) and (keyCode == LEFT): 49 | angle -= 0.1 50 | 51 | elif key == ' ': 52 | shot = True 53 | force = PVector.fromAngle(angle) 54 | force.mult(10) 55 | ball.applyForce(force) -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_02_cannon/cannon_ball.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class CannonBall(object): 8 | def __init__(self, x, y): 9 | # All of our regular motion stuff 10 | self.position = PVector(x, y) 11 | self.velocity = PVector() 12 | self.acceleration = PVector() 13 | self.topspeed = 10 14 | 15 | # Size 16 | self.r = 8 17 | 18 | def update(self): 19 | """Standard Euler integration""" 20 | self.velocity.add(self.acceleration) 21 | self.velocity.limit(self.topspeed) 22 | self.position.add(self.velocity) 23 | self.acceleration.mult(0) 24 | 25 | def applyForce(self, force): 26 | self.acceleration.add(force) 27 | 28 | def display(self): 29 | stroke(0) 30 | strokeWeight(2) 31 | pushMatrix() 32 | translate(self.position.x,self.position.y) 33 | ellipse(0, 0, self.r*2, self.r*2) 34 | popMatrix() 35 | 36 | -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_04_spiral/Exercise_3_04_spiral.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # A Polar coordinate, radius now starts at 0 to spiral outwards 8 | r = 0 9 | theta = 0 10 | 11 | def setup(): 12 | size(750, 200) 13 | background(255) 14 | smooth() 15 | 16 | def draw(): 17 | global r, theta 18 | 19 | # Polar to Cartesian conversion 20 | x = r * cos(theta) 21 | y = r * sin(theta) 22 | 23 | # Draw an ellipse at x, y 24 | noStroke() 25 | fill(0) 26 | 27 | # Adjust for center of window 28 | ellipse(x + width/2, y + height/2, 16, 16) 29 | 30 | # Increment the angle 31 | theta += 0.01 32 | 33 | # Increment the radius 34 | r += 0.05 35 | -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_05_asteroids/Exercise_3_05_asteroids.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Chapter 3: Asteroids exercise 8 | 9 | from spaceship import Spaceship 10 | 11 | def setup(): 12 | size(640, 360) 13 | 14 | global ship 15 | ship = Spaceship() 16 | 17 | def draw(): 18 | background(255) 19 | 20 | # Update position 21 | ship.update() 22 | 23 | # Wrape edges 24 | ship.wrapEdges() 25 | 26 | # Draw ship 27 | ship.display() 28 | 29 | 30 | fill(0) 31 | # text("left right arrows to turn, z to thrust", 10, height-5) 32 | 33 | # Turn or thrust the ship depending on what key is pressed 34 | if keyPressed: 35 | if (key == CODED) and (keyCode == LEFT): 36 | ship.turn(-0.03) 37 | 38 | elif (key == CODED) and (keyCode == RIGHT): 39 | ship.turn(0.03) 40 | 41 | elif (key == 'z') or (key == 'Z'): 42 | ship.thrust() -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_10_OOPWave/Exercise_3_10_OOPWave.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Sine Wave 8 | 9 | from wave import Wave 10 | 11 | def setup(): 12 | size(750, 200) 13 | # Initialize a wave with starting point, width, amplitude, and period. 14 | global wave0, wave1 15 | wave0 = Wave(PVector(50, 75), 100, 20, 500) 16 | wave1 = Wave(PVector(300, 100), 300, 40, 220) 17 | 18 | 19 | 20 | def draw(): 21 | background(255) 22 | global wave0, wave1 23 | 24 | # Update and display waves 25 | wave0.calculate() 26 | wave0.display() 27 | 28 | wave1.calculate() 29 | wave1.display() 30 | 31 | -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_10_OOPWave/wave.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Wave(object): 8 | def __init__(self, origin, w, a, p): 9 | 10 | # How far apart should each horizontal position be spaced 11 | self.xspacing = 8 12 | 13 | # Width of entire wave 14 | self.w = w 15 | 16 | # Where does the wave's first point start 17 | self.origin = origin.get() 18 | 19 | # Start angle at 0 20 | self.theta = 0.0 21 | 22 | # Height of wave 23 | self.amplitude = a 24 | 25 | # How many pixels before the wave repeats 26 | self.period = p 27 | 28 | # Value for incrementing X, to be calculated as a function of period 29 | # and xspacing 30 | self.dx = (TWO_PI / self.period) * self.xspacing 31 | 32 | # Using an array to store height values for the wave (not entirely 33 | # necessary) 34 | self.yvalues_length = w/self.xspacing 35 | self.yvalues = [] 36 | 37 | def calculate(self): 38 | # Increment self.theta (try different values for 'angular velocity' here 39 | self.theta += 0.02 40 | 41 | # For every x value, calculate a y value with sine function 42 | x = self.theta 43 | self.yvalues = [] 44 | for i in range(self.yvalues_length): 45 | self.yvalues.append(sin(x)*self.amplitude) 46 | x += self.dx 47 | 48 | def display(self): 49 | # A simple way to draw the wave with an ellipse at each position 50 | for x, yval in enumerate(self.yvalues): 51 | stroke(0) 52 | fill(0,50) 53 | ellipseMode(CENTER) 54 | ellipse(self.origin.x+x*self.xspacing, \ 55 | self.origin.y+yval, \ 56 | 48, 48) 57 | -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_16_springs/Exercise_3_16_springs.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from mover import Bob 8 | from spring import Spring 9 | 10 | def setup(): 11 | size(640, 360) 12 | global bobs, springs 13 | # Create objects at starting position 14 | # Note third argument in Spring constructor is "rest length" 15 | bobs = [Bob(width/2, 100*k) for k in range(1, 4)] 16 | springs = [Spring(bobs[k], bobs[(k+1)%3], 100) for k in range(3)] 17 | 18 | def draw(): 19 | background(255) 20 | global bobs, springs 21 | 22 | for s in springs: 23 | s.update() 24 | 25 | for s in springs: 26 | s.display() 27 | 28 | for b in bobs: 29 | b.update() 30 | b.display() 31 | 32 | bobs[0].drag(mouseX, mouseY) 33 | 34 | def mousePressed(): 35 | global bobs 36 | bobs[0].clicked(mouseX, mouseY) 37 | 38 | def mouseReleased(): 39 | global bobs 40 | bobs[0].stopDragging() 41 | 42 | -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_16_springs/spring.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Chapter 3: Oscillation 3 | # Daniel Shiffman 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Spring(object): 8 | """ 9 | Class to describe an anchor point that can connect to "Bob" objects via 10 | a spring. 11 | Thank you: http://www.myphysicslab.com/spring2d.html 12 | """ 13 | 14 | def __init__(self, a, b, l): 15 | self.a = a 16 | self.b = b 17 | 18 | # Rest length and spring constant 19 | self.length = l 20 | self.k = 0.2 21 | 22 | def update(self): 23 | """Calculate spring force""" 24 | 25 | # Vector pointing from anchor to bob position 26 | force = PVector.sub(self.a.position, self.b.position) 27 | 28 | # What is distance 29 | d = force.mag() 30 | 31 | # Stretch is difference between current distance and rest length 32 | stretch = d - self.length 33 | 34 | # Calculate force according to Hooke's Law 35 | # F = k * stretch 36 | force.normalize() 37 | force.mult(-1 * self.k * stretch) 38 | self.a.applyForce(force) 39 | force.mult(-1) 40 | self.b.applyForce(force) 41 | 42 | def display(self): 43 | strokeWeight(2) 44 | stroke(0) 45 | line(self.b.position.x, self.b.position.y, \ 46 | self.a.position.x, self.a.position.y) -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_16_springs_array/Exercise_3_16_springs_array.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from mover import Bob 8 | from spring import Spring 9 | 10 | bobs = [None for k in range(5)] 11 | springs = [None for k in range(4)] 12 | 13 | def setup(): 14 | size(640, 360) 15 | global bobs, springs 16 | 17 | # Create objects at starting position 18 | # Note third argument in Spring constructor is "rest length" 19 | for i in range(len(bobs)): 20 | bobs[i] = Bob(width/2, i*40) 21 | 22 | for i in range(len(springs)): 23 | springs[i] = Spring(bobs[i], bobs[i+1],40) 24 | 25 | def draw(): 26 | background(255) 27 | global bobs, springs 28 | 29 | for s in springs: 30 | s.update() 31 | s.display() 32 | 33 | for b in bobs: 34 | b.update() 35 | b.display() 36 | b.drag(mouseX, mouseY) 37 | 38 | def mousePressed(): 39 | global bobs 40 | for b in bobs: 41 | b.clicked(mouseX, mouseY) 42 | 43 | def mouseReleased(): 44 | global bobs 45 | for b in bobs: 46 | b.stopDragging() 47 | -------------------------------------------------------------------------------- /chp03_oscillation/Exercise_3_16_springs_array/spring.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Chapter 3: Oscillation 3 | # Daniel Shiffman 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Spring(object): 8 | """ 9 | Class to describe an anchor point that can connect to "Bob" objects via 10 | a spring. 11 | Thank you: http://www.myphysicslab.com/spring2d.html 12 | """ 13 | 14 | def __init__(self, a, b, l): 15 | self.a = a 16 | self.b = b 17 | 18 | # Rest length and spring constant 19 | self.length = l 20 | self.k = 0.2 21 | 22 | def update(self): 23 | """Calculate spring force""" 24 | 25 | # Vector pointing from anchor to bob position 26 | force = PVector.sub(self.a.position, self.b.position) 27 | 28 | # What is distance 29 | d = force.mag() 30 | 31 | # Stretch is difference between current distance and rest length 32 | stretch = d - self.length 33 | 34 | # Calculate force according to Hooke's Law 35 | # F = k * stretch 36 | force.normalize() 37 | force.mult(-1 * self.k * stretch) 38 | self.a.applyForce(force) 39 | force.mult(-1) 40 | self.b.applyForce(force) 41 | 42 | def display(self): 43 | strokeWeight(2) 44 | stroke(0) 45 | line(self.b.position.x, self.b.position.y, \ 46 | self.a.position.x, self.a.position.y) 47 | -------------------------------------------------------------------------------- /chp03_oscillation/ExtraOscillatingBody/ExtraOscillatingBody.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from attractor import Attractor 8 | from mover import Mover 9 | 10 | def setup(): 11 | global a, m 12 | size(640, 360) 13 | m = Mover() 14 | a = Attractor() 15 | 16 | def draw(): 17 | global a, m 18 | background(255) 19 | 20 | force = a.attract(m) 21 | m.applyForce(force) 22 | m.update() 23 | 24 | a.drag() 25 | a.hover(mouseX, mouseY) 26 | 27 | a.display() 28 | m.display() 29 | 30 | def mousePressed(): 31 | global a 32 | a.clicked(mouseX, mouseY) 33 | 34 | def mouseReleased(): 35 | global a 36 | a.stopDragging() 37 | -------------------------------------------------------------------------------- /chp03_oscillation/ExtraOscillatingBody/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Mover(object): 8 | 9 | def __init__(self): 10 | self.position = PVector(400, 50) 11 | self.velocity = PVector(1, 0) 12 | self.acceleration = PVector(0, 0) 13 | self.mass = 1 14 | 15 | def applyForce(self, force): 16 | f = PVector.div(force, self.mass) 17 | self.acceleration.add(f) 18 | 19 | def update(self): 20 | self.velocity.add(self.acceleration) 21 | self.position.add(self.velocity) 22 | self.acceleration.mult(0) 23 | 24 | def display(self): 25 | stroke(0) 26 | strokeWeight(2) 27 | fill(127) 28 | 29 | pushMatrix() 30 | translate(self.position.x, self.position.y) 31 | heading = self.velocity.heading() 32 | rotate(heading) 33 | ellipse(0, 0, 16, 16) 34 | rectMode(CENTER) 35 | # "20" should be a variable that is oscillating 36 | # with sine function 37 | rect(20, 0, 10, 10) 38 | popMatrix() 39 | 40 | def checkEdges(self): 41 | if position.x > width: 42 | self.position.x = 0 43 | elif position.x < 0: 44 | self.position.x = width 45 | 46 | if position.y > height: 47 | self.velocity.y *= -1 48 | self.position.y = height 49 | -------------------------------------------------------------------------------- /chp03_oscillation/ExtraOscillatingUpAndDown/ExtraOscillatingUpAndDown.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | angle = 0 8 | 9 | def setup(): 10 | size(400, 400) 11 | 12 | def draw(): 13 | background(255) 14 | global angle 15 | 16 | y = 100*sin(angle) 17 | angle += 0.02 18 | 19 | fill(127) 20 | translate(width/2, height/2) 21 | line(0, 0, 0, y) 22 | ellipse(0, y, 16, 16) 23 | -------------------------------------------------------------------------------- /chp03_oscillation/MultipleOscillations/MultipleOscillations.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | angle1 = 0 8 | aVelocity1 = 0.01 9 | amplitude1 = 300 10 | angle2 = 0 11 | aVelocity2 = 0.3 12 | amplitude2 = 10 13 | 14 | 15 | def setup(): 16 | size(640, 360) 17 | 18 | def draw(): 19 | global angle1, aVelocity1, amplitude1 20 | global angle2, aVelocity2, amplitude2 21 | background(255) 22 | 23 | x = 0 24 | x += amplitude1 * cos(angle1) 25 | x += amplitude2 * sin(angle2) 26 | 27 | angle1 += aVelocity1 28 | angle2 += aVelocity2 29 | 30 | ellipseMode(CENTER) 31 | stroke(0) 32 | fill(175) 33 | translate(width/2, height/2) 34 | line(0, 0, x, 0) 35 | ellipse(x, 0, 20, 20) 36 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_03spring_exercise_sine/NOC_03spring_exercise_sine.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | angle = 0 8 | aVelocity = 0.05 9 | 10 | def setup(): 11 | size(640, 360) 12 | smooth() 13 | 14 | def draw(): 15 | background(255) 16 | global angle, aVelocity 17 | 18 | x = width/2 19 | y = map(sin(angle), -1, 1, 50, 250) 20 | angle += aVelocity 21 | 22 | ellipseMode(CENTER) 23 | stroke(0) 24 | fill(175) 25 | line(x, 0, x, y) 26 | ellipse(x, y, 20, 20) 27 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_01_angular_motion/NOC_3_01_angular_motion.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | angle = 0 8 | aVelocity = 0 9 | aAcceleration = 0.0001 10 | 11 | def setup(): 12 | size(800, 200) 13 | smooth() 14 | 15 | def draw(): 16 | global angle, aVelocity, aAcceleration 17 | 18 | background(255) 19 | 20 | fill(127) 21 | stroke(0) 22 | 23 | translate(width/2, height/2) 24 | rectMode(CENTER) 25 | rotate(angle) 26 | 27 | stroke(0) 28 | strokeWeight(2) 29 | fill(127) 30 | line(-60, 0, 60, 0) 31 | ellipse(60, 0, 16, 16) 32 | ellipse(-60, 0, 16, 16) 33 | 34 | angle += aVelocity; 35 | aVelocity += aAcceleration; 36 | 37 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_02_forces_angular_motion/NOC_3_02_forces_angular_motion.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from attractor import Attractor 8 | from mover import Mover 9 | 10 | max_movers = 20 11 | 12 | 13 | def setup(): 14 | size(640, 360) 15 | 16 | global movers, a 17 | 18 | movers = [Mover(random(0.1, 2), random(width), random(height)) \ 19 | for i in xrange(max_movers)] 20 | a = Attractor(position=PVector(width/2, height/2)) 21 | 22 | background(255) 23 | 24 | def draw(): 25 | global a, movers 26 | 27 | background(255) 28 | a.display() 29 | 30 | for mv in movers: 31 | force = a.attract(mv) 32 | mv.applyForce(force) 33 | 34 | mv.update() 35 | mv.display() -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_02_forces_angular_motion/attractor.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Attractor(object): 8 | """A class for a draggable attractive body in our world""" 9 | def __init__(self, position=PVector(0, 0), 10 | mass=20, g=0.4): 11 | self.position = position 12 | self.mass = mass 13 | self.g = g 14 | 15 | def attract(self, m): 16 | # Calculate the direction of force. 17 | force = PVector.sub(self.position, m.position) 18 | 19 | # Get the distance between the bodies using the force magnitude 20 | distance = force.mag() 21 | 22 | # Limit the distance to eliminate "extreme" results for very close 23 | # or very far objects 24 | distance = constrain(distance, 5.0, 25.0) 25 | 26 | # We are only interested in the direction, so normalize. 27 | force.normalize() 28 | 29 | # Calculate the gravitional force magnitude 30 | strength = (self.g * self.mass * m.mass)/(distance*distance) 31 | 32 | # Get force vector. 33 | force.mult(strength) 34 | 35 | return force 36 | 37 | def display(self): 38 | """Method to display""" 39 | stroke(0) 40 | strokeWeight(2) 41 | fill(127) 42 | ellipse(self.position.x, self.position.y, 48, 48) 43 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_02_forces_angular_motion/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self, mass, x, y): 9 | self.mass = mass 10 | self.position = PVector(x, y) 11 | self.velocity = PVector(random(-1, 1), random(-1, 1)) 12 | self.acceleration = PVector(0, 0) 13 | 14 | self.angle = 0 15 | self.aVelocity = 0 16 | self.aAcceleration = 0 17 | 18 | def applyForce(self, force): 19 | f = PVector.div(force, self.mass) 20 | self.acceleration.add(f) 21 | 22 | def update(self): 23 | self.velocity.add(self.acceleration) 24 | self.position.add(self.velocity) 25 | 26 | self.aAcceleration = self.acceleration.x / 10.0 27 | self.aVelocity += self.aAcceleration 28 | self.aVelocity = constrain(self.aVelocity,-0.1,0.1) 29 | self.angle += self.aVelocity 30 | 31 | self.acceleration.mult(0) 32 | 33 | def display(self): 34 | stroke(0) 35 | fill(175, 200) 36 | rectMode(CENTER) 37 | 38 | pushMatrix() 39 | translate(self.position.x, self.position.y) 40 | rotate(self.angle) 41 | rect(0, 0, self.mass*16, self.mass*16) 42 | popMatrix() 43 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_03_pointing_velocity/NOC_3_03_pointing_velocity.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from mover import Mover 8 | 9 | def setup(): 10 | size(640,360) 11 | global mover 12 | mover = Mover() 13 | 14 | def draw(): 15 | background(255) 16 | 17 | mover.update() 18 | mover.checkEdges() 19 | mover.display() 20 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_03_pointing_velocity/mover.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Mover(object): 8 | def __init__(self): 9 | self.r = 16 10 | self.position = PVector(width/2, height/2) 11 | self.velocity = PVector(0, 0) 12 | self.topspeed = 4 13 | self.xoff = 1000 14 | self.yoff = 0 15 | 16 | def update(self): 17 | mouse = PVector(mouseX, mouseY) 18 | dir = PVector.sub(mouse, self.position) 19 | dir.normalize() 20 | dir.mult(0.5) 21 | self.acceleration = dir 22 | 23 | self.velocity.add(self.acceleration) 24 | self.velocity.limit(self.topspeed) 25 | self.position.add(self.velocity) 26 | 27 | def display(self): 28 | theta = self.velocity.heading() 29 | 30 | stroke(0) 31 | strokeWeight(2) 32 | fill(127) 33 | pushMatrix() 34 | rectMode(CENTER) 35 | translate(self.position.x, self.position.y) 36 | rotate(theta) 37 | rect(0, 0, 30, 10) 38 | popMatrix() 39 | 40 | def checkEdges(self): 41 | if (self.position.x > width): 42 | self.position.x = 0 43 | elif (self.position.x < 0): 44 | self.position.x = width 45 | 46 | if (self.position.y > height): 47 | self.position.y = 0 48 | elif (self.position.y < 0): 49 | self.position.y = height 50 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_04_PolarToCartesian/NOC_3_04_PolarToCartesian.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # PolarToCartesian 8 | # Convert a polar coordinate (r,theta) to cartesian (x,y): 9 | # x = r * cos(theta) 10 | # y = r * sin(theta) 11 | 12 | 13 | def setup(): 14 | size(640, 360) 15 | # Initialize all values 16 | global r, theta 17 | r = height * 0.45 18 | theta = 0 19 | 20 | 21 | def draw(): 22 | background(255) 23 | global r, theta 24 | 25 | # Translate the origin point to the center of the screen 26 | translate(width/2, height/2) 27 | 28 | # Convert polar to cartesian 29 | x = r * cos(theta) 30 | y = r * sin(theta) 31 | 32 | # Draw the ellipse at the cartesian coordinate 33 | ellipseMode(CENTER) 34 | fill(127) 35 | stroke(0) 36 | strokeWeight(2) 37 | line(0,0,x,y) 38 | ellipse(x, y, 48, 48) 39 | 40 | # Increase the angle over time 41 | theta += 0.02 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_04_PolarToCartesian_trail/NOC_3_04_PolarToCartesian_trail.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # PolarToCartesian 8 | # Convert a polar coordinate (r,theta) to cartesian (x,y): 9 | # x = r * cos(theta) 10 | # y = r * sin(theta) 11 | 12 | 13 | def setup(): 14 | size(800, 200) 15 | background(255) 16 | global r, theta 17 | # Initialize all values 18 | r = height * 0.45 19 | theta = 0 20 | 21 | def draw(): 22 | # background(255) 23 | global r, theta 24 | 25 | noStroke() 26 | fill(255,5) 27 | rect(0, 0, width, height) 28 | 29 | # Translate the origin point to the center of the screen 30 | translate(width/2, height/2) 31 | 32 | # Convert polar to cartesian 33 | x = r * cos(theta) 34 | y = r * sin(theta) 35 | 36 | # Draw the ellipse at the cartesian coordinate 37 | ellipseMode(CENTER) 38 | fill(127) 39 | stroke(0) 40 | strokeWeight(2) 41 | line(0,0,x,y) 42 | ellipse(x, y, 48, 48) 43 | 44 | # Increase the angle over time 45 | theta += 0.02 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_05_simple_harmonic_motion/NOC_3_05_simple_harmonic_motion.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | def setup(): 8 | size(640,360) 9 | 10 | def draw(): 11 | background(255) 12 | 13 | period = 120 14 | amplitude = 300 15 | 16 | # Calculating horizontal position according to formula 17 | # for simple harmonic motion 18 | x = amplitude * sin(TWO_PI * frameCount / period) 19 | 20 | stroke(0) 21 | strokeWeight(2) 22 | fill(127) 23 | translate(width/2, height/2) 24 | line(0, 0, x, 0) 25 | ellipse(x, 0, 48, 48) 26 | 27 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_06_simple_harmonic_motion/NOC_3_06_simple_harmonic_motion.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | angle = 0 8 | aVelocity = 0.03 9 | 10 | def setup(): 11 | size(640, 360) 12 | smooth() 13 | 14 | 15 | def draw(): 16 | background(255) 17 | global angle, aVelocity 18 | 19 | amplitude = 300 20 | x = amplitude * sin(angle) 21 | angle += aVelocity 22 | 23 | ellipseMode(CENTER) 24 | stroke(0) 25 | fill(175) 26 | translate(width/2, height/2) 27 | line(0, 0, x, 0) 28 | ellipse(x, 0, 20, 20) -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_07_oscillating_objects/NOC_3_07_oscillating_objects.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from oscillator import Oscillator 8 | 9 | max_oscillators = 10 10 | 11 | def setup(): 12 | size(640, 360) 13 | smooth() 14 | 15 | # Initialize all objects 16 | global oscillators 17 | oscillators = [Oscillator() for i in range(max_oscillators)] 18 | 19 | background(255) 20 | 21 | def draw(): 22 | background(255) 23 | # Run all objects 24 | for oscillator in oscillators: 25 | oscillator.oscillate() 26 | oscillator.display() 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_07_oscillating_objects/oscillator.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Oscillator(object): 8 | def __init__(self): 9 | self.angle = PVector() 10 | self.velocity = PVector(random(-0.05, 0.05), random(-0.05, 0.05)) 11 | self.amplitude = PVector(random(20, width/2), random(20, height/2)) 12 | 13 | def oscillate(self): 14 | self.angle.add(self.velocity) 15 | 16 | def display(self): 17 | x = sin(self.angle.x) * self.amplitude.x 18 | y = sin(self.angle.y) * self.amplitude.y 19 | 20 | pushMatrix() 21 | translate(width/2, height/2) 22 | stroke(0) 23 | strokeWeight(2) 24 | fill(127,127) 25 | line(0, 0, x, y) 26 | ellipse(x, y, 32, 32) 27 | popMatrix() -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_08_static_wave_lines/NOC_3_08_static_wave_lines.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | angle = 0 8 | angleVel = 0.1 9 | 10 | size(640, 360) 11 | 12 | background(255) 13 | stroke(0) 14 | strokeWeight(2) 15 | noFill() 16 | 17 | beginShape() 18 | for x in range(0, width+1, 5): 19 | y = map(sin(angle), -1, 1, 0, height) 20 | vertex(x, y) 21 | angle += angleVel 22 | endShape() 23 | 24 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_09_wave/NOC_3_09_wave.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | startAngle = 0 8 | angleVel = 0.23 9 | 10 | def setup(): 11 | size(640,360) 12 | 13 | def draw(): 14 | background(255) 15 | 16 | global startAngle, angleVel 17 | 18 | startAngle += 0.015 19 | angle = startAngle 20 | 21 | for x in range(0, width+1, 24): 22 | y = map(sin(angle), -1, 1, 0, height) 23 | 24 | stroke(0) 25 | fill(0, 50) 26 | strokeWeight(2) 27 | ellipse(x, y, 48, 48) 28 | 29 | angle += angleVel 30 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_09_wave_a/NOC_3_09_wave_a.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | startAngle = 0 8 | angleVel = 0.05 9 | 10 | def setup(): 11 | size(250, 200) 12 | smooth() 13 | 14 | def draw(): 15 | background(255) 16 | global startAngle, angleVel 17 | 18 | startAngle += 0.015 19 | angle = startAngle 20 | 21 | for x in range(0, width+1, 25): 22 | y = map(sin(angle), -1, 1, 0, height) 23 | 24 | stroke(0) 25 | fill(0, 50) 26 | strokeWeight(2) 27 | ellipse(x, y, 48, 48) 28 | 29 | angle += angleVel 30 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_09_wave_b/NOC_3_09_wave_b.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | startAngle = 0 8 | angleVel = 0.2 9 | 10 | def setup(): 11 | size(250, 200) 12 | smooth() 13 | 14 | def draw(): 15 | background(255) 16 | global startAngle, angleVel 17 | 18 | startAngle += 0.015 19 | angle = startAngle 20 | 21 | for x in range(0, width+1, 24): 22 | y = map(sin(angle), -1, 1, 0, height) 23 | 24 | stroke(0) 25 | fill(0, 50) 26 | strokeWeight(2) 27 | ellipse(x, y, 48, 48) 28 | 29 | angle += angleVel 30 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_09_wave_c/NOC_3_09_wave_c.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | startAngle = 0 8 | angleVel = 0.4 9 | 10 | def setup(): 11 | size(250, 200) 12 | smooth() 13 | 14 | def draw(): 15 | background(255) 16 | global startAngle, angleVel 17 | 18 | startAngle += 0.015 19 | angle = startAngle 20 | 21 | for x in range(0, width+1, 24): 22 | y = map(sin(angle), -1, 1, 0, height) 23 | 24 | stroke(0) 25 | fill(0, 50) 26 | strokeWeight(2) 27 | ellipse(x, y, 48, 48) 28 | 29 | angle += angleVel -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_10_PendulumExample/NOC_3_10_PendulumExample.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Pendulum 8 | # 9 | # A simple pendulum simulation 10 | # Given a pendulum with an angle theta (0 being the pendulum at rest) and 11 | # a radius r we can use sine to calculate the angular component of the 12 | # gravitational force. 13 | # 14 | # Gravity Force = Mass * Gravitational Constant; 15 | # Pendulum Force = Gravity Force * sine(theta) 16 | # Angular Acceleration = 17 | # Pendulum Force / Mass = gravitational acceleration * sine(theta); 18 | # 19 | # Note this is an ideal world scenario with no tension in the pendulum arm, 20 | # a more realistic formula might be: 21 | # Angular Acceleration = (g / R) * sine(theta) 22 | # 23 | # For a more substantial explanation, visit: 24 | # http://www.myphysicslab.com/pendulum1.html 25 | 26 | from pendulum import Pendulum 27 | 28 | def setup(): 29 | size(640, 360) 30 | 31 | # Make a new Pendulum with an origin position and armlength 32 | global p 33 | p = Pendulum(PVector(width/2, 0), 175) 34 | 35 | def draw(): 36 | background(255) 37 | p.go() 38 | 39 | def mousePressed(): 40 | p.clicked(mouseX, mouseY) 41 | 42 | def mouseReleased(): 43 | p.stopDragging() 44 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_10_PendulumExampleSimplified/NOC_3_10_PendulumExampleSimplified.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Pendulum 8 | # 9 | # A simple pendulum simulation 10 | # Given a pendulum with an angle theta (0 being the pendulum at rest) and a 11 | # radius r we can use sine to calculate the angular component of the 12 | # gravitational force. 13 | # 14 | # Gravity Force = Mass * Gravitational Constant; 15 | # Pendulum Force = Gravity Force * sine(theta) 16 | # Angular Acceleration = Pendulum Force / Mass 17 | # = Gravitational Constant * sine(theta); 18 | # 19 | # Note this is an ideal world scenario with no tension in the pendulum arm, a 20 | # more realistic formula might be: 21 | # Angular Acceleration = (G / R) * sine(theta) 22 | # 23 | # For a more substantial explanation, visit: 24 | # http://www.myphysicslab.com/pendulum1.html 25 | 26 | from pendulum import Pendulum 27 | 28 | def setup(): 29 | size(640,360) 30 | # Make a new Pendulum with an origin position and armlength 31 | global p 32 | p = Pendulum(PVector(width/2, 0), 175) 33 | 34 | def draw(): 35 | background(255) 36 | p.go() 37 | -------------------------------------------------------------------------------- /chp03_oscillation/NOC_3_11_spring/NOC_3_11_spring.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from mover import Bob 8 | from spring import Spring 9 | 10 | def setup(): 11 | size(640, 360) 12 | 13 | # Create objects at starting position 14 | # Note third argument in Spring constructor is "rest length" 15 | global bob, spring 16 | spring = Spring(width/2, 10, 100) 17 | bob = Bob(width/2, 100) 18 | 19 | def draw(): 20 | background(255) 21 | global bob, spring 22 | 23 | # Apply a gravity force to the bob 24 | gravity = PVector(0, 2) 25 | bob.applyForce(gravity) 26 | 27 | # Connect the bob to the spring (this calculates the force) 28 | spring.connect(bob) 29 | 30 | # Constrain spring distance between min and max 31 | spring.constrainLength(bob, 30, 200) 32 | 33 | # Update bob 34 | bob.update() 35 | # If it's being dragged 36 | bob.drag(mouseX, mouseY) 37 | 38 | # Draw a line between spring and bob 39 | spring.displayLine(bob) 40 | 41 | # Draw everything else 42 | bob.display() 43 | spring.display() 44 | 45 | fill(0) 46 | text("click on bob to drag", 10, height-5) 47 | 48 | # For mouse interaction with bob 49 | def mousePressed(): 50 | global bob 51 | bob.clicked(mouseX, mouseY) 52 | 53 | def mouseReleased(): 54 | global bob 55 | bob.stopDragging() 56 | 57 | 58 | -------------------------------------------------------------------------------- /chp03_oscillation/OOPWaveParticles/OOPWaveParticles.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Sine Wave 8 | 9 | from particle import Particle 10 | from wave import Wave 11 | 12 | def setup(): 13 | size(640, 360) 14 | global wave0, wave1 15 | # Initialize a wave with starting point, width, amplitude, and period 16 | wave0 = Wave(PVector(200, 75), 100, 20, 500) 17 | wave1 = Wave(PVector(150, 250), 300, 40, 220) 18 | 19 | def draw(): 20 | background(255) 21 | global wave0, wave1 22 | 23 | # Update and display waves 24 | wave0.calculate() 25 | wave0.display() 26 | 27 | wave1.calculate() 28 | wave1.display() 29 | -------------------------------------------------------------------------------- /chp03_oscillation/OOPWaveParticles/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | 9 | def __init__(self): 10 | self.position = PVector() 11 | 12 | def setposition(self, x, y): 13 | self.position.x = x 14 | self.position.y = y 15 | 16 | def display(self): 17 | fill(random(255)) 18 | ellipse(self.position.x, self.position.y, 16, 16) 19 | -------------------------------------------------------------------------------- /chp04_systems/CircleVsBlob/CircleVsBlob.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | def setup(): 8 | size(200, 200) 9 | 10 | global img 11 | img = loadImage("texture.png") 12 | 13 | background(0) 14 | image(img, 0, 0, width, height) 15 | save("blob.tif") 16 | 17 | background(0) 18 | fill(255) 19 | noStroke() 20 | ellipse(100, 100, width, height) 21 | save("circle.tif") 22 | 23 | def draw(): 24 | pass 25 | -------------------------------------------------------------------------------- /chp04_systems/CircleVsBlob/blob.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/CircleVsBlob/blob.tif -------------------------------------------------------------------------------- /chp04_systems/CircleVsBlob/circle.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/CircleVsBlob/circle.tif -------------------------------------------------------------------------------- /chp04_systems/CircleVsBlob/data/texture.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/CircleVsBlob/data/texture.gif -------------------------------------------------------------------------------- /chp04_systems/CircleVsBlob/data/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/CircleVsBlob/data/texture.png -------------------------------------------------------------------------------- /chp04_systems/CircleVsBlob/data/texture.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/CircleVsBlob/data/texture.psd -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_03_MovingParticleSystem/Exercise_4_03_MovingParticleSystem.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | from particle_system import ParticleSystem 9 | 10 | def setup(): 11 | size(640, 360) 12 | 13 | global ps 14 | ps = ParticleSystem(PVector(width/2, 50)) 15 | 16 | def draw(): 17 | background(255) 18 | global ps 19 | 20 | # Option 1: Move the ParticleSystem origin 21 | ps.origin.set(mouseX, mouseY, 0) 22 | 23 | ps.add_particle() 24 | ps.run() 25 | 26 | # Option 2: Move the ParticleSystem origin 27 | # ps.add_particle(mouseX, mouseY) -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_03_MovingParticleSystem/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, l): 12 | self.acceleration = PVector(0, 0.05) 13 | self. velocity = PVector(random(-1, 1), random(-2, 0)) 14 | self.position = l.get() 15 | self.lifespan = 255.0 16 | 17 | def run(self): 18 | self.update() 19 | self.display() 20 | 21 | def update(self): 22 | """Method to update position""" 23 | self.velocity.add(self.acceleration) 24 | self.position.add(self.velocity) 25 | self.lifespan -= 2.0 26 | 27 | def display(self): 28 | """Method to display""" 29 | stroke(0, self.lifespan) 30 | strokeWeight(2) 31 | fill(127, self.lifespan) 32 | ellipse(self.position.x, self.position.y, 12, 12) 33 | 34 | def is_dead(self): 35 | """Is the particle still useful?""" 36 | return self.lifespan < 0.0 -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_03_MovingParticleSystem/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | """Simple Particle System 11 | 12 | A class to describe a group of Particles 13 | A list is used to manage the particles. 14 | """ 15 | def __init__(self, location): 16 | # List of all the particles 17 | self.particles = [] 18 | 19 | # Origin point for where the particles are birthed 20 | self.origin = location.get() 21 | 22 | def add_particle(self): 23 | self.particles.append(Particle(self.origin)) 24 | 25 | def run(self): 26 | for i, p in enumerate(self.particles): 27 | p.run() 28 | if p.is_dead(): 29 | dead_p = self.particles.pop(i) 30 | 31 | def is_dead(self): 32 | """A Method to test is the particle system has particles""" 33 | return len(self.particles) == 0 34 | -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_04_asteroids/Exercise_4_04_asteroids.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Chapter 3: Asteroids exercise 8 | from spaceship import Spaceship 9 | 10 | def setup(): 11 | size(640, 360) 12 | global ship 13 | ship = Spaceship() 14 | 15 | def draw(): 16 | global ship 17 | background(255) 18 | 19 | # Update positon 20 | ship.update() 21 | # Wrap edges 22 | ship.wrapEdges() 23 | # Draw ship 24 | ship.display() 25 | 26 | fill(0) 27 | text("left right arrows to turn, z to thrust", 10, height-5) 28 | 29 | if keyPressed: 30 | if key == CODED and keyCode == LEFT: 31 | ship.turn(-0.03) 32 | elif key == CODED and keyCode == RIGHT: 33 | ship.turn(0.03) 34 | elif key == 'z' or key == 'Z': 35 | ship.thrust() -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_04_asteroids/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, l, dir): 12 | self.acceleration = dir.get() 13 | self. velocity = PVector.random2D() 14 | self.location = l.get() 15 | self.lifespan = 255.0 16 | 17 | def run(self): 18 | self.update() 19 | self.display() 20 | 21 | def update(self): 22 | """Method to update position""" 23 | self.velocity.add(self.acceleration) 24 | self.location.add(self.velocity) 25 | self.lifespan -= 2.0 26 | 27 | def display(self): 28 | """Method to display""" 29 | noStroke() 30 | fill(127, 0, 0, self.lifespan) 31 | ellipse(self.location.x, self.location.y, 8, 8) 32 | 33 | def is_dead(self): 34 | """Is the particle still useful?""" 35 | return self.lifespan < 0.0 -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_04_asteroids/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | """Simple Particle System 11 | 12 | A class to describe a group of Particles 13 | A list is used to manage the particles. 14 | """ 15 | def __init__(self): 16 | # List of all the particles 17 | self.particles = [] 18 | 19 | def add_particle(self, x, y, force): 20 | self.particles.append(Particle(PVector(x, y), force)) 21 | 22 | def run(self): 23 | for i, p in enumerate(self.particles): 24 | p.run() 25 | if p.is_dead(): 26 | dead_p = self.particles.pop(i) 27 | 28 | def is_dead(self): 29 | """A Method to test is the particle system has particles""" 30 | return len(self.particles) == 0 -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_06_Shatter/Exercise_4_06_Shatter.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle_system import ParticleSystem 8 | 9 | def setup(): 10 | size(640, 360) 11 | global ps 12 | ps = ParticleSystem(100, 100, 5) 13 | 14 | def draw(): 15 | background(255) 16 | 17 | global ps 18 | ps.display() 19 | ps.update() 20 | 21 | def mousePressed(): 22 | global ps 23 | ps.shatter() 24 | -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_06_Shatter/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, x, y, r): 12 | self.acceleration = PVector(0, 0.01) 13 | self.velocity = PVector.random2D() 14 | self.velocity.mult(0.5) 15 | self.position = PVector(x, y) 16 | self.lifespan = 255.0 17 | 18 | self.r = r 19 | 20 | def run(self): 21 | self.update() 22 | self.display() 23 | 24 | def update(self): 25 | """Method to update position""" 26 | self.velocity.add(self.acceleration) 27 | self.position.add(self.velocity) 28 | self.lifespan -= 2.0 29 | 30 | def display(self): 31 | """Method to display""" 32 | stroke(0) 33 | fill(0) 34 | rectMode(CENTER) 35 | rect(self.position.x, self.position.y, self.r, self.r) 36 | 37 | def is_dead(self): 38 | """Is the particle still useful?""" 39 | return self.lifespan < 0.0 -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_06_Shatter/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | 11 | def __init__(self, x, y, r): 12 | self.particles = [] 13 | 14 | self.rows = 20 15 | self.cols = 20 16 | 17 | self.intact = True 18 | 19 | for i in range(self.rows*self.cols): 20 | self.add_particle(x + (i%self.cols)*r, 21 | y + (i/self.rows)*r, 22 | r) 23 | 24 | def add_particle(self, x, y, r): 25 | self.particles.append(Particle(x, y, r)) 26 | 27 | def display(self): 28 | for p in self.particles: 29 | p.display() 30 | 31 | def shatter(self): 32 | self.intact = False 33 | 34 | def update(self): 35 | if not self.intact: 36 | for p in self.particles: 37 | p.update() -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_10_particleintersection/Exercise_4_10_particleintersection.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle_system import ParticleSystem 8 | 9 | def setup(): 10 | size(640, 360) 11 | 12 | global ps 13 | ps = ParticleSystem(PVector(width/2, 50)) 14 | 15 | def draw(): 16 | background(255) 17 | global ps 18 | 19 | ps.add_particle(mouseX, mouseY) 20 | ps.update() 21 | ps.intersection() 22 | ps.display() 23 | -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_10_particleintersection/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | def __init__(self, x, y): 9 | self.acceleration = PVector(0, 0.05) 10 | self.velocity = PVector(random(-1, 1), random(-2, 0)) 11 | self.position = PVector(x, y) 12 | self.lifespan = 255 13 | 14 | self.r = 6 15 | self.highlight = False 16 | 17 | def run(self): 18 | self.update() 19 | self.display() 20 | 21 | def intersect(self, particles): 22 | self.highlight = False 23 | for other in particles: 24 | if other != self: 25 | d = PVector.dist(other.position, self.position) 26 | if d < self.r: 27 | self.highlight = True 28 | 29 | def apply_force(self, force): 30 | self.acceleration.add(force) 31 | 32 | def update(self): 33 | """Method to update position.""" 34 | self.velocity.add(self.acceleration) 35 | self.position.add(self.velocity) 36 | self.acceleration.mult(0) 37 | self.lifespan -= 2.0 38 | 39 | def display(self): 40 | """Method to display""" 41 | stroke(0, self.lifespan) 42 | strokeWeight(2) 43 | fill(127, self.lifespan) 44 | if self.highlight: 45 | fill(127, 0, 0) 46 | ellipse(self.position.x, self.position.y, self.r*2, self.r*2) 47 | 48 | def is_dead(self): 49 | """Is the particle still useful?""" 50 | return self.lifespan < 0 -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_10_particleintersection/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | 11 | def __init__(self, position): 12 | self.particles = [] 13 | 14 | def add_particle(self, x, y): 15 | self.particles.append(Particle(x, y)) 16 | 17 | def display(self): 18 | for particle in self.particles: 19 | particle.display() 20 | 21 | def intersection(self): 22 | for particle in self.particles: 23 | particle.intersect(self.particles) 24 | 25 | def update(self): 26 | for i, p in enumerate(self.particles): 27 | p.update() 28 | if p.is_dead(): 29 | dead_p = self.particles.pop(i) 30 | -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_10_particlerepel/Exercise_4_10_particlerepel.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle_system import ParticleSystem 8 | 9 | def setup(): 10 | size(640, 360) 11 | global ps 12 | ps = ParticleSystem(PVector(width/2, 50)) 13 | 14 | def draw(): 15 | background(255) 16 | global ps 17 | 18 | ps.add_particle(random(width), random(height)) 19 | 20 | # gravity = PVector(0, 0.1) 21 | # ps.apply_force(gravity) 22 | 23 | ps.update() 24 | ps.intersection() 25 | ps.display() -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_10_particlerepel/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | def __init__(self, x, y): 9 | self.acceleration = PVector(0, 0.05) 10 | self.velocity = PVector(random(-1, 1), random(-2, 0)) 11 | self.position = PVector(x, y) 12 | self.lifespan = 255 13 | 14 | self.r = 6 15 | 16 | def run(self): 17 | self.update() 18 | self.display() 19 | 20 | def intersects(self, particles): 21 | for other in particles: 22 | if other != self: 23 | dir = PVector.sub(self.position, other.position) 24 | if dir.mag() < self.r*2: 25 | dir.setMag(0.5) 26 | self.apply_force(dir) 27 | 28 | def apply_force(self, force): 29 | self.acceleration.add(force) 30 | 31 | def update(self): 32 | """Method to update position.""" 33 | self.velocity.add(self.acceleration) 34 | self.position.add(self.velocity) 35 | self.acceleration.mult(0) 36 | self.lifespan -= 0.5 37 | 38 | def display(self): 39 | """Method to display""" 40 | stroke(0, self.lifespan) 41 | strokeWeight(2) 42 | fill(127, self.lifespan) 43 | ellipse(self.position.x, self.position.y, self.r*2, self.r*2) 44 | 45 | def is_dead(self): 46 | """Is the particle still useful?""" 47 | return self.lifespan < 0 -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_10_particlerepel/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | 11 | def __init__(self, position): 12 | self.particles = [] 13 | 14 | def add_particle(self, x, y): 15 | self.particles.append(Particle(x, y)) 16 | 17 | def display(self): 18 | for particle in self.particles: 19 | particle.display() 20 | 21 | def apply_force(self, f): 22 | for particle in self.particles: 23 | particle.apply_force(f) 24 | 25 | def intersection(self): 26 | for particle in self.particles: 27 | particle.intersects(self.particles) 28 | 29 | def update(self): 30 | for i, p in enumerate(self.particles): 31 | p.update() 32 | if p.is_dead(): 33 | dead_p = self.particles.pop(i) -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_12_ArrayofImages/Exercise_4_12_ArrayofImages.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle_system import ParticleSystem 8 | 9 | # List of Images for particle textures 10 | imgs = [] 11 | 12 | def setup(): 13 | size(640, 360, P2D) 14 | 15 | global imgs, ps 16 | 17 | imgs.append(loadImage("corona.png")) 18 | imgs.append(loadImage("emitter.png")) 19 | imgs.append(loadImage("particle.png")) 20 | imgs.append(loadImage("texture.png")) 21 | imgs.append(loadImage("reflection.png")) 22 | 23 | ps = ParticleSystem(imgs) 24 | 25 | def draw(): 26 | # Additive blending! 27 | blendMode(ADD) 28 | 29 | background(0) 30 | global ps 31 | 32 | up = PVector(0, -0.2) 33 | ps.apply_force(up) 34 | 35 | ps.run() 36 | 37 | for i in range(5): 38 | ps.add_particle(mouseX, mouseY) -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_12_ArrayofImages/data/corona.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/Exercise_4_12_ArrayofImages/data/corona.png -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_12_ArrayofImages/data/emitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/Exercise_4_12_ArrayofImages/data/emitter.png -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_12_ArrayofImages/data/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/Exercise_4_12_ArrayofImages/data/particle.png -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_12_ArrayofImages/data/reflection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/Exercise_4_12_ArrayofImages/data/reflection.png -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_12_ArrayofImages/data/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/Exercise_4_12_ArrayofImages/data/texture.png -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_12_ArrayofImages/data/texture.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/Exercise_4_12_ArrayofImages/data/texture.psd -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_12_ArrayofImages/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """Simple Particle class""" 9 | def __init__(self, x, y, img): 10 | self.acc = PVector(0, 0) 11 | self.vel = PVector.random2D() 12 | self.pos = PVector(x, y) 13 | self.lifespan = 255 14 | self.img = img 15 | 16 | def run(self): 17 | self.update() 18 | self.display() 19 | 20 | def apply_force(self, f): 21 | self.acc.add(f) 22 | 23 | def update(self): 24 | """Method to update position""" 25 | self.vel.add(self.acc) 26 | self.pos.add(self.vel) 27 | self.acc.mult(0) 28 | self.lifespan -= 2 29 | 30 | def display(self): 31 | """Method to display""" 32 | imageMode(CENTER) 33 | tint(self.lifespan) 34 | image(self.img, self.pos.x, self.pos.y, 32, 32) 35 | 36 | def is_dead(self): 37 | """Is the particle still useful?""" 38 | return self.lifespan <= 0 -------------------------------------------------------------------------------- /chp04_systems/Exercise_4_12_ArrayofImages/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | """A class to describe a group of particles 11 | A list is used to manage the particles.""" 12 | def __init__(self, imgs): 13 | self.textures = imgs 14 | 15 | # initialize the list of particles 16 | self.particles = [] 17 | 18 | def run(self): 19 | for i, particle in enumerate(self.particles): 20 | particle.run() 21 | if particle.is_dead(): 22 | self.particles.pop(i) 23 | 24 | def add_particle(self, x, y, p=None): 25 | if not p: 26 | r = int(random(len(self.textures))) 27 | self.particles.append(Particle(x, y, self.textures[r])) 28 | else: 29 | self.particles.append(p) 30 | 31 | def apply_force(self, f): 32 | for particle in self.particles: 33 | particle.apply_force(f) 34 | 35 | 36 | def dead(self): 37 | return len(self.particles) == 0 -------------------------------------------------------------------------------- /chp04_systems/NOC_4_01_SingleParticle/NOC_4_01_SingleParticle.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | def setup(): 10 | size(200, 200) 11 | global p 12 | p = Particle(PVector(width/2, 10)) 13 | smooth() 14 | 15 | def draw(): 16 | background(255) 17 | global p 18 | 19 | p.run() 20 | if p.is_dead(): 21 | print("Particle Dead!") 22 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_01_SingleParticle/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, l): 12 | self.acceleration = PVector(0, 0.05) 13 | self. velocity = PVector(random(-1, 1), random(-2, 0)) 14 | self.location = l.get() 15 | self.lifespan = 255.0 16 | 17 | def run(self): 18 | self.update() 19 | self.display() 20 | 21 | def update(self): 22 | self.velocity.add(self.acceleration) 23 | self.location.add(self.velocity) 24 | self.lifespan -= 2.0 25 | 26 | def display(self): 27 | stroke(0, self.lifespan) 28 | fill(0, self.lifespan) 29 | ellipse(self.location.x, self.location.y, 8, 8) 30 | 31 | def is_dead(self): 32 | return self.lifespan < 0.0 33 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_01_SingleParticle_trail/NOC_4_01_SingleParticle_trail.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | def setup(): 10 | size(800, 200) 11 | 12 | global p 13 | p = Particle(PVector(width/2, 20)) 14 | 15 | background(255) 16 | smooth() 17 | 18 | def draw(): 19 | global p 20 | 21 | if mousePressed: 22 | noStroke() 23 | fill(255, 5) 24 | rect(0, 0, width, height) 25 | 26 | p.run() 27 | if p.is_dead(): 28 | print("Particle dead!") 29 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_01_SingleParticle_trail/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, l): 12 | self.acceleration = PVector(0, 0.05) 13 | self. velocity = PVector(random(-1, 1), random(-2, 0)) 14 | self.location = l.get() 15 | self.lifespan = 255.0 16 | 17 | def run(self): 18 | self.update() 19 | self.display() 20 | 21 | def update(self): 22 | """Method to update position""" 23 | self.velocity.add(self.acceleration) 24 | self.location.add(self.velocity) 25 | self.lifespan -= 2.0 26 | 27 | def display(self): 28 | """Method to display""" 29 | stroke(0, self.lifespan) 30 | fill(0, self.lifespan) 31 | ellipse(self.location.x, self.location.y, 8, 8) 32 | 33 | def is_dead(self): 34 | """Is the particle still useful?""" 35 | return self.lifespan < 0.0 36 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_02_ArrayListParticles/NOC_4_02_ArrayListParticles.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | particles = [] 10 | 11 | def setup(): 12 | size(640, 360) 13 | 14 | def draw(): 15 | background(255) 16 | global particles 17 | 18 | particles.append(Particle(PVector(width/2, 50))) 19 | 20 | for i, p in enumerate(particles): 21 | p.run() 22 | if p.is_dead(): 23 | dead_p = particles.pop(i) -------------------------------------------------------------------------------- /chp04_systems/NOC_4_02_ArrayListParticles/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, l): 12 | self.acceleration = PVector(0, 0.05) 13 | self. velocity = PVector(random(-1, 1), random(-2, 0)) 14 | self.location = l.get() 15 | self.lifespan = 255.0 16 | 17 | def run(self): 18 | self.update() 19 | self.display() 20 | 21 | def update(self): 22 | """Method to update position""" 23 | self.velocity.add(self.acceleration) 24 | self.location.add(self.velocity) 25 | self.lifespan -= 2.0 26 | 27 | def display(self): 28 | """Method to display""" 29 | stroke(0, self.lifespan) 30 | fill(0, self.lifespan) 31 | ellipse(self.location.x, self.location.y, 8, 8) 32 | 33 | def is_dead(self): 34 | """Is the particle still useful?""" 35 | return self.lifespan < 0.0 36 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_03_ParticleSystemClass/NOC_4_03_ParticleSystemClass.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | from particle_system import ParticleSystem 9 | 10 | def setup(): 11 | size(640, 360) 12 | global ps 13 | ps = ParticleSystem(PVector(width/2, 50)) 14 | 15 | def draw(): 16 | background(255) 17 | global ps 18 | ps.add_particle() 19 | ps.run() -------------------------------------------------------------------------------- /chp04_systems/NOC_4_03_ParticleSystemClass/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, l): 12 | self.acceleration = PVector(0, 0.05) 13 | self.velocity = PVector(random(-1, 1), random(-2, 0)) 14 | self.location = l.get() 15 | self.lifespan = 255.0 16 | 17 | def run(self): 18 | self.update() 19 | self.display() 20 | 21 | def update(self): 22 | self.velocity.add(self.acceleration) 23 | self.location.add(self.velocity) 24 | self.lifespan -= 2.0 25 | 26 | def display(self): 27 | stroke(0, self.lifespan) 28 | fill(0, self.lifespan) 29 | ellipse(self.location.x, self.location.y, 8, 8) 30 | 31 | def is_dead(self): 32 | return self.lifespan < 0.0 33 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_03_ParticleSystemClass/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # A simple particle system 8 | 9 | from particle import Particle 10 | 11 | class ParticleSystem(object): 12 | def __init__(self, location): 13 | self.particles = [] 14 | self.origin = location.get() 15 | 16 | def add_particle(self): 17 | self.particles.append(Particle(self.origin)) 18 | 19 | def run(self): 20 | for i, p in enumerate(self.particles): 21 | p.run() 22 | if p.is_dead(): 23 | dead_p = self.particles.pop(i) 24 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_04_SystemofSystems/NOC_4_04_SystemofSystems.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Simple Particle System 8 | 9 | # Particles are generated each cycle through draw(), 10 | # fall with gravity and fade out over time 11 | # A ParticleSystem object manages a variable size 12 | # list of particles. 13 | 14 | from particle import Particle 15 | from particle_system import ParticleSystem 16 | 17 | systems = [] 18 | 19 | def setup(): 20 | size(640, 360) 21 | 22 | def draw(): 23 | background(255) 24 | global systems 25 | for ps in systems: 26 | ps.run() 27 | ps.add_particle() 28 | 29 | fill(0) 30 | text("click mouse to add particle systems", 10, height-30) 31 | 32 | def mousePressed(): 33 | global systems 34 | systems.append(ParticleSystem(1, PVector(mouseX, mouseY))) -------------------------------------------------------------------------------- /chp04_systems/NOC_4_04_SystemofSystems/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, l): 12 | self.acceleration = PVector(0, 0.05) 13 | self.velocity = PVector(random(-1, 1), random(-2, 0)) 14 | self.location = l.get() 15 | self.lifespan = 255.0 16 | 17 | def run(self): 18 | self.update() 19 | self.display() 20 | 21 | def update(self): 22 | """Method to update position""" 23 | self.velocity.add(self.acceleration) 24 | self.location.add(self.velocity) 25 | self.lifespan -= 2.0 26 | 27 | def display(self): 28 | """Method to display""" 29 | stroke(0, self.lifespan) 30 | fill(0, self.lifespan) 31 | ellipse(self.location.x, self.location.y, 8, 8) 32 | 33 | def is_dead(self): 34 | """Is the particle still useful?""" 35 | return self.lifespan < 0.0 36 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_04_SystemofSystems/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | """Simple Particle System 11 | 12 | A class to describe a group of Particles 13 | A list is used to manage the particles. 14 | """ 15 | def __init__(self, num, location): 16 | # List of all the particles 17 | self.particles = [] 18 | 19 | # Origin point for where the particles are birthed 20 | self.origin = location.get() 21 | 22 | # Add `num` amount of particles 23 | for i in range(num): 24 | self.add_particle() 25 | 26 | def add_particle(self): 27 | self.particles.append(Particle(self.origin)) 28 | 29 | def run(self): 30 | for i, p in enumerate(self.particles): 31 | p.run() 32 | if p.is_dead(): 33 | dead_p = self.particles.pop(i) 34 | 35 | def is_dead(self): 36 | """A Method to test is the particle system has particles""" 37 | return len(self.particles) == 0 38 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/NOC_4_05_ParticleSystemInheritancePolymorphism.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle_system import ParticleSystem 8 | 9 | def setup(): 10 | size(640, 360) 11 | global ps 12 | ps = ParticleSystem(PVector(width/2, 50)) 13 | 14 | def draw(): 15 | background(255) 16 | global ps 17 | ps.add_particle() 18 | ps.run() 19 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/confetti.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class Confetti(Particle): 10 | def __init__(self, location): 11 | super(Confetti, self).__init__(location) 12 | 13 | def display(self): 14 | rectMode(CENTER) 15 | fill(127, self.lifespan) 16 | stroke(0, self.lifespan) 17 | strokeWeight(2) 18 | pushMatrix() 19 | translate(self.position.x, self.position.y) 20 | theta = map(self.position.x, 0, width, 0, TWO_PI*2) 21 | rotate(theta) 22 | rect(0, 0, 12, 12) 23 | popMatrix() -------------------------------------------------------------------------------- /chp04_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, l): 12 | self.acceleration = PVector(0, 0.05) 13 | self.velocity = PVector(random(-1, 1), random(-2, 0)) 14 | self.position = l.get() 15 | self.lifespan = 255.0 16 | 17 | def run(self): 18 | self.update() 19 | self.display() 20 | 21 | def update(self): 22 | """Method to update position""" 23 | self.velocity.add(self.acceleration) 24 | self.position.add(self.velocity) 25 | self.lifespan -= 2.0 26 | 27 | def display(self): 28 | """Method to display""" 29 | stroke(0, self.lifespan) 30 | fill(0, self.lifespan) 31 | ellipse(self.position.x, self.position.y, 8, 8) 32 | 33 | def is_dead(self): 34 | """Is the particle still useful?""" 35 | return self.lifespan < 0.0 -------------------------------------------------------------------------------- /chp04_systems/NOC_4_05_ParticleSystemInheritancePolymorphism/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | from confetti import Confetti 9 | 10 | class ParticleSystem(object): 11 | """Simple Particle System 12 | 13 | A class to describe a group of Particles 14 | A list is used to manage the particles. 15 | """ 16 | def __init__(self, position): 17 | # List of all the particles 18 | self.particles = [] 19 | 20 | # Origin point for where the particles are birthed 21 | self.origin = position.get() 22 | 23 | def add_particle(self): 24 | r = random(1) 25 | if r < 0.5: 26 | self.particles.append(Particle(self.origin)) 27 | else: 28 | self.particles.append(Confetti(self.origin)) 29 | 30 | def run(self): 31 | for i, p in enumerate(self.particles): 32 | p.run() 33 | if p.is_dead(): 34 | dead_p = self.particles.pop(i) -------------------------------------------------------------------------------- /chp04_systems/NOC_4_06_ParticleSystemForces/NOC_4_06_ParticleSystemForces.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle_system import ParticleSystem 8 | 9 | def setup(): 10 | size(640, 360) 11 | global ps 12 | ps = ParticleSystem(PVector(width/2, 50)) 13 | 14 | def draw(): 15 | background(255) 16 | 17 | global ps 18 | gravity = PVector(0, 0.1) 19 | ps.apply_force(gravity) 20 | 21 | ps.add_particle() 22 | ps.run() -------------------------------------------------------------------------------- /chp04_systems/NOC_4_06_ParticleSystemForces/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | def __init__(self, l): 9 | self.acceleration = PVector(0, 0) 10 | self.velocity = PVector(random(-1, 1), random(-2, 0)) 11 | self.position = l.get() 12 | self.lifespan = 255.0 13 | self.mass = 1 14 | 15 | def run(self): 16 | self.update() 17 | self.display() 18 | 19 | def apply_force(self, force): 20 | f = force.get() 21 | f.div(self.mass) 22 | self.acceleration.add(f) 23 | 24 | def update(self): 25 | """Method to update position""" 26 | self.velocity.add(self.acceleration) 27 | self.position.add(self.velocity) 28 | self.acceleration.mult(0) 29 | self.lifespan -= 2.0 30 | 31 | def display(self): 32 | """Method to display""" 33 | stroke(0, self.lifespan) 34 | strokeWeight(2) 35 | fill(0, self.lifespan) 36 | ellipse(self.position.x, self.position.y, 12, 12) 37 | 38 | def is_dead(self): 39 | """Is the particle still useful?""" 40 | return self.lifespan < 0.0 41 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_06_ParticleSystemForces/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | def __init__(self, position): 11 | # List of all the particles 12 | self.particles = [] 13 | 14 | # Origin point for where the particles are birthed 15 | self.origin = position.get() 16 | 17 | def add_particle(self): 18 | self.particles.append(Particle(self.origin)) 19 | 20 | def apply_force(self, f): 21 | """A function to apply force to all particles""" 22 | for p in self.particles: 23 | p.apply_force(f) 24 | 25 | def run(self): 26 | for i, p in enumerate(self.particles): 27 | p.run() 28 | if p.is_dead(): 29 | dead_p = self.particles.pop(i) 30 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_07_ParticleSystemForcesRepeller/NOC_4_07_ParticleSystemForcesRepeller.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle_system import ParticleSystem 8 | from repeller import Repeller 9 | 10 | def setup(): 11 | size(640, 360) 12 | global ps, repeller 13 | ps = ParticleSystem(PVector(width/2, 50)) 14 | repeller = Repeller(width/2 - 20, height/2) 15 | 16 | def draw(): 17 | background(255) 18 | global ps, repeller 19 | 20 | ps.add_particle() 21 | 22 | # Apply gravity to all particles 23 | gravity = PVector(0, 0.1) 24 | ps.apply_force(gravity) 25 | 26 | ps.apply_repeller(repeller) 27 | 28 | repeller.display() 29 | ps.run() -------------------------------------------------------------------------------- /chp04_systems/NOC_4_07_ParticleSystemForcesRepeller/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | def __init__(self, l): 9 | self.acceleration = PVector(0, 0) 10 | self.velocity = PVector(random(-1, 1), random(-2, 0)) 11 | self.position = l.get() 12 | self.lifespan = 255.0 13 | self.mass = 1 14 | 15 | def run(self): 16 | self.update() 17 | self.display() 18 | 19 | def apply_force(self, force): 20 | f = force.get() 21 | f.div(self.mass) 22 | self.acceleration.add(f) 23 | 24 | def update(self): 25 | """Method to update position""" 26 | self.velocity.add(self.acceleration) 27 | self.position.add(self.velocity) 28 | self.acceleration.mult(0) 29 | self.lifespan -= 2.0 30 | 31 | def display(self): 32 | """Method to display""" 33 | stroke(0, self.lifespan) 34 | strokeWeight(2) 35 | fill(0, self.lifespan) 36 | ellipse(self.position.x, self.position.y, 12, 12) 37 | 38 | def is_dead(self): 39 | """Is the particle still useful?""" 40 | return self.lifespan < 0.0 41 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_07_ParticleSystemForcesRepeller/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | def __init__(self, position): 11 | # List of all the particles 12 | self.particles = [] 13 | 14 | # Origin point for where the particles are birthed 15 | self.origin = position.get() 16 | 17 | def add_particle(self): 18 | self.particles.append(Particle(self.origin)) 19 | 20 | def apply_force(self, f): 21 | """A function to apply force to all particles""" 22 | for p in self.particles: 23 | p.apply_force(f) 24 | 25 | def run(self): 26 | for i, p in enumerate(self.particles): 27 | p.run() 28 | if p.is_dead(): 29 | dead_p = self.particles.pop(i) 30 | 31 | def apply_repeller(self, r): 32 | for p in self.particles: 33 | force = r.repel(p) 34 | p.apply_force(force) 35 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_07_ParticleSystemForcesRepeller/repeller.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port: Abhik Pal 6 | 7 | # Particle + Forces 8 | 9 | class Repeller(object): 10 | """A very basic repeller class.""" 11 | def __init__(self, x, y): 12 | # Gravitational Constant 13 | self.G = 100 14 | 15 | # Position 16 | self.position = PVector(x, y) 17 | self.r = 10 18 | 19 | def repel(self, m): 20 | # Calculate the direction of force 21 | force = PVector.sub(self.position, m.position) 22 | 23 | # Distance between objects 24 | d = force.mag() 25 | 26 | # Limiting the distance to eliminate "extreme" results for 27 | # very close or very far objects 28 | d = constrain(d, 5, 100) 29 | 30 | # Normalize vector (distance doesn't matter here, we just 31 | # want this vector for direction) 32 | force.normalize(); 33 | 34 | # Calculate gravitional force magnitude 35 | strength = float(-1 * self.G)/float(d * d) 36 | 37 | # Get force vector --> magnitude * direction 38 | force.mult(strength) 39 | 40 | return force 41 | 42 | def display(self): 43 | stroke(0) 44 | strokeWeight(2) 45 | fill(175) 46 | ellipse(self.position.x, self.position.y, self.r*2, self.r*2) -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke/NOC_4_08_ParticleSystemSmoke.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Smoke Particle System 8 | 9 | # A basic smoke effect using a particle system 10 | # Each particle is rendered as an alpha masked image 11 | 12 | from particle_system import ParticleSystem 13 | 14 | def setup(): 15 | size(640, 360) 16 | img = loadImage("texture.png") 17 | global ps 18 | ps = ParticleSystem(0, PVector(width/2, height-75), img) 19 | 20 | def draw(): 21 | background(0) 22 | global ps 23 | 24 | # Calculate the "wind" force based on mouse horizontal position 25 | dx = map(mouseX, 0, width, -0.2, 0.2) 26 | wind = PVector(dx, 0) 27 | ps.apply_force(wind) 28 | ps.run() 29 | 30 | for i in range(2): 31 | ps.add_particle() 32 | 33 | draw_vector(wind, PVector(width/2, 50, 0), 500) 34 | 35 | 36 | def draw_vector(v, pos, scayl): 37 | """ 38 | Renders a vector object `v` as an arrow and a position `pos` 39 | """ 40 | pushMatrix() 41 | arrow_size = 4 42 | 43 | # Translate position to draw vector 44 | translate(pos.x, pos.y) 45 | stroke(255) 46 | 47 | # Call the vector heading fucntion to thet direction 48 | # (note that pointing up is a heading of 0) 49 | rotate(v.heading2D()) 50 | 51 | # Calculate the length of the vector and scale it to be bigger or smaller 52 | # if necessary. 53 | length = v.mag() * scayl 54 | 55 | # Draw three lines to make an arrow 56 | # (draw pointing up since we've rotated to the proper direction) 57 | line(0, 0, length, 0); 58 | line(length, 0, length-arrow_size, arrow_size/2.0); 59 | line(length, 0, length-arrow_size, -arrow_size/2.0); 60 | 61 | popMatrix() -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke/data/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/NOC_4_08_ParticleSystemSmoke/data/texture.png -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke/data/texture.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/NOC_4_08_ParticleSystemSmoke/data/texture.psd -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | def __init__(self, l, img): 9 | self.acceleration = PVector(0, 0) 10 | 11 | vx = randomGaussian()*0.3 12 | vy = randomGaussian()*0.3 - 1 13 | self.velocity = PVector(vx, vy) 14 | 15 | self.position = l.get() 16 | 17 | self.lifespan = 100 18 | self.img = img 19 | 20 | def run(self): 21 | self.update() 22 | self.display() 23 | 24 | def apply_force(self, force): 25 | self.acceleration.add(force) 26 | 27 | def update(self): 28 | """Method to update position""" 29 | self.velocity.add(self.acceleration) 30 | self.position.add(self.velocity) 31 | self.lifespan -= 2.5 32 | self.acceleration.mult(0) 33 | 34 | def display(self): 35 | """Method to display""" 36 | imageMode(CENTER) 37 | tint(255, self.lifespan) 38 | image(self.img, self.position.x, self.position.y) 39 | 40 | def is_dead(self): 41 | """Is the particle still useful?""" 42 | return self.lifespan <= 0.0 43 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Smoke particle system 8 | 9 | from particle import Particle 10 | 11 | class ParticleSystem(object): 12 | """ 13 | A class to describe a group of particles 14 | A python list is used to manage the list of Particles (duh) 15 | """ 16 | def __init__(self, num, position, img): 17 | # List of all the particles 18 | self.particles = [] 19 | 20 | # Origin point for where the particles are birthed 21 | self.origin = position.get() 22 | self.img = img 23 | 24 | # Add `num` amount of particles 25 | for i in range(num): 26 | self.particles.append(Particle(self.origin, self.img)) 27 | 28 | def add_particle(self): 29 | self.particles.append(Particle(self.origin, self.img)) 30 | 31 | def apply_force(self, f): 32 | """A function to apply force to all particles""" 33 | for p in self.particles: 34 | p.apply_force(f) 35 | 36 | def run(self): 37 | for i, p in enumerate(self.particles): 38 | p.run() 39 | if p.is_dead(): 40 | dead_p = self.particles.pop(i) -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke_b/NOC_4_08_ParticleSystemSmoke_b.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Smoke Particle System 8 | 9 | # A basic smoke effect using a particle system 10 | # Each particle is rendered as an alpha masked image 11 | 12 | from particle_system import ParticleSystem 13 | 14 | def setup(): 15 | size(640, 360) 16 | img = loadImage("texture.png") 17 | global ps 18 | ps = ParticleSystem(0, PVector(width/2, height-75), img) 19 | smooth() 20 | 21 | def draw(): 22 | background(0) 23 | global ps 24 | 25 | # Calculate the "wind" force based on mouse horizontal position 26 | dx = map(mouseX, 0, width, -0.2, 0.2) 27 | wind = PVector(dx, 0) 28 | ps.apply_force(wind) 29 | ps.run() 30 | 31 | for i in range(2): 32 | ps.add_particle() 33 | 34 | draw_vector(wind, PVector(width/2, 50, 0), 500) 35 | 36 | 37 | def draw_vector(v, pos, scayl): 38 | """ 39 | Renders a vector object `v` as an arrow and a position `pos` 40 | """ 41 | pushMatrix() 42 | arrow_size = 4 43 | 44 | # Translate position to draw vector 45 | translate(pos.x, pos.y) 46 | stroke(255) 47 | 48 | # Call the vector heading fucntion to thet direction 49 | # (note that pointing up is a heading of 0) 50 | rotate(v.heading2D()) 51 | 52 | # Calculate the length of the vector and scale it to be bigger or smaller 53 | # if necessary. 54 | length = v.mag() * scayl 55 | 56 | # Draw three lines to make an arrow 57 | # (draw pointing up since we've rotated to the proper direction) 58 | line(0, 0, length, 0); 59 | line(length, 0, length-arrow_size, arrow_size/2.0); 60 | line(length, 0, length-arrow_size, -arrow_size/2.0); 61 | 62 | popMatrix() -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke_b/data/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/NOC_4_08_ParticleSystemSmoke_b/data/texture.png -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke_b/data/texture.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/NOC_4_08_ParticleSystemSmoke_b/data/texture.psd -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke_b/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | Simple particle. Renders the image as an image. 10 | """ 11 | def __init__(self, l, img): 12 | self.acceleration = PVector(0, 0) 13 | 14 | vx = randomGaussian()*0.3 15 | vy = randomGaussian()*0.3 - 1 16 | self.velocity = PVector(vx, vy) 17 | 18 | self.position = l.get() 19 | 20 | self.lifespan = 100 21 | self.img = img 22 | 23 | def run(self): 24 | self.update() 25 | self.display() 26 | 27 | def apply_force(self, force): 28 | self.acceleration.add(force) 29 | 30 | def update(self): 31 | """Method to update position""" 32 | self.velocity.add(self.acceleration) 33 | self.position.add(self.velocity) 34 | self.lifespan -= 2.5 35 | self.acceleration.mult(0) 36 | 37 | def display(self): 38 | """Method to display""" 39 | # Drawing a circle instead 40 | fill(255,self.lifespan) 41 | noStroke() 42 | ellipse(self.position.x, self.position.y, \ 43 | self.img.width, self.img.height); 44 | 45 | def is_dead(self): 46 | """Is the particle still useful?""" 47 | return self.lifespan <= 0.0 -------------------------------------------------------------------------------- /chp04_systems/NOC_4_08_ParticleSystemSmoke_b/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Smoke particle system 8 | 9 | from particle import Particle 10 | 11 | class ParticleSystem(object): 12 | """ 13 | A class to describe a group of particles 14 | A python list is used to manage the list of Particles (duh) 15 | """ 16 | def __init__(self, num, position, img): 17 | # List of all the particles 18 | self.particles = [] 19 | 20 | # Origin point for where the particles are birthed 21 | self.origin = position.get() 22 | self.img = img 23 | 24 | # Add `num` amount of particles 25 | for i in range(num): 26 | self.particles.append(Particle(self.origin, self.img)) 27 | 28 | def add_particle(self): 29 | self.particles.append(Particle(self.origin, self.img)) 30 | 31 | def apply_force(self, f): 32 | """A function to apply force to all particles""" 33 | for p in self.particles: 34 | p.apply_force(f) 35 | 36 | def run(self): 37 | for i, p in enumerate(self.particles): 38 | p.run() 39 | if p.is_dead(): 40 | dead_p = self.particles.pop(i) 41 | -------------------------------------------------------------------------------- /chp04_systems/NOC_4_09_AdditiveBlending/NOC_4_09_AdditiveBlending.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Additive Blending 8 | 9 | # This example demonstrates a "glow" like effect using 10 | # additive blending with a Particle system. By playing 11 | # with colors, textures, etc. you can achieve a variety 12 | # of looks. 13 | 14 | from particle_system import ParticleSystem 15 | 16 | def setup(): 17 | size(640, 360, P2D) 18 | 19 | # Create an alpha masked image to be applied as the particle's 20 | # texture. 21 | global img 22 | img = loadImage("texture.png") 23 | 24 | global ps 25 | ps = ParticleSystem(PVector(width/2, 50), img) 26 | 27 | def draw(): 28 | # Additive blending! 29 | blendMode(ADD) 30 | 31 | background(0) 32 | 33 | global ps 34 | global img 35 | ps.run() 36 | for i in range(10): 37 | ps.add_particle() -------------------------------------------------------------------------------- /chp04_systems/NOC_4_09_AdditiveBlending/data/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/NOC_4_09_AdditiveBlending/data/texture.png -------------------------------------------------------------------------------- /chp04_systems/NOC_4_09_AdditiveBlending/data/texture.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp04_systems/NOC_4_09_AdditiveBlending/data/texture.psd -------------------------------------------------------------------------------- /chp04_systems/NOC_4_09_AdditiveBlending/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | Simple particle. Renders the image as an image. 10 | """ 11 | def __init__(self, l, img): 12 | self.acceleration = PVector(0, 0.05, 0) 13 | self.velocity = PVector(random(-1, 1), random(-1, 1), 0) 14 | self.velocity.mult(2) 15 | 16 | self.position = l.get() 17 | self.img = img 18 | 19 | self.lifespan = 255 20 | 21 | def run(self): 22 | self.update() 23 | self.render() 24 | 25 | def render(self): 26 | imageMode(CENTER) 27 | tint(self.lifespan) 28 | image(self.img, self.position.x, self.position.y) 29 | 30 | def update(self): 31 | """Method to update position""" 32 | self.velocity.add(self.acceleration) 33 | self.position.add(self.velocity) 34 | self.lifespan -= 2 35 | 36 | def is_dead(self): 37 | """Is the particle still useful?""" 38 | return self.lifespan <= 0.0 -------------------------------------------------------------------------------- /chp04_systems/NOC_4_09_AdditiveBlending/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleSystem(object): 10 | """ 11 | A class to describe a group of particles 12 | A python list is used to manage the list of Particles (duh) 13 | """ 14 | def __init__(self, position, img): 15 | # List of all the particles 16 | self.particles = [] 17 | 18 | # Origin point for where the particles are birthed 19 | self.origin = position.get() 20 | self.img = img 21 | 22 | def add_particle(self, p=None): 23 | if not p: 24 | self.particles.append(Particle(self.origin, self.img)) 25 | else: 26 | self.particles.append(p) 27 | 28 | def run(self): 29 | for i, p in enumerate(self.particles): 30 | p.run() 31 | if p.is_dead(): 32 | dead_p = self.particles.pop(i) 33 | 34 | def dead(self): 35 | """ 36 | A method to test if the particle system still has particles. 37 | """ 38 | return len(self.particles) == 0 -------------------------------------------------------------------------------- /chp04_systems/ParticleSystemInheritance_pushpop/ParticleSystemInheritance_pushpop.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from particle_system import ParticleSystem 6 | 7 | def setup(): 8 | size(640, 360) 9 | global ps 10 | ps = ParticleSystem(PVector(width/2, 50)) 11 | 12 | def draw(): 13 | background(255) 14 | global ps 15 | 16 | ps.add_particle() 17 | ps.run() 18 | -------------------------------------------------------------------------------- /chp04_systems/ParticleSystemInheritance_pushpop/particle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Particle(object): 8 | """ 9 | A Simple Paticle Class 10 | """ 11 | def __init__(self, p): 12 | self.acceleration = PVector(0, 0.05) 13 | self.velocity = PVector(random(-1, 1), random(-2, 0)) 14 | self.position = p.get() 15 | self.lifespan = 255.0 16 | 17 | def run(self): 18 | self.update() 19 | self.push() 20 | self.display() 21 | self.pop() 22 | 23 | def push(self): 24 | pushMatrix() 25 | 26 | def pop(self): 27 | popMatrix() 28 | 29 | def update(self): 30 | """Method to update position""" 31 | self.velocity.add(self.acceleration) 32 | self.position.add(self.velocity) 33 | self.lifespan -= 2.0 34 | 35 | def display(self): 36 | """Method to display""" 37 | stroke(0, self.lifespan) 38 | fill(0, self.lifespan) 39 | translate(self.position.x, self.position.y) 40 | ellipse(0, 0, 8, 8) 41 | 42 | def is_dead(self): 43 | """Is the particle still useful?""" 44 | return self.lifespan < 0.0 -------------------------------------------------------------------------------- /chp04_systems/ParticleSystemInheritance_pushpop/particle_child.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | 9 | class ParticleChild(Particle): 10 | # We override the display() method. 11 | def display(self): 12 | super(ParticleChild, self).display() 13 | theta = map(self.position.x, 0, width, 0, TWO_PI*2) 14 | rotate(theta) 15 | stroke(0) 16 | line(0, 0, 50, 0) 17 | -------------------------------------------------------------------------------- /chp04_systems/ParticleSystemInheritance_pushpop/particle_system.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from particle import Particle 8 | from particle_child import ParticleChild 9 | 10 | class ParticleSystem(object): 11 | """Simple Particle System 12 | 13 | A class to describe a group of Particles 14 | A list is used to manage the particles. 15 | """ 16 | def __init__(self, position): 17 | # List of all the particles 18 | self.particles = [] 19 | 20 | # Origin point for where the particles are birthed 21 | self.origin = position.get() 22 | 23 | def add_particle(self): 24 | r = random(1) 25 | if r < 0.5: 26 | self.particles.append(Particle(self.origin)) 27 | else: 28 | self.particles.append(ParticleChild(self.origin)) 29 | 30 | def run(self): 31 | for i, p in enumerate(self.particles): 32 | p.run() 33 | if p.is_dead(): 34 | dead_p = self.particles.pop(i) 35 | -------------------------------------------------------------------------------- /chp04_systems/simpleInheritance/circle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from shape import Shape 8 | 9 | class Circle(Shape): 10 | def __init__(self, x, y, r, c): 11 | """Inherits all instance variables from parent + adding one""" 12 | Shape.__init__(self, x, y, r) 13 | self.c = c 14 | 15 | def jiggle(self): 16 | """Call the parent for jiggle but do more stuff too.""" 17 | super(Circle, self).jiggle() 18 | self.r += random(-1, 1) 19 | self.r = constrain(self.r, 0, 100) 20 | 21 | def change_color(self): 22 | """The change_color() method us unique to the Circle class""" 23 | self.c = color(random(255)) 24 | 25 | def display(self): 26 | fill(self.c) 27 | stroke(0) 28 | ellipse(self.x, self.y, self.r, self.r) -------------------------------------------------------------------------------- /chp04_systems/simpleInheritance/shape.py: -------------------------------------------------------------------------------- 1 | # Learning Processing 2 | # Daniel Shiffman 3 | # http://www.learningprocessing.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Example 22-1: Inheritance 8 | 9 | class Shape(object): 10 | def __init__(self, x, y, r): 11 | self.x = x 12 | self.y = y 13 | self.r = r 14 | 15 | def jiggle(self): 16 | self.x += random(-1, 1) 17 | self.y += random(-1, 1) 18 | 19 | def display(self): 20 | """ 21 | A generic shape does not really know how to be displayed. 22 | This will be overridden in the child classes 23 | """ 24 | point(self.x, self.y) 25 | -------------------------------------------------------------------------------- /chp04_systems/simpleInheritance/simpleInheritance.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | # Object oriented programming allows us to define classes in terms of other 8 | # classes. A class can be a subclass (aka "child" ) of a super class (aka 9 | # "parent"). This is a simple example demonstrating this concept, known as 10 | # "inheritance." 11 | 12 | from square import Square 13 | from circle import Circle 14 | 15 | def setup(): 16 | size(200, 200) 17 | 18 | # A circle and a square 19 | global s, c 20 | s = Square(75, 75, 10) 21 | c = Circle(125, 125, 20, color(175)) 22 | 23 | def draw(): 24 | background(255) 25 | global s, c 26 | 27 | c.jiggle() 28 | s.jiggle() 29 | 30 | c.display() 31 | s.display() 32 | -------------------------------------------------------------------------------- /chp04_systems/simpleInheritance/square.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from shape import Shape 8 | 9 | class Square(Shape): 10 | """ 11 | Variables are inherited from the parent. 12 | We could also add variables unique to the Square class if we so desire 13 | """ 14 | def display(self): 15 | """The square overrides its parent for display""" 16 | rectMode(CENTER) 17 | fill(175) 18 | stroke(0) 19 | rect(self.x, self.y, self.r, self.r) -------------------------------------------------------------------------------- /chp04_systems/simplePolymorphism/circle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from shape import Shape 8 | 9 | class Circle(Shape): 10 | def __init__(self, x, y, r, c): 11 | # Call the parent constructor 12 | super(Circle, self).__init__(x, y, r) 13 | 14 | # Inherits all instance variables from parent + adding one 15 | # Also deal with the this new instance varibale 16 | self.c = c 17 | 18 | def jiggle(self): 19 | # Call the parent jiggle, but dos ome more stuff too. 20 | super(Circle, self).jiggle() 21 | 22 | # The circle jiggles its size as well as its x, y position 23 | self.r += random(-1, 1) 24 | self.r = constrain(self.r, 0, 100) 25 | 26 | def change_color(self): 27 | # The change_color() function is unique to the Circle class. 28 | self.c = color(random(255)) 29 | 30 | def display(self): 31 | ellipseMode(CENTER) 32 | fill(self.c) 33 | stroke(0) 34 | ellipse(self.x, self.y, self.r, self.r) -------------------------------------------------------------------------------- /chp04_systems/simplePolymorphism/shape.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | class Shape(object): 8 | def __init__(self, x, y, r): 9 | self.x = x 10 | self.y = y 11 | self.r = r 12 | 13 | def jiggle(self): 14 | self.x += random(-1, 1) 15 | self.y += random(-1, 1) 16 | 17 | def display(self): 18 | """ 19 | A generic shape does not really know how to be fisplayed 20 | This will be overridden in the child classes. 21 | """ 22 | point(self.x, self.y) 23 | -------------------------------------------------------------------------------- /chp04_systems/simplePolymorphism/simplePolymorphism.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from circle import Circle 6 | from square import Square 7 | 8 | # A list of Shapes 9 | shapes = [] 10 | 11 | def setup(): 12 | size(200, 200) 13 | 14 | global shapes 15 | for i in range(30): 16 | r = int(random(0, 2)) 17 | if r == 0: 18 | shapes.append(Circle(100, 100, 10, color(random(255), 100))) 19 | else: 20 | shapes.append(Square(100, 100, 10)) 21 | 22 | def draw(): 23 | background(255) 24 | global shapes 25 | 26 | for shape in shapes: 27 | shape.jiggle() 28 | shape.display() -------------------------------------------------------------------------------- /chp04_systems/simplePolymorphism/square.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # 5 | # Python port by Abhik Pal 6 | 7 | from shape import Shape 8 | 9 | class Square(Shape): 10 | # Varibales are inherited from the parent 11 | # We could also add variables unique to the Square class if we so desire 12 | 13 | # Inherits __init__() and jiggle() from the parent 14 | 15 | def display(self): 16 | """The square overrides its parent for display""" 17 | rectMode(CENTER) 18 | fill(175) 19 | stroke(0) 20 | rect(self.x, self.y, self.r, self.r) 21 | -------------------------------------------------------------------------------- /chp05_physicslibraries/CollisionsEqualMass/CollisionsEqualMass.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Collisions -- Elastic, Equal Mass, Two objects only 5 | 6 | # Based off of Chapter 9: Resolving Collisions 7 | # Mathematics and Physics for Programmers by Danny Kodicek 8 | 9 | # A Thing class for idealized collisions 10 | 11 | # ported by: Jakub Pustelnik 12 | 13 | from mover import Mover 14 | 15 | showVectors = True 16 | 17 | def setup(): 18 | global a, b 19 | size(200, 200) 20 | a = Mover(PVector(random(5), random(-5, 5)), PVector(10, 10)) 21 | b = Mover(PVector(-2, 1), PVector(150, 150)) 22 | 23 | 24 | def draw(): 25 | background(255) 26 | a.go(showVectors) 27 | b.go(showVectors) 28 | 29 | a.collideEqualMass(b) 30 | 31 | def mousePressed(): 32 | showVectors = not showVectors 33 | -------------------------------------------------------------------------------- /chp05_physicslibraries/NOC_5_1_box2d_exercise/NOC_5_1_box2d_exercise.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # ported by: Jakub Pustelnik 6 | from box import Box 7 | 8 | # A list for all of our rectangles 9 | boxes = [] 10 | 11 | def setup(): 12 | size(640, 360) 13 | 14 | def draw(): 15 | background(255) 16 | 17 | if mousePressed: 18 | p = Box(mouseX, mouseY) 19 | boxes.append(p) 20 | 21 | for b in boxes: 22 | b.display() 23 | -------------------------------------------------------------------------------- /chp05_physicslibraries/NOC_5_1_box2d_exercise/box.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # ported by: Jakub Pustelnik 6 | 7 | # A rectangular box 8 | class Box: 9 | 10 | def __init__(self, x, y): 11 | self.x = x 12 | self.y = y 13 | self.w = 16 14 | self.h = 16 15 | 16 | # Drawing the box 17 | def display(self): 18 | fill(127) 19 | stroke(9) 20 | strokeWeight(2) 21 | rectMode(CENTER) 22 | rect(self.x, self.y, self.w, self.h) 23 | -------------------------------------------------------------------------------- /chp06_agents/NOC_06_01_Seek/NOC_06_01_Seek.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # Seeking "vehicle" follows the mouse position 6 | 7 | # Implements Craig Reynold's autonomous steering behaviors 8 | # One vehicle "seeks" 9 | # See: http://www.red3d.com/cwr/ 10 | 11 | from vehicle import Vehicle 12 | 13 | def setup(): 14 | global v 15 | size(640, 360) 16 | v = Vehicle(width / 2, height / 2) 17 | 18 | 19 | def draw(): 20 | background(51) 21 | 22 | mouse = PVector(mouseX, mouseY) 23 | 24 | # Draw an ellipse at the mouse position 25 | fill(127) 26 | stroke(200) 27 | strokeWeight(2) 28 | ellipse(mouse.x, mouse.y, 48, 48) 29 | 30 | # Call the appropriate steering behaviors for our agents 31 | v.seek(mouse) 32 | v.update() 33 | v.display() 34 | -------------------------------------------------------------------------------- /chp06_agents/NOC_06_01_Seek/vehicle.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # The "Vehicle" class 6 | 7 | class Vehicle(): 8 | 9 | def __init__(self, x, y): 10 | self.acceleration = PVector(0, 0) 11 | self.velocity = PVector(0, -2) 12 | self.position = PVector(x, y) 13 | self.r = 6 14 | self.maxspeed = 8 15 | self.maxforce = 0.2 16 | 17 | # Method to update location 18 | def update(self): 19 | # Update velocity 20 | self.velocity.add(self.acceleration) 21 | # Limit speed 22 | self.velocity.limit(self.maxspeed) 23 | self.position.add(self.velocity) 24 | # Reset accelerationelertion to 0 each cycle 25 | self.acceleration.mult(0) 26 | 27 | def applyForce(self, force): 28 | # We could add mass here if we want A = F / M 29 | self.acceleration.add(force) 30 | 31 | # A method that calculates a steering force towards a target 32 | # STEER = DESIRED MINUS VELOCITY 33 | def seek(self, target): 34 | 35 | # A vector pointing from the location to the target 36 | desired = target - self.position 37 | 38 | # Scale to maximum speed 39 | desired.setMag(self.maxspeed) 40 | 41 | steer = desired - self.velocity 42 | steer.limit(self.maxforce) # Limit to maximum steering force 43 | 44 | self.applyForce(steer) 45 | 46 | def display(self): 47 | # Draw a triangle rotated in the direction of velocity 48 | theta = self.velocity.heading() + PI / 2 49 | fill(127) 50 | stroke(200) 51 | strokeWeight(1) 52 | with pushMatrix(): 53 | translate(self.position.x, self.position.y) 54 | rotate(theta) 55 | beginShape() 56 | vertex(0, -self.r * 2) 57 | vertex(-self.r, self.r * 2) 58 | vertex(self.r, self.r * 2) 59 | endShape(CLOSE) 60 | -------------------------------------------------------------------------------- /chp06_agents/NOC_06_02_Arrive/NOC_06_02_Arrive.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # Seeking "vehicle" follows the mouse position 6 | 7 | # Implements Craig Reynold's autonomous steering behaviors 8 | # One vehicle "seeks" 9 | # See: http://www.red3d.com/cwr/ 10 | 11 | from vehicle import Vehicle 12 | 13 | def setup(): 14 | global v 15 | size(640, 360) 16 | v = Vehicle(width / 2, height / 2) 17 | 18 | 19 | def draw(): 20 | background(51) 21 | 22 | mouse = PVector(mouseX, mouseY) 23 | 24 | # Draw an ellipse at the mouse position 25 | fill(127) 26 | stroke(200) 27 | strokeWeight(2) 28 | ellipse(mouse.x, mouse.y, 48, 48) 29 | 30 | # Call the appropriate steering behaviors for our agents 31 | v.arrive(mouse) 32 | v.update() 33 | v.display() 34 | -------------------------------------------------------------------------------- /chp06_agents/NOC_06_03_StayWithinWalls/NOC_06_03_StayWithinWalls.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # Stay Within Walls 6 | # "Made-up" Steering behavior to stay within walls 7 | 8 | from vehicle import Vehicle 9 | 10 | debug = True 11 | d = 25 12 | 13 | def setup(): 14 | global v 15 | size(640, 360) 16 | v = Vehicle(width / 2, height / 2) 17 | 18 | 19 | def draw(): 20 | background(255) 21 | 22 | if debug: 23 | stroke(175) 24 | noFill() 25 | rectMode(CENTER) 26 | rect(width / 2, height / 2, width - d * 2, height - d * 2) 27 | 28 | v.boundaries(d) 29 | v.run() 30 | 31 | def mousePressed(): 32 | global debug 33 | debug = not debug 34 | -------------------------------------------------------------------------------- /chp07_CA/Exercise_7_01_WolframCA_randomizedrules/Exercise_7_01_WolframCA_randomizedrules.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # Wolfram Cellular Automata 6 | 7 | # Simple demonstration of a Wolfram 1-dimensional cellular automata 8 | # When the system reaches bottom of the window, it restarts with a new ruleset 9 | # Mouse click restarts as well 10 | 11 | # import CA a class to describe a Wolfram elementary Cellular Automata 12 | from CA import CA 13 | 14 | delay = 0 15 | 16 | def setup(): 17 | global ca 18 | size(800, 200) 19 | background(255) 20 | ruleset = [0, 1, 0, 1, 1, 0, 1, 0] # An initial rule system 21 | ca = CA(ruleset) # Initialize CA 22 | frameRate(30) 23 | 24 | 25 | def draw(): 26 | global delay 27 | ca.display() # Draw the CA 28 | ca.generate() 29 | 30 | # If we're done, clear the screen, pick a new ruleset and restart 31 | if ca.finished(): 32 | delay += 1 33 | if delay > 30: 34 | background(255) 35 | ca.randomize() 36 | ca.restart() 37 | delay = 0 38 | 39 | 40 | def mousePressed(): 41 | background(255) 42 | ca.randomize() 43 | ca.restart() 44 | -------------------------------------------------------------------------------- /chp07_CA/Figure_7_17_cells/Figure_7_17_cells.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | size(1800, 90) 6 | w = 90 7 | total = width / w 8 | cells = [1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0,] 9 | 10 | print "cells = [", 11 | for i, cell in enumerate(cells): 12 | if cell == 0: 13 | fill(255) 14 | else: 15 | fill(64) 16 | stroke(0) 17 | rect(i * w, 0, w - 1, w - 1) 18 | print str(cell) + ", ", 19 | print "]", 20 | 21 | saveFrame("cells.png") 22 | -------------------------------------------------------------------------------- /chp07_CA/Figure_7_17_cells/cells.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nature-of-code/noc-examples-python/a6d823b6998304daa972a21affbf3e13444fe093/chp07_CA/Figure_7_17_cells/cells.png -------------------------------------------------------------------------------- /chp07_CA/GameOfLifeWrapAround/GameOfLifeWrapAround.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # Daniel Shiffman, Nature of Code 6 | 7 | # A basic implementation of John Conway's Game of Life CA 8 | # how could this be improved to use object oriented programming? 9 | # think of it as similar to our particle system, with a "cell" class 10 | # to describe each individual cell and a "cellular automata" class 11 | # to describe a collection of cells 12 | 13 | # Cells wrap around 14 | 15 | from GOL import GOL 16 | 17 | def setup(): 18 | global gol 19 | size(400, 400) 20 | gol = GOL() 21 | 22 | 23 | def draw(): 24 | background(255) 25 | gol.generate() 26 | gol.display() 27 | 28 | # reset board when mouse is pressed 29 | def mousePressed(): 30 | gol.init() 31 | -------------------------------------------------------------------------------- /chp07_CA/HexagonCells/GOL.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from cell import Cell 6 | 7 | class GOL(): 8 | 9 | W = 20 10 | H = sin(radians(60)) * W 11 | 12 | def __init__(self): 13 | # Initialize self.rows, self.cols and set-up a list of lists 14 | self.cols = width / int(GOL.W*3) 15 | self.rows = height / int(GOL.H) 16 | # Game of life board 17 | self.board = [[0] * self.rows for _ in range(self.cols)] 18 | # Call function to fill array with random values 0 or 1 19 | self.init() 20 | 21 | def init(self): 22 | for i in range(self.cols): 23 | for j in range(self.rows): 24 | if j % 2 == 0: 25 | self.board[i][j] = Cell(i * GOL.W * 3, 26 | j * GOL.H, 27 | GOL.W) 28 | else: 29 | self.board[i][j] = Cell(i * GOL.W * 3 + GOL.W + GOL.W / 2, 30 | j * GOL.H, 31 | GOL.W) 32 | 33 | 34 | # The easy part, draw the cells, fill 255 for '1', fill 0 for '0' 35 | def display(self): 36 | background(255) 37 | for i in range(self.cols): 38 | for j in range(self.rows): 39 | self.board[i][j].display() 40 | -------------------------------------------------------------------------------- /chp07_CA/HexagonCells/HexagonCells.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # Outline for game of life 6 | # This is just a grid of hexagons right now 7 | 8 | from GOL import GOL 9 | 10 | def setup(): 11 | global gol 12 | size(600, 600) 13 | gol = GOL() 14 | 15 | 16 | def draw(): 17 | background(255) 18 | gol.display() 19 | 20 | # reset board when mouse is pressed 21 | def mousePressed(): 22 | gol.init() 23 | -------------------------------------------------------------------------------- /chp07_CA/HexagonCells/cell.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | class Cell(): 6 | 7 | def __init__(self, x, y, w): 8 | self.x = x 9 | self.y = y 10 | self.w = w 11 | self.xoff = w / 2 12 | self.yoff = sin(radians(60)) * w 13 | self.state = int(random(2)) 14 | 15 | def display(self): 16 | 17 | fill(self.state * 255) 18 | stroke(0) 19 | with pushMatrix(): 20 | translate(self.x, self.y) 21 | with beginShape(): 22 | vertex(0, self.yoff) 23 | vertex(self.xoff, 0) 24 | vertex(self.xoff + self.w, 0) 25 | vertex(2 * self.w, self.yoff) 26 | vertex(self.xoff + self.w, 2 * self.yoff) 27 | vertex(self.xoff, 2 * self.yoff) 28 | vertex(0, self.yoff) 29 | -------------------------------------------------------------------------------- /introduction/Exercise_I_10_NoiseLandscape/Exercise_I_10_NoiseLandscape.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Landscape with height values according to Perlin noise 5 | 6 | from landscape import Landscape 7 | 8 | theta = 0.0 9 | 10 | 11 | def setup(): 12 | size(800, 200, P3D) 13 | # Create a landscape object 14 | global land 15 | land = Landscape(20, 800, 400) 16 | 17 | 18 | def draw(): 19 | global theta 20 | 21 | # Ok, visualize the landscape space 22 | background(255) 23 | pushMatrix() 24 | translate(width / 2, height / 2 + 20, -160) 25 | rotateX(PI / 3) 26 | rotateZ(theta) 27 | land.render() 28 | popMatrix() 29 | land.calculate() 30 | 31 | theta += 0.0025 32 | 33 | -------------------------------------------------------------------------------- /introduction/Exercise_I_1_WalkerTendsToDownRight/Exercise_I_1_WalkerTendsToDownRight.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | 8 | def setup(): 9 | size(640, 360) 10 | # Create a walker object 11 | global w 12 | w = Walker() 13 | background(255) 14 | 15 | 16 | def draw(): 17 | # Run the walker object 18 | w.step() 19 | w.render() 20 | 21 | -------------------------------------------------------------------------------- /introduction/Exercise_I_1_WalkerTendsToDownRight/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker object! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.x = width / 2 11 | self.y = height / 2 12 | 13 | def render(self): 14 | stroke(0) 15 | strokeWeight(2) 16 | point(self.x, self.y) 17 | 18 | # Randomly move up, down, left, right, or stay in one place 19 | def step(self): 20 | r = random(1) 21 | # A 40% of moving to the right! 22 | if r < 0.4: 23 | self.x += 1 24 | elif r < 0.5: 25 | self.x -= 1 26 | elif r < 0.9: 27 | self.y += 1 28 | else: 29 | self.y -= 1 30 | 31 | self.x = constrain(self.x, 0, width - 1) 32 | self.y = constrain(self.y, 0, height - 1) 33 | 34 | -------------------------------------------------------------------------------- /introduction/Exercise_I_9_Noise3D/Exercise_I_9_Noise3D.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | increment = 0.01 6 | 7 | # The noise function's 3rd argument, a global variable that increments 8 | # once per cycle 9 | zoff = 0.0 10 | 11 | # We will increment zoff differently than xoff and yoff 12 | zincrement = 0.02 13 | 14 | 15 | def setup(): 16 | size(200, 200) 17 | 18 | 19 | def draw(): 20 | global zoff 21 | 22 | background(0) 23 | 24 | # Optional: adjust noise detail here 25 | # noiseDetail(8,0.65f) 26 | 27 | loadPixels() 28 | xoff = 0.0 # Start xoff at 0 29 | 30 | # For every x,y coordinate in a 2D space, calculate a noise value and 31 | # produce a brightness value 32 | for x in range(width): 33 | xoff += increment # Increment xoff 34 | yoff = 0.0 # For every xoff, start yoff at 0 35 | for y in range(height): 36 | yoff += increment # Increment yoff 37 | 38 | # Calculate noise and scale by 255 39 | bright = noise(xoff, yoff, zoff) * 255 40 | # Try using this line instead 41 | #bright = random(0,255) 42 | 43 | # Set each pixel onscreen to a grayscale value 44 | pixels[x + y * width] = color(bright, bright, bright) 45 | 46 | updatePixels() 47 | 48 | zoff += zincrement # Increment zoff 49 | 50 | -------------------------------------------------------------------------------- /introduction/Figure_I_2_BellCurve/Figure_I_2_BellCurve.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | def setup(): 7 | size(400, 200) 8 | smooth() 9 | global heights 10 | heights = [0.0] * width 11 | 12 | 13 | def draw(): 14 | background(255) 15 | # "e", see http://mathforum.org/dr.math/faq/faq.e.html for more info 16 | e = 2.71828183 17 | m = 0 # default mean of 0 18 | sd = map(mouseX, 0, width, 0.4, 2) # standard deviation based on mouseX 19 | for i in range(width): 20 | xcoord = map(i, 0, width, -3, 3) 21 | sq2pi = sqrt(2 * PI) # square root of 2 * PI 22 | xmsq = -1 * (xcoord - m) * (xcoord - m) # -(x - mu)^2 23 | sdsq = sd * sd # variance (standard deviation squared) 24 | heights[i] = (1 / (sd * sq2pi)) * \ 25 | (pow(e, (xmsq / sdsq))) # P(x) function 26 | 27 | # a little for loop that draws a line between each point on the graph 28 | stroke(0) 29 | strokeWeight(2) 30 | noFill() 31 | beginShape() 32 | for x, h in enumerate(heights): 33 | vertex(x, map(h, 0, 1, height - 2, 2)) 34 | endShape() 35 | 36 | -------------------------------------------------------------------------------- /introduction/Figure_I_5_Noise1DGraph/Figure_I_5_Noise1DGraph.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | # TIME 6 | t = 0.0 7 | 8 | 9 | def setup(): 10 | size(400, 200) 11 | smooth() 12 | 13 | 14 | def draw(): 15 | global t 16 | background(255) 17 | xoff = t 18 | noFill() 19 | stroke(0) 20 | strokeWeight(2) 21 | beginShape() 22 | for i in range(width): 23 | y = noise(xoff) * height 24 | xoff += 0.01 25 | vertex(i, y) 26 | 27 | endShape() 28 | t += 0.01 29 | 30 | -------------------------------------------------------------------------------- /introduction/Figure_I_6_RandomGraph/Figure_I_6_RandomGraph.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | def setup(): 7 | size(400, 200) 8 | smooth() 9 | 10 | 11 | def draw(): 12 | background(255) 13 | noFill() 14 | stroke(0) 15 | strokeWeight(2) 16 | beginShape() 17 | for i in range(width): 18 | y = random(height) 19 | vertex(i, y) 20 | endShape() 21 | noLoop() 22 | 23 | -------------------------------------------------------------------------------- /introduction/Gaussian2/Gaussian2.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | def setup(): 7 | size(200, 200) 8 | background(0) 9 | 10 | 11 | def draw(): 12 | # create an alpha blended background 13 | fill(0, 1) 14 | rect(0, 0, width, height) 15 | # get 3 gaussian random numbers w/ mean of 0 and standard deviation of 1.0 16 | r = randomGaussian() 17 | g = randomGaussian() 18 | b = randomGaussian() 19 | # define standard deviation and mean 20 | sd = 100 21 | mean = 100 22 | # scale by standard deviation and mean 23 | # also constrain to between (0,255) since we are dealing with color 24 | r = constrain((r * sd) + mean, 0, 255) 25 | # repeat for g & b 26 | sd = 20 27 | mean = 200 28 | g = constrain((g * sd) + mean, 0, 255) 29 | sd = 50 30 | mean = 0 31 | b = constrain((b * sd) + mean, 0, 255) 32 | # get more gaussian numbers, this time for location 33 | xloc = randomGaussian() 34 | yloc = randomGaussian() 35 | sd = width / 10 36 | mean = width / 2 37 | xloc = (xloc * sd) + mean 38 | yloc = (yloc * sd) + mean 39 | # draw an ellipse with gaussian generated color and location 40 | noStroke() 41 | fill(r, g, b) 42 | ellipse(xloc, yloc, 8, 8) 43 | 44 | -------------------------------------------------------------------------------- /introduction/MonteCarloDistribution/MonteCarloDistribution.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | def setup(): 7 | size(200, 200) 8 | global vals, norms 9 | vals = [0.0] * width # Array to count how often a random # is picked 10 | norms = [0.0] * width # Normalized version of above 11 | 12 | 13 | def draw(): 14 | background(100) 15 | # Pick a random number between 0 and 1 based on custom probability function 16 | n = montecarlo() 17 | # What spot in the array did we pick 18 | index = int(n * width) 19 | vals[index] += 1 20 | stroke(255) 21 | normalization = False 22 | maxy = 0.0 23 | # Draw graph based on values in norms array 24 | # If a value is greater than the height, set normalization to True 25 | for x, val in enumerate(vals): 26 | line(x, height, x, height - norms[x]) 27 | if val > height: 28 | normalization = True 29 | if val > maxy: 30 | maxy = val 31 | 32 | # If normalization is True then normalize to height 33 | # Otherwise, just copy the info 34 | for x, val in enumerate(vals): 35 | if normalization: 36 | norms[x] = (val / maxy) * height 37 | else: 38 | norms[x] = val 39 | 40 | 41 | def montecarlo(): 42 | """ 43 | An algorithm for picking a random number based on monte carlo method 44 | Here probability is determined by formula y = x 45 | """ 46 | # let's count just so we don't get stuck in an infinite loop by accident 47 | hack = 0 48 | while hack < 10000: 49 | # Pick two random numbers 50 | r1 = random(1) 51 | r2 = random(1) 52 | y = r1 * r1 # y = x*x (change for different results) 53 | # If r2 is valid, we'll use this one 54 | if r2 < y: 55 | return r1 56 | hack += 1 57 | # Hack in case we run into a problem (need to improve this) 58 | return 0 59 | 60 | -------------------------------------------------------------------------------- /introduction/MultipleProbability/MultipleProbability.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | def setup(): 7 | size(200, 200) 8 | background(0) 9 | smooth() 10 | 11 | x, y = 0, 0 12 | 13 | 14 | def draw(): 15 | global x, y 16 | # create an alpha blended background 17 | fill(0, 1) 18 | rect(0, 0, width, height) 19 | # probabilities for 3 different cases (these need to add up to 100% since 20 | # something always occurs here!) 21 | p1 = 0.05 # 5% chance of pure white occurring 22 | p2 = 0.80 + p1 # 80% chance of gray occuring 23 | # p3 = 1.0 - p2 # 15% chance of black (we don't actually need this line since it is 24 | # by definit n, the "in all other cases" part of our else 25 | num = random(1) # pick a random number between 0 and 1 26 | if num < p1: 27 | fill(255) 28 | elif num < p2: 29 | fill(150) 30 | else: 31 | fill(0) 32 | 33 | stroke(200) 34 | rect(x, y, 10, 10) 35 | # X and Y walk through a grid 36 | x = (x + 10) % width 37 | if x == 0: 38 | y = (y + 10) % width 39 | 40 | -------------------------------------------------------------------------------- /introduction/NOC_I_1_RandomWalkTraditional/NOC_I_1_RandomWalkTraditional.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | def setup(): 8 | size(640, 360) 9 | # Create a walker object 10 | global w 11 | w = Walker() 12 | background(255) 13 | 14 | 15 | def draw(): 16 | # Run the walker object 17 | w.step() 18 | w.render() 19 | 20 | -------------------------------------------------------------------------------- /introduction/NOC_I_1_RandomWalkTraditional/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker object! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.x = width / 2 11 | self.y = height / 2 12 | 13 | def render(self): 14 | stroke(0) 15 | point(self.x, self.y) 16 | 17 | # Randomly move up, down, left, right, or stay in one place 18 | def step(self): 19 | choice = int(random(4)) 20 | 21 | if choice == 0: 22 | self.x += 1 23 | elif choice == 1: 24 | self.x -= 1 25 | elif choice == 2: 26 | self.y += 1 27 | else: 28 | self.y -= 1 29 | 30 | self.x = constrain(self.x, 0, width - 1) 31 | self.y = constrain(self.y, 0, height - 1) 32 | 33 | -------------------------------------------------------------------------------- /introduction/NOC_I_2_RandomDistribution/NOC_I_2_RandomDistribution.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # An array to keep track of how often random numbers are picked 5 | 6 | randomCounts = [0.0] * 20 7 | 8 | 9 | def setup(): 10 | size(640, 360) 11 | 12 | 13 | def draw(): 14 | background(255) 15 | 16 | # Pick a random number and increase the count 17 | index = int(random(len(randomCounts))) 18 | randomCounts[index] += 1 19 | 20 | # Draw a rectangle to graph results 21 | stroke(0) 22 | strokeWeight(2) 23 | fill(127) 24 | 25 | w = width / len(randomCounts) 26 | 27 | for x, r in enumerate(randomCounts): 28 | rect(x * w, height - r, w - 1, r) 29 | 30 | -------------------------------------------------------------------------------- /introduction/NOC_I_3_RandomWalkTendsToRight/NOC_I_3_RandomWalkTendsToRight.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | def setup(): 8 | size(640, 360) 9 | # Create a walker object 10 | global w 11 | w = Walker() 12 | background(255) 13 | 14 | 15 | def draw(): 16 | # Run the walker object 17 | w.step() 18 | w.render() 19 | 20 | -------------------------------------------------------------------------------- /introduction/NOC_I_3_RandomWalkTendsToRight/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker object! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.x = width / 2 11 | self.y = height / 2 12 | 13 | def render(self): 14 | stroke(0) 15 | strokeWeight(2) 16 | point(self.x, self.y) 17 | 18 | # Randomly move up, down, left, right, or stay in one place 19 | def step(self): 20 | 21 | r = random(1) 22 | # A 40% of moving to the right! 23 | if r < 0.4: 24 | self.x += 1 25 | elif r < 0.6: 26 | self.x -= 1 27 | elif r < 0.8: 28 | self.y += 1 29 | else: 30 | self.y -= 1 31 | 32 | self.x = constrain(self.x, 0, width - 1) 33 | self.y = constrain(self.y, 0, height - 1) 34 | 35 | -------------------------------------------------------------------------------- /introduction/NOC_I_4_Gaussian/NOC_I_4_Gaussian.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | 6 | def setup(): 7 | size(640, 360) 8 | background(255) 9 | 10 | 11 | def draw(): 12 | # Get a gaussian random number w/ mean of 0 and standard deviation of 1.0 13 | xloc = randomGaussian() 14 | sd = 60 # Define a standard deviation 15 | # Define a mean value (middle of the screen along the x-axis) 16 | mean = width / 2 17 | # Scale the gaussian random number by standard deviation and mean 18 | xloc = (xloc * sd) + mean 19 | fill(0, 10) 20 | noStroke() 21 | # Draw an ellipse at our "normal" random location 22 | ellipse(xloc, height / 2, 16, 16) 23 | 24 | -------------------------------------------------------------------------------- /introduction/NOC_I_5_NoiseWalk/NOC_I_5_NoiseWalk.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | def setup(): 8 | size(800, 200) 9 | frameRate(30) 10 | # Create a walker object 11 | global w 12 | w = Walker() 13 | 14 | 15 | def draw(): 16 | background(255) 17 | # Run the walker object 18 | w.walk() 19 | w.display() 20 | 21 | -------------------------------------------------------------------------------- /introduction/NOC_I_5_NoiseWalk/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker class! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.location = PVector(width / 2, height / 2) 11 | self.noff = PVector(random(1000), random(1000)) 12 | 13 | def display(self): 14 | strokeWeight(2) 15 | fill(127) 16 | stroke(0) 17 | ellipse(self.location.x, self.location.y, 48, 48) 18 | 19 | # Randomly move up, down, left, right, or stay in one place 20 | def walk(self): 21 | self.location.x = map(noise(self.noff.x), 0, 1, 0, width) 22 | self.location.y = map(noise(self.noff.y), 0, 1, 0, height) 23 | 24 | self.noff.add(0.01, 0.01, 0) 25 | 26 | -------------------------------------------------------------------------------- /introduction/Noise1D/Noise1D.pyde: -------------------------------------------------------------------------------- 1 | # Daniel Shiffman 2 | # The Nature of Code 3 | # http://natureofcode.com 4 | xoff = 0.0 5 | xincrement = 0.01 6 | 7 | 8 | def setup(): 9 | size(200, 200) 10 | background(0) 11 | noStroke() 12 | 13 | 14 | def draw(): 15 | # Create an alpha blended background 16 | fill(0, 10) 17 | rect(0, 0, width, height) 18 | 19 | # n = random(0,width)# Try this line instead of noise 20 | 21 | # Get a noise value based on xoff and scale it according to the window's 22 | # width 23 | global xoff 24 | n = noise(xoff) * width 25 | 26 | # With each cycle, increment xoff 27 | xoff += xincrement 28 | 29 | # Draw the ellipse at the value produced by perlin noise 30 | fill(200) 31 | ellipse(n, height / 2, 16, 16) 32 | 33 | -------------------------------------------------------------------------------- /introduction/Noise2D/Noise2D.pyde: -------------------------------------------------------------------------------- 1 | # Daniel Shiffman 2 | # The Nature of Code 3 | # http://natureofcode.com 4 | 5 | increment = 0.02 6 | 7 | 8 | def setup(): 9 | size(640, 360) 10 | noLoop() 11 | 12 | 13 | def draw(): 14 | background(0) 15 | 16 | # Optional: adjust noise detail here 17 | # noiseDetail(8,0.65) 18 | 19 | loadPixels() 20 | xoff = 0.0 # Start xoff at 0 21 | 22 | # For every x,y coordinate in a 2D space, calculate a noise value and 23 | # produce a brightness value 24 | for x in range(width): 25 | xoff += increment # Increment xoff 26 | yoff = 0.0 # For every xoff, start yoff at 0 27 | for y in range(height): 28 | yoff += increment # Increment yoff 29 | 30 | # Calculate noise and scale by 255 31 | bright = noise(xoff, yoff) * 255 32 | # Try using this line instead 33 | #bright = random(0,255) 34 | 35 | # Set each pixel onscreen to a grayscale value 36 | pixels[x + y * width] = color(bright) 37 | 38 | updatePixels() 39 | 40 | -------------------------------------------------------------------------------- /introduction/NoiseDistribution/NoiseDistribution.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # Testing Distribution of Perlin Noise generated #'s vs. Randoms 5 | 6 | xoff = 0.0 7 | 8 | 9 | def setup(): 10 | size(300, 200) 11 | global vals, norms 12 | vals = [0.0] * width 13 | norms = [0.0] * width 14 | 15 | 16 | def draw(): 17 | background(100) 18 | global xoff 19 | n = noise(xoff) 20 | index = int(n * width) 21 | vals[index] += 1 22 | xoff += 0.01 23 | stroke(255) 24 | normalization = False 25 | maxy = 0.0 26 | for x, val in enumerate(vals): 27 | line(x, height, x, height - norms[x]) 28 | if val > height: 29 | normalization = True 30 | if val > maxy: 31 | maxy = vals[x] 32 | 33 | for x, val in enumerate(vals): 34 | if normalization: 35 | norms[x] = (val / maxy) * height 36 | else: 37 | norms[x] = val 38 | 39 | -------------------------------------------------------------------------------- /introduction/NoiseWalkAcceleration/NoiseWalkAcceleration.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | 8 | def setup(): 9 | size(640, 360) 10 | # Create a walker object 11 | global w 12 | w = Walker() 13 | 14 | 15 | def draw(): 16 | background(255) 17 | # Run the walker object 18 | w.walk() 19 | w.display() 20 | 21 | -------------------------------------------------------------------------------- /introduction/NoiseWalkAcceleration/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker class! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.location = PVector(width / 2, height / 2) 11 | self.history = [] 12 | self.noff = PVector(random(1000), random(1000)) 13 | self.velocity = PVector() 14 | self.acceleration = PVector() 15 | 16 | def display(self): 17 | stroke(0) 18 | fill(175) 19 | rectMode(CENTER) 20 | rect(self.location.x, self.location.y, 16, 16) 21 | beginShape() 22 | stroke(0) 23 | noFill() 24 | for v in self.history: 25 | vertex(v.x, v.y) 26 | endShape() 27 | 28 | # Randomly move up, down, left, right, or stay in one place 29 | def walk(self): 30 | self.acceleration.x = map(noise(self.noff.x), 0, 1, -1, 1) 31 | self.acceleration.y = map(noise(self.noff.y), 0, 1, -1, 1) 32 | self.acceleration.mult(0.1) 33 | self.noff.add(0.01, 0.01, 0) 34 | self.velocity.add(self.acceleration) 35 | self.velocity.limit(1) 36 | self.location.add(self.velocity) 37 | 38 | self.history.append(self.location.get()) 39 | if len(self.history) > 1000: 40 | self.history = self.history[1:] 41 | 42 | # Stay on the screen 43 | self.location.x = constrain(self.location.x, 0, width - 1) 44 | self.location.y = constrain(self.location.y, 0, height - 1) 45 | 46 | -------------------------------------------------------------------------------- /introduction/NoiseWalkVelocity/NoiseWalkVelocity.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | from walker import Walker 5 | 6 | 7 | def setup(): 8 | size(400, 400) 9 | frameRate(30) 10 | # Create a walker object 11 | global w 12 | w = Walker() 13 | 14 | 15 | def draw(): 16 | background(255) 17 | # Run the walker object 18 | w.walk() 19 | w.display() 20 | 21 | -------------------------------------------------------------------------------- /introduction/NoiseWalkVelocity/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker class! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.location = PVector(width / 2, height / 2) 11 | self.history = [] 12 | self.noff = PVector(random(1000), random(1000)) 13 | self.velocity = PVector() 14 | 15 | def display(self): 16 | stroke(0) 17 | fill(175) 18 | rectMode(CENTER) 19 | rect(self.location.x, self.location.y, 16, 16) 20 | beginShape() 21 | stroke(0) 22 | noFill() 23 | for v in self.history: 24 | vertex(v.x, v.y) 25 | endShape() 26 | 27 | # Randomly move up, down, left, right, or stay in one place 28 | def walk(self): 29 | self.velocity.x = map(noise(self.noff.x), 0, 1, -1, 1) 30 | self.velocity.y = map(noise(self.noff.y), 0, 1, -1, 1) 31 | self.velocity.mult(5) 32 | self.noff.add(0.01, 0.01, 0) 33 | self.location.add(self.velocity) 34 | self.history.append(self.location.get()) 35 | if len(self.history) > 1000: 36 | self.history = self.history[1:] 37 | 38 | # Stay on the screen 39 | self.location.x = constrain(self.location.x, 0, width - 1) 40 | self.location.y = constrain(self.location.y, 0, height - 1) 41 | 42 | -------------------------------------------------------------------------------- /introduction/NoiseWalk_Many/NoiseWalk_Many.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | w = [] 8 | 9 | 10 | def setup(): 11 | size(600, 400) 12 | 13 | 14 | def draw(): 15 | background(255) 16 | o = int(map(mouseX, 0, width, 1, 8)) 17 | noiseDetail(o, 0.3) 18 | if frameCount % 30 == 0 and len(w) < 10: 19 | w.append(Walker()) 20 | for walker in w: 21 | walker.walk() 22 | walker.display() 23 | 24 | -------------------------------------------------------------------------------- /introduction/NoiseWalk_Many/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker class! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.location = PVector(width / 2, height / 2) 11 | self.noff = PVector(random(1000), random(1000)) 12 | 13 | def display(self): 14 | strokeWeight(2) 15 | fill(127) 16 | stroke(0) 17 | ellipse(self.location.x, self.location.y, 48, 48) 18 | 19 | # Randomly move up, down, left, right, or stay in one place 20 | def walk(self): 21 | self.location.x = map(noise(self.noff.x), 0, 1, 0, width) 22 | self.location.y = map(noise(self.noff.y), 0, 1, 0, height) 23 | self.noff.x += 0.01 24 | self.noff.y += 0.01 25 | 26 | -------------------------------------------------------------------------------- /introduction/RandomWalk/RandomWalk.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | 8 | def setup(): 9 | size(400, 400) 10 | frameRate(30) 11 | # Create a walker object 12 | global w 13 | w = Walker() 14 | 15 | 16 | def draw(): 17 | background(255) 18 | # Run the walker object 19 | w.walk() 20 | w.render() 21 | 22 | -------------------------------------------------------------------------------- /introduction/RandomWalk/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker class! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.x = width / 2 11 | self.y = height / 2 12 | 13 | def render(self): 14 | stroke(0) 15 | fill(175) 16 | rectMode(CENTER) 17 | rect(self.x, self.y, 40, 40) 18 | 19 | # Randomly move up, down, left, right, or stay in one place 20 | def walk(self): 21 | vx = random(-2, 2) 22 | vy = random(-2, 2) 23 | self.x += vx 24 | self.y += vy 25 | # Stay on the screen 26 | self.x = constrain(self.x, 0, width - 1) 27 | self.y = constrain(self.y, 0, height - 1) 28 | 29 | -------------------------------------------------------------------------------- /introduction/RandomWalkLevy/RandomWalkLevy.pyde: -------------------------------------------------------------------------------- 1 | # Daniel Shiffman 2 | # The Nature of Code 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | 8 | def setup(): 9 | size(640, 480) 10 | # Create a walker object 11 | global w 12 | w = Walker() 13 | background(0) 14 | 15 | 16 | def draw(): 17 | # Run the walker object 18 | w.step() 19 | w.render() 20 | 21 | -------------------------------------------------------------------------------- /introduction/RandomWalkLevy/walker.py: -------------------------------------------------------------------------------- 1 | # Daniel Shiffman 2 | # The Nature of Code 3 | # http://natureofcode.com 4 | # A random walker object! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.x = width / 2 11 | self.y = height / 2 12 | self.prevX = 0 13 | self.prevY = 0 14 | 15 | def render(self): 16 | stroke(255) 17 | line(self.prevX, self.prevY, self.x, self.y) 18 | 19 | # Randomly move according to floating point values 20 | def step(self): 21 | self.prevX = self.x 22 | self.prevY = self.y 23 | 24 | stepx = random(-1, 1) 25 | stepy = random(-1, 1) 26 | 27 | stepsize = montecarlo() * 50 28 | stepx *= stepsize 29 | stepy *= stepsize 30 | 31 | self.x += stepx 32 | self.y += stepy 33 | self.x = constrain(self.x, 0, width - 1) 34 | self.y = constrain(self.y, 0, height - 1) 35 | 36 | 37 | def montecarlo(): 38 | while True: 39 | r1 = random(1) 40 | probability = pow(1.0 - r1, 8) 41 | r2 = random(1) 42 | if r2 < probability: 43 | return r1 44 | 45 | -------------------------------------------------------------------------------- /introduction/RandomWalkNoise/RandomWalkNoise.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | def setup(): 8 | size(640, 360) 9 | global w 10 | w = Walker() 11 | background(0) 12 | 13 | 14 | def draw(): 15 | # Run the walker object 16 | w.step() 17 | w.render() 18 | 19 | -------------------------------------------------------------------------------- /introduction/RandomWalkNoise/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker object! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.tx = 0 11 | self.ty = 10000 12 | self.x = map(noise(self.tx), 0, 1, 0, width) 13 | self.y = map(noise(self.ty), 0, 1, 0, height) 14 | self.prevX, self.prevY = 0, 0 15 | 16 | def render(self): 17 | stroke(255) 18 | line(self.prevX, self.prevY, self.x, self.y) 19 | 20 | # Randomly move according to floating point values 21 | def step(self): 22 | self.prevX = self.x 23 | self.prevY = self.y 24 | self.x = map(noise(self.tx), 0, 1, 0, width) 25 | self.y = map(noise(self.ty), 0, 1, 0, height) 26 | self.tx += 0.01 27 | self.ty += 0.01 28 | 29 | -------------------------------------------------------------------------------- /introduction/RandomWalkPVector/RandomWalkPVector.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | def setup(): 8 | size(400, 400) 9 | frameRate(30) 10 | # Create a walker object 11 | global w 12 | w = Walker() 13 | 14 | 15 | def draw(): 16 | background(255) 17 | # Run the walker object 18 | w.walk() 19 | w.render() 20 | 21 | -------------------------------------------------------------------------------- /introduction/RandomWalkPVector/walker.py: -------------------------------------------------------------------------------- 1 | # Daniel Shiffman 2 | # The Nature of Code 3 | # http://natureofcode.com 4 | # A random walker class! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.loc = PVector(width / 2, height / 2) 11 | 12 | def render(self): 13 | stroke(0) 14 | fill(175) 15 | rectMode(CENTER) 16 | rect(self.loc.x, self.loc.y, 40, 40) 17 | 18 | # Randomly move up, down, left, right, or stay in one place 19 | def walk(self): 20 | vel = PVector(random(-2, 2), random(-2, 2)) 21 | self.loc.add(vel) 22 | 23 | # Stay on the screen 24 | self.loc.x = constrain(self.loc.x, 0, width - 1) 25 | self.loc.y = constrain(self.loc.y, 0, height - 1) 26 | 27 | -------------------------------------------------------------------------------- /introduction/RandomWalkTraditional2/RandomWalkTraditional2.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | def setup(): 8 | size(200, 200) 9 | # Create a walker object 10 | global w 11 | w = Walker() 12 | background(0) 13 | 14 | 15 | def draw(): 16 | # Run the walker object 17 | w.step() 18 | w.render() 19 | 20 | -------------------------------------------------------------------------------- /introduction/RandomWalkTraditional2/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker object! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.x = width / 2 11 | self.y = height / 2 12 | 13 | def render(self): 14 | stroke(255) 15 | point(self.x, self.y) 16 | 17 | # Randomly move to any neighboring pixel (or stay in the same spot) 18 | def step(self): 19 | stepx = int(random(3)) - 1 20 | stepy = int(random(3)) - 1 21 | self.x += stepx 22 | self.y += stepy 23 | self.x = constrain(self.x, 0, width - 1) 24 | self.y = constrain(self.y, 0, height - 1) 25 | 26 | -------------------------------------------------------------------------------- /introduction/RandomWalkTraditional3/RandomWalkTraditional3.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | 8 | def setup(): 9 | size(200, 200) 10 | # Create a walker object 11 | global w 12 | w = Walker() 13 | background(0) 14 | 15 | 16 | def draw(): 17 | # Run the walker object 18 | w.step() 19 | w.render() 20 | 21 | -------------------------------------------------------------------------------- /introduction/RandomWalkTraditional3/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker object! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.x = width / 2 11 | self.y = height / 2 12 | 13 | def render(self): 14 | stroke(255) 15 | point(self.x, self.y) 16 | 17 | # Randomly move according to floating point values 18 | def step(self): 19 | stepx = random(-1, 1) 20 | stepy = random(-1, 1) 21 | self.x += stepx 22 | self.y += stepy 23 | self.x = constrain(self.x, 0, width - 1) 24 | self.y = constrain(self.y, 0, height - 1) 25 | 26 | -------------------------------------------------------------------------------- /introduction/RandomWalkTrail/RandomWalkTrail.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | from walker import Walker 6 | 7 | 8 | def setup(): 9 | size(400, 400) 10 | frameRate(30) 11 | # Create a walker object 12 | global w 13 | w = Walker() 14 | 15 | 16 | def draw(): 17 | background(255) 18 | # Run the walker object 19 | w.walk() 20 | w.display() 21 | 22 | -------------------------------------------------------------------------------- /introduction/RandomWalkTrail/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker class! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.location = PVector(width / 2, height / 2) 11 | self.history = [] 12 | 13 | def display(self): 14 | stroke(0) 15 | fill(175) 16 | rectMode(CENTER) 17 | rect(self.location.x, self.location.y, 16, 16) 18 | beginShape() 19 | stroke(0) 20 | noFill() 21 | for v in self.history: 22 | vertex(v.x, v.y) 23 | endShape() 24 | 25 | # Randomly move up, down, left, right, or stay in one place 26 | def walk(self): 27 | vel = PVector(random(-2, 2), random(-2, 2)) 28 | self.location.add(vel) 29 | # Stay on the screen 30 | self.location.x = constrain(self.location.x, 0, width - 1) 31 | self.location.y = constrain(self.location.y, 0, height - 1) 32 | self.history.append(self.location.get()) 33 | if len(self.history) > 1000: 34 | self.history = self.history[1:] 35 | 36 | -------------------------------------------------------------------------------- /introduction/RandomWalkTrailCurve/RandomWalkTrailCurve.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | from walker import Walker 5 | 6 | 7 | def setup(): 8 | size(400, 300) 9 | # Create a walker object 10 | global w 11 | w = Walker() 12 | 13 | 14 | def draw(): 15 | background(255) 16 | # Run the walker object 17 | w.step() 18 | w.render() 19 | 20 | -------------------------------------------------------------------------------- /introduction/RandomWalkTrailCurve/walker.py: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | # A random walker object! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.position = PVector(width / 2, height / 2) 11 | self.history = [] 12 | 13 | def render(self): 14 | stroke(0) 15 | beginShape() 16 | for v in self.history: 17 | curveVertex(v.x, v.y) 18 | endShape() 19 | noFill() 20 | stroke(0) 21 | ellipse(self.position.x, self.position.y, 16, 16) 22 | 23 | # Randomly move up, down, left, right, or stay in one place 24 | def step(self): 25 | self.position.x += random(-10, 10) 26 | self.position.y += random(-10, 10) 27 | self.position.x = constrain(self.position.x, 0, width - 1) 28 | self.position.y = constrain(self.position.y, 0, height - 1) 29 | self.history.append(self.position.get()) 30 | 31 | -------------------------------------------------------------------------------- /introduction/SelfAvoidingWalk/SelfAvoidingWalk.pyde: -------------------------------------------------------------------------------- 1 | # Daniel Shiffman 2 | # The Nature of Code 3 | # http://www.shiffman.net/ 4 | from walker import Walker 5 | 6 | 7 | def setup(): 8 | size(600, 400) 9 | # Create a walker object 10 | global w 11 | w = Walker() 12 | background(255) 13 | 14 | 15 | def draw(): 16 | # Run the walker object 17 | w.step() 18 | w.render() 19 | 20 | -------------------------------------------------------------------------------- /introduction/SelfAvoidingWalk/walker.py: -------------------------------------------------------------------------------- 1 | # Daniel Shiffman 2 | # The Nature of Code 3 | # http://www.shiffman.net/ 4 | # A random walker object! 5 | 6 | 7 | class Walker(object): 8 | 9 | def __init__(self): 10 | self.x = width / 2 11 | self.y = height / 2 12 | self.grid = [] 13 | for _ in range(width): 14 | self.grid.append([False] * height) 15 | 16 | def render(self): 17 | stroke(0) 18 | line(self.x, self.y, self.x, self.y) 19 | 20 | # Randomly move up, down, left, right, or stay in one place 21 | def step(self): 22 | ok = False 23 | helpme = 0 24 | while not ok: 25 | choice = int(random(4)) 26 | saveX = self.x 27 | saveY = self.y 28 | if choice == 0: 29 | self.x += 1 30 | elif choice == 1: 31 | self.x -= 1 32 | elif choice == 2: 33 | self.y += 1 34 | else: 35 | self.y -= 1 36 | 37 | self.x = constrain(self.x, 0, width - 1) 38 | self.y = constrain(self.y, 0, height - 1) 39 | if not self.grid[self.x][self.y]: 40 | ok = True 41 | self.grid[self.x][self.y] = True 42 | else: 43 | self.x = saveX 44 | self.y = saveY 45 | 46 | helpme += 1 47 | if helpme > 1000: 48 | println("STUCK") 49 | noLoop() 50 | ok = True 51 | 52 | -------------------------------------------------------------------------------- /introduction/SimpleProbablility/SimpleProbablility.pyde: -------------------------------------------------------------------------------- 1 | # The Nature of Code 2 | # Daniel Shiffman 3 | # http://natureofcode.com 4 | 5 | x, y = 0, 0 6 | 7 | 8 | def setup(): 9 | size(200, 200) 10 | background(0) 11 | smooth() 12 | 13 | 14 | def draw(): 15 | global x, y 16 | # create an alpha blended background 17 | fill(0, 1) 18 | rect(0, 0, width, height) 19 | 20 | # calculate a probability between 0 and 100% based on mouseX location 21 | prob = mouseX / float(width) 22 | 23 | # get a random floating point value between 0 and 1 24 | r = random(1) 25 | 26 | # test the random value against the probability and trigger an event 27 | if r < prob: 28 | noStroke() 29 | fill(255) 30 | ellipse(x, y, 10, 10) 31 | 32 | # X and Y walk through a grid 33 | x = (x + 10) % width 34 | if x == 0: 35 | y = (y + 10) % width 36 | 37 | --------------------------------------------------------------------------------