removing old nature of code examples before adding new ones

This commit is contained in:
shiffman
2012-12-11 20:01:56 +00:00
parent e3aff605a8
commit 9b4891e419
541 changed files with 0 additions and 35009 deletions

View File

@@ -1,15 +0,0 @@
# The Nature of Code
![Screenshot](http://www.shiffman.net/images/noc/1.jpg) ![Screenshot](http://www.shiffman.net/images/noc/2.jpg) ![Screenshot](http://www.shiffman.net/images/noc/3.jpg) ![Screenshot](http://www.shiffman.net/images/noc/4.jpg) ![Screenshot](http://www.shiffman.net/images/noc/5.jpg) ![Screenshot](http://www.shiffman.net/images/noc/6.jpg) ![Screenshot](http://www.shiffman.net/images/noc/7.jpg) ![Screenshot](http://www.shiffman.net/images/noc/8.jpg)
# What is this?
This repository contains all of the examples for my ITP course and upcoming book "The Nature of Code." It is currently in progress and as I write the book, I will continue to add and update the examples here.
Relevant links:
[Site](http://www.natureofcode.com)
[Online tutorials](http://www.shiffman.net/teaching/nature/)
[2011 Syllabus](http://itp.nyu.edu/varwiki/Syllabus/Nature-of-Code-S11)

View File

@@ -1,63 +0,0 @@
// An animated drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
class Connection {
// Connection is from Neuron A to B
Neuron a;
Neuron b;
// Connection has a weight
float weight;
// Variables to track the animation
boolean sending = false;
PVector sender;
// Need to store the output for when its time to pass along
float output = 0;
Connection(Neuron from, Neuron to, float w) {
weight = w;
a = from;
b = to;
}
// The Connection is active
void feedforward(float val) {
output = val*weight; // Compute output
sender = a.location.get(); // Start animation at Neuron A
sending = true; // Turn on sending
}
// Update traveling sender
void update() {
if (sending) {
// Use a simple interpolation
sender.x = lerp(sender.x, b.location.x, 0.1);
sender.y = lerp(sender.y, b.location.y, 0.1);
float d = PVector.dist(sender, b.location);
// If we've reached the end
if (d < 1) {
// Pass along the output!
b.feedforward(output);
sending = false;
}
}
}
// Draw line and traveling circle
void display() {
stroke(0);
strokeWeight(1+weight*4);
line(a.location.x, a.location.y, b.location.x, b.location.y);
if (sending) {
fill(0);
strokeWeight(1);
ellipse(sender.x, sender.y, 16, 16);
}
}
}

View File

@@ -1,49 +0,0 @@
// An animated drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
Network network;
void setup() {
size(750,200);
smooth();
// Create the Network object
network = new Network(width/2, height/2);
int layers = 3;
int inputs = 2;
Neuron output = new Neuron(250, 0);
for (int i = 0; i < layers; i++) {
for (int j = 0; j < inputs; j++) {
float x = map(i, 0, layers, -300, 300);
float y = map(j, 0, inputs-1, -75, 75);
Neuron n = new Neuron(x, y);
if (i > 0) {
for (int k = 0; k < inputs; k++) {
Neuron prev = network.neurons.get(network.neurons.size()-inputs+k-j);
network.connect(prev, n, random(1));
}
}
if (i == layers-1) {
network.connect(n, output, random(1));
}
network.addNeuron(n);
}
}
network.addNeuron(output);
}
void draw() {
background(255);
// Update and display the Network
network.update();
network.display();
// Every 30 frames feed in an input
if (frameCount % 30 == 0) {
network.feedforward(random(1),random(1));
}
}

View File

@@ -1,66 +0,0 @@
// An animated drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
class Network {
// The Network has a list of neurons
ArrayList<Neuron> neurons;
// The Network now keeps a duplicate list of all Connection objects.
// This makes it easier to draw everything in this class
ArrayList<Connection> connections;
PVector location;
Network(float x, float y) {
location = new PVector(x, y);
neurons = new ArrayList<Neuron>();
connections = new ArrayList<Connection>();
}
// We can add a Neuron
void addNeuron(Neuron n) {
neurons.add(n);
}
// We can connection two Neurons
void connect(Neuron a, Neuron b, float weight) {
Connection c = new Connection(a, b, weight);
a.addConnection(c);
// Also add the Connection here
connections.add(c);
}
// Sending an input to the first Neuron
// We should do something better to track multiple inputs
void feedforward(float input1, float input2) {
Neuron n1 = neurons.get(0);
n1.feedforward(input1);
Neuron n2 = neurons.get(1);
n2.feedforward(input2);
}
// Update the animation
void update() {
for (Connection c : connections) {
c.update();
}
}
// Draw everything
void display() {
pushMatrix();
translate(location.x, location.y);
for (Neuron n : neurons) {
n.display();
}
for (Connection c : connections) {
c.display();
}
popMatrix();
}
}

View File

@@ -1,62 +0,0 @@
// An animated drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
class Neuron {
// Neuron has a location
PVector location;
// Neuron has a list of connections
ArrayList<Connection> connections;
// We now track the inputs and sum them
float sum = 0;
// The Neuron's size can be animated
float r = 32;
Neuron(float x, float y) {
location = new PVector(x, y);
connections = new ArrayList<Connection>();
}
// Add a Connection
void addConnection(Connection c) {
connections.add(c);
}
// Receive an input
void feedforward(float input) {
// Accumulate it
sum += input;
// Activate it?
if (sum > 1) {
fire();
sum = 0; // Reset the sum to 0 if it fires
}
}
// The Neuron fires
void fire() {
r = 64; // It suddenly is bigger
// We send the output through all connections
for (Connection c : connections) {
c.feedforward(sum);
}
}
// Draw it as a circle
void display() {
stroke(0);
strokeWeight(1);
// Brightness is mapped to sum
float b = map(sum,0,1,255,0);
fill(b);
ellipse(location.x, location.y, r, r);
// Size shrinks down back to original dimensions
r = lerp(r,32,0.1);
}
}

View File

@@ -1,20 +0,0 @@
class Connection {
float weight;
Neuron a;
Neuron b;
Connection(Neuron from, Neuron to,float w) {
weight = w;
a = from;
b = to;
}
void display() {
stroke(0);
strokeWeight(weight*4);
line(a.location.x, a.location.y, b.location.x, b.location.y);
}
}

View File

@@ -1,14 +0,0 @@
Network network;
void setup() {
size(640, 360);
smooth();
network = new Network(4,3,1);
}
void draw() {
background(255);
network.display();
}

View File

@@ -1,45 +0,0 @@
class Network {
ArrayList<Neuron> neurons;
PVector location;
Network(int layers, int inputs, int outputs) {
location = new PVector(width/2, height/2);
neurons = new ArrayList<Neuron>();
Neuron output = new Neuron(250, 0);
for (int i = 0; i < layers; i++) {
for (int j = 0; j < inputs; j++) {
float x = map(i, 0, layers, -200, 200);
float y = map(j, 0, inputs-1, -100, 100);
println(j + " " + y);
Neuron n = new Neuron(x, y);
if (i > 0) {
for (int k = 0; k < inputs; k++) {
Neuron prev = neurons.get(neurons.size()-inputs+k-j);
prev.connect(n);
}
}
if (i == layers-1) {
n.connect(output);
}
neurons.add(n);
}
}
neurons.add(output);
}
void display() {
pushMatrix();
translate(location.x, location.y);
for (Neuron n : neurons) {
n.display();
}
popMatrix();
}
}

View File

@@ -1,29 +0,0 @@
class Neuron {
PVector location;
ArrayList<Connection> connections;
Neuron(float x, float y) {
location = new PVector(x, y);
connections = new ArrayList<Connection>();
}
void connect(Neuron n) {
Connection c = new Connection(this, n, random(1));
connections.add(c);
}
void display() {
stroke(0);
strokeWeight(1);
fill(0);
ellipse(location.x, location.y, 16, 16);
for (Connection c : connections) {
c.display();
}
}
}

View File

@@ -1,89 +0,0 @@
// Daniel Shiffman
// The Nature of Code
// http://www.shiffman.net/teaching/nature
// Simple Perceptron Example
// See: http://en.wikipedia.org/wiki/Perceptron
// Code based on text "Artificial Intelligence", George Luger
// A list of points we will use to "train" the perceptron
Trainer[] training = new Trainer[2000];
// A Perceptron object
Perceptron ptron;
// We will train the perceptron with one "Point" object at a time
int count = 0;
// Coordinate space
float xmin = -400;
float ymin = -100;
float xmax = 400;
float ymax = 100;
// The function to describe a line
float f(float x) {
return 0.4*x+1;
}
void setup() {
size(800, 200);
// The perceptron has 3 inputs -- x, y, and bias
// Second value is "Learning Constant"
ptron = new Perceptron(3, 0.00001); // Learning Constant is low just b/c it's fun to watch, this is not necessarily optimal
// Create a random set of training points and calculate the "known" answer
for (int i = 0; i < training.length; i++) {
float x = random(xmin, xmax);
float y = random(ymin, ymax);
int answer = 1;
if (y < f(x)) answer = -1;
training[i] = new Trainer(x, y, answer);
}
smooth();
}
void draw() {
background(255);
translate(width/2,height/2);
// Draw the line
strokeWeight(4);
stroke(127);
float x1 = xmin;
float y1 = f(x1);
float x2 = xmax;
float y2 = f(x2);
line(x1,y1,x2,y2);
// Draw the line based on the current weights
// Formula is weights[0]*x + weights[1]*y + weights[2] = 0
stroke(0);
strokeWeight(1);
float[] weights = ptron.getWeights();
x1 = xmin;
y1 = (-weights[2] - weights[0]*x1)/weights[1];
x2 = xmax;
y2 = (-weights[2] - weights[0]*x2)/weights[1];
line(x1,y1,x2,y2);
// Train the Perceptron with one "training" point at a time
ptron.train(training[count].inputs, training[count].answer);
count = (count + 1) % training.length;
// Draw all the points based on what the Perceptron would "guess"
// Does not use the "known" correct answer
for (int i = 0; i < count; i++) {
stroke(0);
strokeWeight(1);
fill(0);
int guess = ptron.feedforward(training[i].inputs);
if (guess > 0) noFill();
ellipse(training[i].inputs[0], training[i].inputs[1], 8, 8);
}
}

View File

@@ -1,59 +0,0 @@
// Daniel Shiffman
// The Nature of Code
// http://www.shiffman.net/teaching/nature
// Simple Perceptron Example
// See: http://en.wikipedia.org/wiki/Perceptron
// Perceptron Class
class Perceptron {
float[] weights; // Array of weights for inputs
float c; // learning constant
// Perceptron is created with n weights and learning constant
Perceptron(int n, float c_) {
weights = new float[n];
// Start with random weights
for (int i = 0; i < weights.length; i++) {
weights[i] = random(-1,1);
}
c = c_;
}
// Function to train the Perceptron
// Weights are adjusted based on "desired" answer
void train(float[] inputs, int desired) {
// Guess the result
int guess = feedforward(inputs);
// Compute the factor for changing the weight based on the error
// Error = desired output - guessed output
// Note this can only be 0, -2, or 2
// Multiply by learning constant
float error = desired - guess;
// Adjust weights based on weightChange * input
for (int i = 0; i < weights.length; i++) {
weights[i] += c * error * inputs[i];
}
}
// Guess -1 or 1 based on input values
int feedforward(float[] inputs) {
// Sum all values
float sum = 0;
for (int i = 0; i < weights.length; i++) {
sum += inputs[i]*weights[i];
}
// Result is sign of the sum, -1 or 1
return activate(sum);
}
int activate(float sum) {
if (sum > 0) return 1;
else return -1;
}
// Return weights
float[] getWeights() {
return weights;
}
}

View File

@@ -1,23 +0,0 @@
// Daniel Shiffman
// The Nature of Code
// http://www.shiffman.net/teaching/nature
// Simple Perceptron Example
// See: http://en.wikipedia.org/wiki/Perceptron
// A class to describe a training point
// Has an x and y, a "bias" (1) and known output
// Could also add a variable for "guess" but not required here
class Trainer {
float[] inputs;
int answer;
Trainer(float x, float y, int a) {
inputs = new float[3];
inputs[0] = x;
inputs[1] = y;
inputs[2] = 1;
answer = a;
}
}

View File

@@ -1,62 +0,0 @@
// A Vehicle controlled by a Perceptron
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code, Spring 2011
Vehicle v;
PVector desired;
ArrayList<PVector> targets;
void setup() {
size(800, 200);
smooth();
// The Vehicle's desired location
desired = new PVector(width/2,height/2);
// Create a list of targets
makeTargets();
// Create the Vehicle (it has to know about the number of targets
// in order to configure its brain)
v = new Vehicle(targets.size(), random(width), random(height));
}
// Make a random ArrayList of targets to steer towards
void makeTargets() {
targets = new ArrayList<PVector>();
for (int i = 0; i < 8; i++) {
targets.add(new PVector(random(width), random(height)));
}
}
void draw() {
background(255);
// Draw a rectangle to show the Vehicle's goal
rectMode(CENTER);
stroke(0);
strokeWeight(2);
fill(0, 100);
rect(desired.x, desired.y, 36, 36);
// Draw the targets
for (PVector target : targets) {
fill(0, 100);
stroke(0);
strokeWeight(2);
ellipse(target.x, target.y, 30, 30);
}
// Update the Vehicle
v.steer(targets);
v.update();
v.display();
}
void mousePressed() {
makeTargets();
}

View File

@@ -1,44 +0,0 @@
// Daniel Shiffman
// The Nature of Code
// http://www.shiffman.net/teaching/nature
// Simple Perceptron Example
// See: http://en.wikipedia.org/wiki/Perceptron
// Perceptron Class
class Perceptron {
float[] weights; // Array of weights for inputs
float c; // learning constant
// Perceptron is created with n weights and learning constant
Perceptron(int n, float c_) {
weights = new float[n];
c = c_;
// Start with random weights
for (int i = 0; i < weights.length; i++) {
weights[i] = random(0, 1);
}
}
// Function to train the Perceptron
// Weights are adjusted based on vehicle's error
void train(PVector[] forces, PVector error) {
for (int i = 0; i < weights.length; i++) {
weights[i] += c*error.x*forces[i].x;
weights[i] += c*error.y*forces[i].y;
weights[i] = constrain(weights[i], 0, 1);
}
}
// Give me a steering result
PVector feedforward(PVector[] forces) {
// Sum all values
PVector sum = new PVector();
for (int i = 0; i < weights.length; i++) {
forces[i].mult(weights[i]);
sum.add(forces[i]);
}
return sum;
}
}

View File

@@ -1,102 +0,0 @@
// Seek
// Daniel Shiffman <http://www.shiffman.net>
// The "Vehicle" class
class Vehicle {
// Vehicle now has a brain!
Perceptron brain;
PVector location;
PVector velocity;
PVector acceleration;
float r;
float maxforce; // Maximum steering force
float maxspeed; // Maximum speed
Vehicle(int n, float x, float y) {
brain = new Perceptron(n,0.001);
acceleration = new PVector(0,0);
velocity = new PVector(0,0);
location = new PVector(x,y);
r = 3.0;
maxspeed = 4;
maxforce = 0.1;
}
// Method to update location
void update() {
// Update velocity
velocity.add(acceleration);
// Limit speed
velocity.limit(maxspeed);
location.add(velocity);
// Reset accelerationelertion to 0 each cycle
acceleration.mult(0);
location.x = constrain(location.x,0,width);
location.y = constrain(location.y,0,height);
}
void applyForce(PVector force) {
// We could add mass here if we want A = F / M
acceleration.add(force);
}
// Here is where the brain processes everything
void steer(ArrayList<PVector> targets) {
// Make an array of forces
PVector[] forces = new PVector[targets.size()];
// Steer towards all targets
for (int i = 0; i < forces.length; i++) {
forces[i] = seek(targets.get(i));
}
// That array of forces is the input to the brain
PVector result = brain.feedforward(forces);
// Use the result to steer the vehicle
applyForce(result);
// Train the brain according to the error
PVector error = PVector.sub(desired, location);
brain.train(forces,error);
}
// A method that calculates a steering force towards a target
// STEER = DESIRED MINUS VELOCITY
PVector seek(PVector target) {
PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target
// Normalize desired and scale to maximum speed
desired.normalize();
desired.mult(maxspeed);
// Steering = Desired minus velocity
PVector steer = PVector.sub(desired,velocity);
steer.limit(maxforce); // Limit to maximum steering force
return steer;
}
void display() {
// Draw a triangle rotated in the direction of velocity
float theta = velocity.heading2D() + PI/2;
fill(175);
stroke(0);
strokeWeight(1);
pushMatrix();
translate(location.x,location.y);
rotate(theta);
beginShape();
vertex(0, -r*2);
vertex(-r, r*2);
vertex(r, r*2);
endShape(CLOSE);
popMatrix();
}
}

View File

@@ -1,29 +0,0 @@
// A static drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
class Connection {
// Connection is from Neuron A to B
Neuron a;
Neuron b;
// Connection has a weight
float weight;
Connection(Neuron from, Neuron to,float w) {
weight = w;
a = from;
b = to;
}
// Drawn as a line
void display() {
stroke(0);
strokeWeight(weight*4);
line(a.location.x, a.location.y, b.location.x, b.location.y);
}
}

View File

@@ -1,39 +0,0 @@
// A static drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code, Spring 2011
Network network;
void setup() {
size(800, 200);
smooth();
// Create the Network object
network = new Network(width/2,height/2);
// Create a bunch of Neurons
Neuron a = new Neuron(-300,0);
Neuron b = new Neuron(0,75);
Neuron c = new Neuron(0,-75);
Neuron d = new Neuron(300,0);
// Connect them
network.connect(a,b);
network.connect(a,c);
network.connect(b,d);
network.connect(c,d);
// Add them to the Network
network.addNeuron(a);
network.addNeuron(b);
network.addNeuron(c);
network.addNeuron(d);
}
void draw() {
background(255);
// Draw the Network
network.display();
noLoop();
}

View File

@@ -1,37 +0,0 @@
// A static drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
class Network {
// The Network has a list of neurons
ArrayList<Neuron> neurons;
PVector location;
Network(float x, float y) {
location = new PVector(x,y);
neurons = new ArrayList<Neuron>();
}
// We can add a Neuron
void addNeuron(Neuron n) {
neurons.add(n);
}
// We can connection two Neurons
void connect(Neuron a, Neuron b) {
Connection c = new Connection(a, b, random(1));
a.addConnection(c);
}
// We can draw the network
void display() {
pushMatrix();
translate(location.x, location.y);
for (Neuron n : neurons) {
n.display();
}
popMatrix();
}
}

View File

@@ -1,36 +0,0 @@
// A static drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
class Neuron {
// Neuron has a location
PVector location;
// Neuron has a list of connections
ArrayList<Connection> connections;
Neuron(float x, float y) {
location = new PVector(x, y);
connections = new ArrayList<Connection>();
}
// Add a Connection
void addConnection(Connection c) {
connections.add(c);
}
// Draw Neuron as a circle
void display() {
stroke(0);
strokeWeight(1);
fill(0);
ellipse(location.x, location.y, 16, 16);
// Draw all its connections
for (Connection c : connections) {
c.display();
}
}
}

View File

@@ -1,63 +0,0 @@
// An animated drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
class Connection {
// Connection is from Neuron A to B
Neuron a;
Neuron b;
// Connection has a weight
float weight;
// Variables to track the animation
boolean sending = false;
PVector sender;
// Need to store the output for when its time to pass along
float output = 0;
Connection(Neuron from, Neuron to, float w) {
weight = w;
a = from;
b = to;
}
// The Connection is active
void feedforward(float val) {
output = val*weight; // Compute output
sender = a.location.get(); // Start animation at Neuron A
sending = true; // Turn on sending
}
// Update traveling sender
void update() {
if (sending) {
// Use a simple interpolation
sender.x = lerp(sender.x, b.location.x, 0.1);
sender.y = lerp(sender.y, b.location.y, 0.1);
float d = PVector.dist(sender, b.location);
// If we've reached the end
if (d < 1) {
// Pass along the output!
b.feedforward(output);
sending = false;
}
}
}
// Draw line and traveling circle
void display() {
stroke(0);
strokeWeight(1+weight*4);
line(a.location.x, a.location.y, b.location.x, b.location.y);
if (sending) {
fill(0);
strokeWeight(1);
ellipse(sender.x, sender.y, 16, 16);
}
}
}

View File

@@ -1,50 +0,0 @@
// An animated drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
Network network;
void setup() {
size(800, 200);
smooth();
// Create the Network object
network = new Network(width/2, height/2);
// Create a bunch of Neurons
Neuron a = new Neuron(-350, 0);
Neuron b = new Neuron(-200, 0);
Neuron c = new Neuron(0, 75);
Neuron d = new Neuron(0, -75);
Neuron e = new Neuron(200, 0);
Neuron f = new Neuron(350, 0);
// Connect them
network.connect(a, b,1);
network.connect(b, c,random(1));
network.connect(b, d,random(1));
network.connect(c, e,random(1));
network.connect(d, e,random(1));
network.connect(e, f,1);
// Add them to the Network
network.addNeuron(a);
network.addNeuron(b);
network.addNeuron(c);
network.addNeuron(d);
network.addNeuron(e);
network.addNeuron(f);
}
void draw() {
background(255);
// Update and display the Network
network.update();
network.display();
// Every 30 frames feed in an input
if (frameCount % 30 == 0) {
network.feedforward(random(1));
}
}

View File

@@ -1,62 +0,0 @@
// An animated drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
class Network {
// The Network has a list of neurons
ArrayList<Neuron> neurons;
// The Network now keeps a duplicate list of all Connection objects.
// This makes it easier to draw everything in this class
ArrayList<Connection> connections;
PVector location;
Network(float x, float y) {
location = new PVector(x, y);
neurons = new ArrayList<Neuron>();
connections = new ArrayList<Connection>();
}
// We can add a Neuron
void addNeuron(Neuron n) {
neurons.add(n);
}
// We can connection two Neurons
void connect(Neuron a, Neuron b, float weight) {
Connection c = new Connection(a, b, weight);
a.addConnection(c);
// Also add the Connection here
connections.add(c);
}
// Sending an input to the first Neuron
// We should do something better to track multiple inputs
void feedforward(float input) {
Neuron start = neurons.get(0);
start.feedforward(input);
}
// Update the animation
void update() {
for (Connection c : connections) {
c.update();
}
}
// Draw everything
void display() {
pushMatrix();
translate(location.x, location.y);
for (Neuron n : neurons) {
n.display();
}
for (Connection c : connections) {
c.display();
}
popMatrix();
}
}

View File

@@ -1,62 +0,0 @@
// An animated drawing of a Neural Network
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code
class Neuron {
// Neuron has a location
PVector location;
// Neuron has a list of connections
ArrayList<Connection> connections;
// We now track the inputs and sum them
float sum = 0;
// The Neuron's size can be animated
float r = 32;
Neuron(float x, float y) {
location = new PVector(x, y);
connections = new ArrayList<Connection>();
}
// Add a Connection
void addConnection(Connection c) {
connections.add(c);
}
// Receive an input
void feedforward(float input) {
// Accumulate it
sum += input;
// Activate it?
if (sum > 1) {
fire();
sum = 0; // Reset the sum to 0 if it fires
}
}
// The Neuron fires
void fire() {
r = 64; // It suddenly is bigger
// We send the output through all connections
for (Connection c : connections) {
c.feedforward(sum);
}
}
// Draw it as a circle
void display() {
stroke(0);
strokeWeight(1);
// Brightness is mapped to sum
float b = map(sum,0,1,255,0);
fill(b);
ellipse(location.x, location.y, r, r);
// Size shrinks down back to original dimensions
r = lerp(r,32,0.1);
}
}

View File

@@ -1,73 +0,0 @@
// Daniel Shiffman
// <http://www.shiffman.net>
// "Landscape" example
class Landscape {
int scl; // size of each cell
int w,h; // width and height of thingie
int rows, cols; // number of rows and columns
float zoff = 0.0; // perlin noise argument
float[][] z; // using an array to store all the height values
Landscape(int scl_, int w_, int h_) {
scl = scl_;
w = w_;
h = h_;
cols = w/scl;
rows = h/scl;
z = new float[cols][rows];
}
// Calculate height values (based off a neural netork)
void calculate(Network nn) {
float x = 0;
float dx = (float) 1.0 / cols;
for (int i = 0; i < cols; i++)
{
float y = 0;
float dy = (float) 1.0 / rows;
for (int j = 0; j < rows; j++)
{
float[] input = new float[2];
input[0] = x;
input[1] = y;
float result = nn.feedForward(input);
z[i][j] = z[i][j]*0.95 + 0.05*(float)(result*280.0f-140.0);
y += dy;
}
x += dx;
}
}
// Render landscape as grid of quads
void render() {
// Every cell is an individual quad
// (could use quad_strip here, but produces funny results, investigate this)
for (int x = 0; x < z.length-1; x++)
{
for (int y = 0; y < z[x].length-1; y++)
{
// one quad at a time
// each quad's color is determined by the height value at each vertex
// (clean this part up)
noStroke();
pushMatrix();
beginShape(QUADS);
translate(x*scl-w/2,y*scl-h/2,0);
fill(z[x][y]+127,220);
vertex(0,0,z[x][y]);
fill(z[x+1][y]+127,220);
vertex(scl,0,z[x+1][y]);
fill(z[x+1][y+1]+127,220);
vertex(scl,scl,z[x+1][y+1]);
fill(z[x][y+1]+127,220);
vertex(0,scl,z[x][y+1]);
endShape();
popMatrix();
}
}
}
}

View File

@@ -1,47 +0,0 @@
// Daniel Shiffman
// The Nature of Code, Fall 2006
// Neural Network
// Class to describe a connection between two neurons
package nn;
public class Connection {
private Neuron from; // Connection goes from. . .
private Neuron to; // To. . .
private float weight; // Weight of the connection. . .
// Constructor builds a connection with a random weight
public Connection(Neuron a_, Neuron b_) {
from = a_;
to = b_;
weight = (float) Math.random()*2-1;
}
// In case I want to set the weights manually, using this for testing
public Connection(Neuron a_, Neuron b_, float w) {
from = a_;
to = b_;
weight = w;
}
public Neuron getFrom() {
return from;
}
public Neuron getTo() {
return to;
}
public float getWeight() {
return weight;
}
// Changing the weight of the connection
public void adjustWeight(float deltaWeight) {
weight += deltaWeight;
}
}

View File

@@ -1,20 +0,0 @@
//Daniel Shiffman
//The Nature of Code, Fall 2006
//Neural Network
// Hidden Neuron Class
// So far not necessary to differentiate these
package nn;
public class HiddenNeuron extends Neuron {
public HiddenNeuron() {
super();
}
public HiddenNeuron(int i) {
super(i);
}
}

View File

@@ -1,23 +0,0 @@
//Daniel Shiffman
//The Nature of Code, Fall 2006
//Neural Network
// Input Neuron Class
// Has additional functionality to receive beginning input
package nn;
public class InputNeuron extends Neuron {
public InputNeuron() {
super();
}
public InputNeuron(int i) {
super(i);
}
public void input(float d) {
output = d;
}
}

View File

@@ -1,143 +0,0 @@
// Daniel Shiffman
// The Nature of Code, Fall 2006
// Neural Network
// Class to describe the entire network
// Arrays for input neurons, hidden neurons, and output neuron
// Need to update this so that it would work with an array out outputs
// Rather silly that I didn't do this initially
// Also need to build in a "Layer" class so that there can easily
// be more than one hidden layer
package nn;
import java.util.ArrayList;
public class Network {
// Layers
InputNeuron[] input;
HiddenNeuron[] hidden;
OutputNeuron output;
public static final float LEARNING_CONSTANT = 0.5f;
// Only One output now to start!!! (i can do better, really. . .)
// Constructor makes the entire network based on number of inputs & number of neurons in hidden layer
// Only One hidden layer!!! (fix this dood)
public Network(int inputs, int hiddentotal) {
input = new InputNeuron[inputs+1]; // Got to add a bias input
hidden = new HiddenNeuron[hiddentotal+1];
// Make input neurons
for (int i = 0; i < input.length-1; i++) {
input[i] = new InputNeuron();
}
// Make hidden neurons
for (int i = 0; i < hidden.length-1; i++) {
hidden[i] = new HiddenNeuron();
}
// Make bias neurons
input[input.length-1] = new InputNeuron(1);
hidden[hidden.length-1] = new HiddenNeuron(1);
// Make output neuron
output = new OutputNeuron();
// Connect input layer to hidden layer
for (int i = 0; i < input.length; i++) {
for (int j = 0; j < hidden.length-1; j++) {
// Create the connection object and put it in both neurons
Connection c = new Connection(input[i],hidden[j]);
input[i].addConnection(c);
hidden[j].addConnection(c);
}
}
// Connect the hidden layer to the output neuron
for (int i = 0; i < hidden.length; i++) {
Connection c = new Connection(hidden[i],output);
hidden[i].addConnection(c);
output.addConnection(c);
}
}
public float feedForward(float[] inputVals) {
// Feed the input with an array of inputs
for (int i = 0; i < inputVals.length; i++) {
input[i].input(inputVals[i]);
}
// Have the hidden layer calculate its output
for (int i = 0; i < hidden.length-1; i++) {
hidden[i].calcOutput();
}
// Calculate the output of the output neuron
output.calcOutput();
// Return output
return output.getOutput();
}
public float train(float[] inputs, float answer) {
float result = feedForward(inputs);
// This is where the error correction all starts
// Derivative of sigmoid output function * diff between known and guess
float deltaOutput = result*(1-result) * (answer-result);
// BACKPROPOGATION
// This is easier b/c we just have one output
// Apply Delta to connections between hidden and output
ArrayList connections = output.getConnections();
for (int i = 0; i < connections.size(); i++) {
Connection c = (Connection) connections.get(i);
Neuron neuron = c.getFrom();
float output = neuron.getOutput();
float deltaWeight = output*deltaOutput;
c.adjustWeight(LEARNING_CONSTANT*deltaWeight);
}
// ADJUST HIDDEN WEIGHTS
for (int i = 0; i < hidden.length; i++) {
connections = hidden[i].getConnections();
float sum = 0;
// Sum output delta * hidden layer connections (just one output)
for (int j = 0; j < connections.size(); j++) {
Connection c = (Connection) connections.get(j);
// Is this a connection from hidden layer to next layer (output)?
if (c.getFrom() == hidden[i]) {
sum += c.getWeight()*deltaOutput;
}
}
// Then adjust the weights coming in based:
// Above sum * derivative of sigmoid output function for hidden neurons
for (int j = 0; j < connections.size(); j++) {
Connection c = (Connection) connections.get(j);
// Is this a connection from previous layer (input) to hidden layer?
if (c.getTo() == hidden[i]) {
float output = hidden[i].getOutput();
float deltaHidden = output * (1 - output); // Derivative of sigmoid(x)
deltaHidden *= sum; // Would sum for all outputs if more than one output
Neuron neuron = c.getFrom();
float deltaWeight = neuron.getOutput()*deltaHidden;
c.adjustWeight(LEARNING_CONSTANT*deltaWeight);
}
}
}
return result;
}
}

View File

@@ -1,81 +0,0 @@
//Daniel Shiffman
//The Nature of Code, Fall 2006
//Neural Network
//Generic Neuron Class
//Can be a bias neuron (true or false)
package nn;
import java.util.ArrayList;
public class Neuron {
protected float output;
protected ArrayList connections;
protected boolean bias = false;
// A regular Neuron
public Neuron() {
output = 0;
// Using an arraylist to store list of connections to other neurons
connections = new ArrayList();
bias = false;
}
// Constructor for a bias neuron
public Neuron(int i) {
output = i;
connections = new ArrayList();
bias = true;
}
// Function to calculate output of this neuron
// Output is sum of all inputs*weight of connections
public void calcOutput() {
if (bias) {
// do nothing
} else {
float sum = 0;
float bias = 0;
//System.out.println("Looking through " + connections.size() + " connections");
for (int i = 0; i < connections.size(); i++) {
Connection c = (Connection) connections.get(i);
Neuron from = c.getFrom();
Neuron to = c.getTo();
// Is this connection moving forward to us
// Ignore connections that we send our output to
if (to == this) {
// This isn't really necessary
// But I am treating the bias individually in case I need to at some point
if (from.bias) {
bias = from.getOutput()*c.getWeight();
} else {
sum += from.getOutput()*c.getWeight();
}
}
}
// Output is result of sigmoid function
output = f(bias+sum);
}
}
void addConnection(Connection c) {
connections.add(c);
}
float getOutput() {
return output;
}
// Sigmoid function
public static float f(float x) {
return 1.0f / (1.0f + (float) Math.exp(-x));
}
public ArrayList getConnections() {
return connections;
}
}

View File

@@ -1,7 +0,0 @@
package nn;
public class OutputNeuron extends Neuron {
public OutputNeuron() {
super();
}
}

View File

@@ -1,114 +0,0 @@
// Daniel Shiffman
// The Nature of Code
// http://www.shiffman.net/teaching/nature
// XOR Multi-Layered Neural Network Example
// Neural network code is all in the "code" folder
import processing.opengl.*;
import nn.*;
ArrayList inputs; // List of training input values
Network nn; // Neural Network Object
int count; // Total training interations
Landscape land; // Solution space
float theta = 0.0; // Angle of rotation
PFont f; // Font
void setup() {
size(400,400,OPENGL);
// Create a landscape object
land = new Landscape(20,300,300);
f = createFont("Courier",12,true);
nn = new Network(2,4);
// Create a list of 4 training inputs
inputs = new ArrayList();
float[] input = new float[2];
input[0] = 1;
input[1] = 0;
inputs.add((float []) input.clone());
input[0] = 0;
input[1] = 1;
inputs.add((float []) input.clone());
input[0] = 1;
input[1] = 1;
inputs.add((float []) input.clone());
input[0] = 0;
input[1] = 0;
inputs.add((float []) input.clone());
}
void draw() {
int trainingIterationsPerFrame = 5;
for (int i = 0; i < trainingIterationsPerFrame; i++) {
// Pick a random training input
int pick = int(random(inputs.size()));
// Grab that input
float[] inp = (float[]) inputs.get(pick);
// Compute XOR
float known = 1;
if ((inp[0] == 1.0 && inp[1] == 1.0) || (inp[0] == 0 && inp[1] == 0)) known = 0;
// Train that sucker!
float result = nn.train(inp,known);
count++;
}
// Ok, visualize the solution space
background(175);
pushMatrix();
translate(width/2,height/2+20,-160);
rotateX(PI/3);
rotateZ(theta);
// Put a little BOX on screen
pushMatrix();
stroke(50);
noFill();
translate(-10,-10,0);
box(280);
// Draw the landscape
popMatrix();
land.calculate(nn);
land.render();
theta += 0.0025;
popMatrix();
// Display overal neural net stats
networkStatus();
}
void networkStatus() {
float mse = 0.0;
textFont(f);
fill(0);
text("Your friendly neighborhood neural network solving XOR.",10,20);
text("Total iterations: " + count,10,40);
for (int i = 0; i < inputs.size(); i++) {
float[] inp = (float[]) inputs.get(i);
float known = 1;
if ((inp[0] == 1.0 && inp[1] == 1.0) || (inp[0] == 0 && inp[1] == 0)) known = 0;
float result = nn.feedForward(inp);
//System.out.println("For: " + inp[0] + " " + inp[1] + ": " + result);
mse += (result - known)*(result - known);
}
float rmse = sqrt(mse/4.0);
DecimalFormat df = new DecimalFormat("0.000");
text("Root mean squared error: " + df.format(rmse), 10,60);
}

View File

@@ -1,55 +0,0 @@
/**
* Acceleration with Vectors
* by Daniel Shiffman.
*
* Demonstration of the basics of motion with vector.
* A "Mover" object stores location, velocity, and acceleration as vectors
* The motion is controlled by affecting the acceleration (in this case towards the mouse)
*/
class Mover {
// The Mover tracks location, velocity, and acceleration
PVector location;
PVector velocity;
PVector acceleration;
// The Mover's maximum speed
float topspeed;
Mover() {
// Start in the center
location = new PVector(width/2,height/2);
velocity = new PVector(0,0);
topspeed = 5;
}
void update() {
// Compute a vector that points from location to mouse
PVector mouse = new PVector(mouseX,mouseY);
PVector acceleration = PVector.sub(mouse,location);
// Set magnitude of acceleration
//acceleration.setMag(0.2);
acceleration.normalize();
acceleration.mult(0.2);
// Velocity changes according to acceleration
velocity.add(acceleration);
// Limit the velocity by topspeed
velocity.limit(topspeed);
// Location changes by velocity
location.add(velocity);
}
void display() {
stroke(0);
strokeWeight(2);
fill(127);
ellipse(location.x,location.y,48,48);
}
}

View File

@@ -1,27 +0,0 @@
/**
* Acceleration with Vectors
* by Daniel Shiffman.
*
* Demonstration of the basics of motion with vector.
* A "Mover" object stores location, velocity, and acceleration as vectors
* The motion is controlled by affecting the acceleration (in this case towards the mouse)
*/
// A Mover object
Mover mover;
void setup() {
size(800,200);
smooth();
mover = new Mover();
}
void draw() {
background(255);
// Update the location
mover.update();
// Display the Mover
mover.display();
}

View File

@@ -1,55 +0,0 @@
/**
* Acceleration with Vectors
* by Daniel Shiffman.
*
* Demonstration of the basics of motion with vector.
* A "Mover" object stores location, velocity, and acceleration as vectors
* The motion is controlled by affecting the acceleration (in this case towards the mouse)
*/
class Mover {
// The Mover tracks location, velocity, and acceleration
PVector location;
PVector velocity;
PVector acceleration;
// The Mover's maximum speed
float topspeed;
Mover() {
// Start in the center
location = new PVector(random(width),random(height));
velocity = new PVector(0,0);
topspeed = 5;
}
void update() {
// Compute a vector that points from location to mouse
PVector mouse = new PVector(mouseX,mouseY);
PVector acceleration = PVector.sub(mouse,location);
// Set magnitude of acceleration
//acceleration.setMag(0.2);
acceleration.normalize();
acceleration.mult(0.2);
// Velocity changes according to acceleration
velocity.add(acceleration);
// Limit the velocity by topspeed
velocity.limit(topspeed);
// Location changes by velocity
location.add(velocity);
}
void display() {
stroke(0);
strokeWeight(2);
fill(127,200);
ellipse(location.x,location.y,48,48);
}
}

View File

@@ -1,21 +0,0 @@
Mover[] movers = new Mover[20];
void setup() {
size(800,200);
smooth();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover();
}
}
void draw() {
background(255);
for (int i = 0; i < movers.length; i++) {
movers[i].update();
movers[i].display();
}
}

View File

@@ -1,38 +0,0 @@
// The Nature of Code
// Daniel Shiffman
// Draft book
// Example 1-1: Bouncing Ball, no vectors
float x = 100;
float y = 100;
float xspeed = 2.5;
float yspeed = 2;
void setup() {
size(800, 200);
smooth();
}
void draw() {
background(255);
// Add the current speed to the location.
x = x + xspeed;
y = y + yspeed;
if ((x > width) || (x < 0)) {
xspeed = xspeed * -1;
}
if ((y > height) || (y < 0)) {
yspeed = yspeed * -1;
}
// Display circle at x location
stroke(0);
strokeWeight(2);
fill(127);
ellipse(x, y, 48, 48);
}

View File

@@ -1,38 +0,0 @@
// The Nature of Code
// Daniel Shiffman
// Draft book
// Example 1-2: Bouncing Ball, with PVector!
PVector location;
PVector velocity;
void setup() {
size(200,200);
smooth();
background(255);
location = new PVector(100,100);
velocity = new PVector(2.5,5);
}
void draw() {
noStroke();
fill(255,10);
rect(0,0,width,height);
// Add the current speed to the location.
location.add(velocity);
if ((location.x > width) || (location.x < 0)) {
velocity.x = velocity.x * -1;
}
if ((location.y > height) || (location.y < 0)) {
velocity.y = velocity.y * -1;
}
// Display circle at x location
stroke(0);
fill(175);
ellipse(location.x,location.y,16,16);
}

View File

@@ -1,26 +0,0 @@
// The Nature of Code
// Daniel Shiffman
// Draft book
// Example 1-3: Vector subtraction
void setup() {
size(800,200);
smooth();
}
void draw() {
background(255);
PVector mouse = new PVector(mouseX,mouseY);
PVector center = new PVector(width/2,height/2);
mouse.sub(center);
translate(width/2,height/2);
strokeWeight(2);
stroke(0);
line(0,0,mouse.x,mouse.y);
}

View File

@@ -1,28 +0,0 @@
// The Nature of Code
// Daniel Shiffman
// Draft book
// Example 1-4: Vector multiplication
void setup() {
size(800,200);
smooth();
}
void draw() {
background(255);
PVector mouse = new PVector(mouseX,mouseY);
PVector center = new PVector(width/2,height/2);
mouse.sub(center);
// Multiplying a vector! The vector is now half its original size (multiplied by 0.5).
mouse.mult(0.5);
translate(width/2,height/2);
strokeWeight(2);
stroke(0);
line(0,0,mouse.x,mouse.y);
}

View File

@@ -1,31 +0,0 @@
// The Nature of Code
// Daniel Shiffman
// Draft book
// Example 1-5: Vector magnitude
void setup() {
size(800,200);
smooth();
}
void draw() {
background(255);
PVector mouse = new PVector(mouseX,mouseY);
PVector center = new PVector(width/2,height/2);
mouse.sub(center);
float m = mouse.mag();
fill(0);
noStroke();
rect(0,0,m,10);
translate(width/2,height/2);
stroke(0);
strokeWeight(2);
line(0,0,mouse.x,mouse.y);
}

View File

@@ -1,38 +0,0 @@
/**
* Normalize
* by Daniel Shiffman.
*
* Demonstration of normalizing a vector.
* Normalizing a vector sets its length to 1.
*/
void setup() {
size(800,200);
smooth();
}
void draw() {
background(255);
// A vector that points to the mouse location
PVector mouse = new PVector(mouseX,mouseY);
// A vector that points to the center of the window
PVector center = new PVector(width/2,height/2);
// Subtract center from mouse which results in a vector that points from center to mouse
mouse.sub(center);
// Normalize the vector
mouse.normalize();
// Multiply its length by 50
mouse.mult(150);
translate(width/2,height/2);
// Draw the resulting vector
stroke(0);
strokeWeight(2);
line(0,0,mouse.x,mouse.y);
}

View File

@@ -1,39 +0,0 @@
class Mover {
PVector location;
PVector velocity;
Mover() {
location = new PVector(random(width), random(height));
velocity = new PVector(random(-2, 2), random(-2, 2));
}
void update() {
location.add(velocity);
}
void display() {
stroke(0);
strokeWeight(2);
fill(127);
ellipse(location.x, location.y, 48, 48);
}
void checkEdges() {
if (location.x > width) {
location.x = 0;
}
else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
location.y = 0;
}
else if (location.y < 0) {
location.y = height;
}
}
}

View File

@@ -1,16 +0,0 @@
Mover mover;
void setup() {
size(800,200);
smooth();
mover = new Mover();
}
void draw() {
background(255);
mover.update();
mover.checkEdges();
mover.display();
}

View File

@@ -1,45 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float topspeed;
Mover() {
location = new PVector(width/2, height/2);
velocity = new PVector(0, 0);
acceleration = new PVector(-0.001, 0.01);
topspeed = 10;
}
void update() {
velocity.add(acceleration);
velocity.limit(topspeed);
location.add(velocity);
}
void display() {
stroke(0);
strokeWeight(2);
fill(127);
ellipse(location.x, location.y, 48, 48);
}
void checkEdges() {
if (location.x > width) {
location.x = 0;
}
else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
location.y = 0;
}
else if (location.y < 0) {
location.y = height;
}
}
}

View File

@@ -1,17 +0,0 @@
Mover mover;
void setup() {
size(800,200);
smooth();
mover = new Mover();
}
void draw() {
background(255);
mover.update();
mover.checkEdges();
mover.display();
}

View File

@@ -1,49 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float topspeed;
Mover() {
location = new PVector(width/2, height/2);
velocity = new PVector(0, 0);
topspeed = 6;
}
void update() {
acceleration = new PVector(random(-1, 1), random(-1, 1));
acceleration.normalize();
acceleration.mult(random(2));
velocity.add(acceleration);
velocity.limit(topspeed);
location.add(velocity);
}
void display() {
stroke(0);
strokeWeight(2);
fill(127);
ellipse(location.x, location.y, 48, 48);
}
void checkEdges() {
if (location.x > width) {
location.x = 0;
}
else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
location.y = 0;
}
else if (location.y < 0) {
location.y = height;
}
}
}

View File

@@ -1,15 +0,0 @@
Mover mover;
void setup() {
size(800,200);
smooth();
mover = new Mover();
}
void draw() {
background(255);
mover.update();
mover.checkEdges();
mover.display();
}

View File

@@ -1,74 +0,0 @@
// Attraction
// Daniel Shiffman <http://www.shiffman.net>
// A class for a draggable attractive body in our world
class Attractor {
float mass; // Mass, tied to size
PVector location; // Location
boolean dragging = false; // Is the object being dragged?
boolean rollover = false; // Is the mouse over the ellipse?
PVector drag; // holds the offset for when object is clicked on
Attractor() {
location = new PVector(width/2,height/2);
mass = 10;
drag = new PVector(0.0,0.0);
}
PVector attract(Mover m) {
PVector force = PVector.sub(location,m.location); // Calculate direction of force
float d = force.mag(); // Distance between objects
d = constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction)
float strength = (g * mass * m.mass) / (d * d); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
return force;
}
// Method to display
void display() {
ellipseMode(CENTER);
stroke(0);
if (dragging) fill (50);
else if (rollover) fill(100);
else fill(0);
ellipse(location.x,location.y,mass*6,mass*6);
}
// The methods below are for mouse interaction
void clicked(int mx, int my) {
float d = dist(mx,my,location.x,location.y);
if (d < mass) {
dragging = true;
drag.x = location.x-mx;
drag.y = location.y-my;
}
}
void rollover(int mx, int my) {
float d = dist(mx,my,location.x,location.y);
if (d < mass) {
rollover = true;
}
else {
rollover = false;
}
}
void stopDragging() {
dragging = false;
}
void drag() {
if (dragging) {
location.x = mouseX + drag.x;
location.y = mouseY + drag.y;
}
}
}

View File

@@ -1,69 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x , float y) {
mass = m;
location = new PVector(x,y);
velocity = new PVector(0,0);
acceleration = new PVector(0,0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
fill(175,200);
ellipse(location.x,location.y,mass*2,mass*2);
}
PVector repel(Mover m) {
PVector force = PVector.sub(location,m.location); // Calculate direction of force
float distance = force.mag(); // Distance between objects
distance = constrain(distance,1.0,10000.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction
float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude
force.mult(-1*strength); // Get force vector --> magnitude * direction
return force;
}
void checkEdges() {
if (location.x > width) {
location.x = width;
velocity.x *= -1;
}
else if (location.x < 0) {
location.x = 0;
velocity.x *= -1;
}
if (location.y > height) {
location.y = height;
velocity.y *= -1;
}
else if (location.y < 0) {
location.y = 0;
velocity.y *= -1;
}
}
}

View File

@@ -1,52 +0,0 @@
Mover[] movers = new Mover[20];
Attractor a;
float g = 1;
void setup() {
size(800,200);
smooth();
a = new Attractor();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(4,12),random(width),random(height));
}
}
void draw() {
background(255);
a.display();
for (int i = 0; i < movers.length; i++) {
for (int j = 0; j < movers.length; j++) {
if (i != j) {
PVector force = movers[j].repel(movers[i]);
movers[i].applyForce(force);
}
}
PVector force = a.attract(movers[i]);
movers[i].applyForce(force);
movers[i].update();
movers[i].display();
}
}

View File

@@ -1,39 +0,0 @@
// Attraction
// Daniel Shiffman <http://www.shiffman.net>
// A class for a draggable attractive body in our world
class Attractor {
float mass; // Mass, tied to size
PVector location; // Location
float g;
Attractor() {
location = new PVector(0,0);
mass = 20;
g = 0.4;
}
PVector attract(Mover m) {
PVector force = PVector.sub(location,m.location); // Calculate direction of force
float distance = force.mag(); // Distance between objects
distance = constrain(distance,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction)
float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
return force;
}
// Method to display
void display() {
stroke(255);
noFill();
pushMatrix();
translate(location.x,location.y,location.z);
sphere(mass*2);
popMatrix();
}
}

View File

@@ -1,51 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x, float y, float z) {
mass = m;
location = new PVector(x,y,z);
velocity = new PVector(1,0);
acceleration = new PVector(0,0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
noStroke();
fill(255);
pushMatrix();
translate(location.x,location.y,location.z);
sphere(mass*8);
popMatrix();
}
void checkEdges() {
if (location.x > width) {
location.x = 0;
}
else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
velocity.y *= -1;
location.y = height;
}
}
}

View File

@@ -1,50 +0,0 @@
import processing.opengl.*;
Mover[] movers = new Mover[10];
Attractor a;
float angle = 0;
void setup() {
size(800,200,OPENGL);
smooth();
background(255);
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.1,2),random(-width/2,width/2),random(-height/2,height/2),random(-100,100));
}
a = new Attractor();
}
void draw() {
background(0);
sphereDetail(8);
lights();
translate(width/2,height/2);
rotateY(angle);
a.display();
for (int i = 0; i < movers.length; i++) {
PVector force = a.attract(movers[i]);
movers[i].applyForce(force);
movers[i].update();
movers[i].display();
}
angle += 0.003;
}

View File

@@ -1,70 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x, float y) {
mass = m;
location = new PVector(x, y);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force, mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
fill(175, 200);
ellipse(location.x, location.y, mass*16, mass*16);
}
PVector attract(Mover m) {
PVector force = PVector.sub(location, m.location); // Calculate direction of force
float distance = force.mag(); // Distance between objects
distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction
float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
return force;
}
void boundaries() {
float d = 50;
PVector force = new PVector(0, 0);
if (location.x < d) {
force.x = 1;
}
else if (location.x > width -d) {
force.x = -1;
}
if (location.y < d) {
force.y = 1;
}
else if (location.y > height-d) {
force.y = -1;
}
force.normalize();
force.mult(0.1);
applyForce(force);
}
}

View File

@@ -1,44 +0,0 @@
Mover[] movers = new Mover[20];
float g = 0.4;
void setup() {
size(800,200);
smooth();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(1,2),random(width),random(height));
}
}
void draw() {
background(255);
for (int i = 0; i < movers.length; i++) {
for (int j = 0; j < movers.length; j++) {
if (i != j) {
PVector force = movers[j].attract(movers[i]);
movers[i].applyForce(force);
}
}
movers[i].boundaries();
movers[i].update();
movers[i].display();
}
}

View File

@@ -1,53 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover() {
location = new PVector(30,30);
velocity = new PVector(0,0);
acceleration = new PVector(0,0);
mass = 1;
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
strokeWeight(2);
fill(127);
ellipse(location.x,location.y,48,48);
}
void checkEdges() {
if (location.x > width) {
location.x = width;
velocity.x *= -1;
} else if (location.x < 0) {
velocity.x *= -1;
location.x = 0;
}
if (location.y > height) {
velocity.y *= -1;
location.y = height;
}
}
}

View File

@@ -1,27 +0,0 @@
Mover m;
void setup() {
size(800,200);
smooth();
m = new Mover();
}
void draw() {
background(255);
PVector wind = new PVector(0.01,0);
PVector gravity = new PVector(0,0.1);
m.applyForce(wind);
m.applyForce(gravity);
m.update();
m.display();
m.checkEdges();
}

View File

@@ -1,53 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x , float y) {
mass = m;
location = new PVector(x,y);
velocity = new PVector(0,0);
acceleration = new PVector(0,0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
strokeWeight(2);
fill(0,127);
ellipse(location.x,location.y,mass*16,mass*16);
}
void checkEdges() {
if (location.x > width) {
location.x = width;
velocity.x *= -1;
} else if (location.x < 0) {
velocity.x *= -1;
location.x = 0;
}
if (location.y > height) {
velocity.y *= -1;
location.y = height;
}
}
}

View File

@@ -1,36 +0,0 @@
Mover[] movers = new Mover[20];
void setup() {
size(800,200);
smooth();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.1,4),0,0);
}
}
void draw() {
background(255);
for (int i = 0; i < movers.length; i++) {
PVector wind = new PVector(0.01,0);
PVector gravity = new PVector(0,0.1);
movers[i].applyForce(wind);
movers[i].applyForce(gravity);
movers[i].update();
movers[i].display();
movers[i].checkEdges();
}
}

View File

@@ -1,53 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x , float y) {
mass = m;
location = new PVector(x,y);
velocity = new PVector(0,0);
acceleration = new PVector(0,0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
strokeWeight(2);
fill(0,127);
ellipse(location.x,location.y,mass*16,mass*16);
}
void checkEdges() {
if (location.x > width) {
location.x = width;
velocity.x *= -1;
} else if (location.x < 0) {
velocity.x *= -1;
location.x = 0;
}
if (location.y > height) {
velocity.y *= -1;
location.y = height;
}
}
}

View File

@@ -1,34 +0,0 @@
Mover[] movers = new Mover[20];
void setup() {
size(800, 200);
smooth();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(1, 4), 0, 0);
}
}
void draw() {
background(255);
for (int i = 0; i < movers.length; i++) {
PVector wind = new PVector(0.01, 0);
PVector gravity = new PVector(0, 0.1*movers[i].mass);
movers[i].applyForce(wind);
movers[i].applyForce(gravity);
movers[i].update();
movers[i].display();
movers[i].checkEdges();
}
}

View File

@@ -1,53 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x , float y) {
mass = m;
location = new PVector(x,y);
velocity = new PVector(0,0);
acceleration = new PVector(0,0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
strokeWeight(2);
fill(0,127);
ellipse(location.x,location.y,mass*16,mass*16);
}
void checkEdges() {
if (location.x > width) {
location.x = width;
velocity.x *= -1;
} else if (location.x < 0) {
location.x = 0;
velocity.x *= -1;
}
if (location.y > height) {
velocity.y *= -1;
location.y = height;
}
}
}

View File

@@ -1,42 +0,0 @@
Mover[] movers = new Mover[5];
void setup() {
size(383, 200);
randomSeed(1);
smooth();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(1, 4), random(width), 0);
}
}
void draw() {
background(255);
for (int i = 0; i < movers.length; i++) {
PVector wind = new PVector(0.01, 0);
PVector gravity = new PVector(0, 0.1*movers[i].mass);
float c = 0.05;
PVector friction = movers[i].velocity.get();
friction.mult(-1);
friction.normalize();
friction.mult(c);
movers[i].applyForce(friction);
movers[i].applyForce(wind);
movers[i].applyForce(gravity);
movers[i].update();
movers[i].display();
movers[i].checkEdges();
}
}

View File

@@ -1,53 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x , float y) {
mass = m;
location = new PVector(x,y);
velocity = new PVector(0,0);
acceleration = new PVector(0,0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
strokeWeight(2);
fill(0,127);
ellipse(location.x,location.y,mass*16,mass*16);
}
void checkEdges() {
if (location.x > width) {
location.x = width;
velocity.x *= -1;
} else if (location.x < 0) {
location.x = 0;
velocity.x *= -1;
}
if (location.y > height) {
velocity.y *= -1;
location.y = height;
}
}
}

View File

@@ -1,42 +0,0 @@
Mover[] movers = new Mover[5];
void setup() {
size(383, 200);
randomSeed(1);
smooth();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(1, 4), random(width), 0);
}
}
void draw() {
background(255);
for (int i = 0; i < movers.length; i++) {
PVector wind = new PVector(0.01, 0);
PVector gravity = new PVector(0, 0.1*movers[i].mass);
float c = 0.05;
PVector friction = movers[i].velocity.get();
friction.mult(-1);
friction.normalize();
friction.mult(c);
//movers[i].applyForce(friction);
movers[i].applyForce(wind);
movers[i].applyForce(gravity);
movers[i].update();
movers[i].display();
movers[i].checkEdges();
}
}

View File

@@ -1,62 +0,0 @@
/**
* Forces (Gravity and Fluid Resistence) with Vectors
* by Daniel Shiffman.
*
* Demonstration of multiple force acting on bodies (Mover class)
* Bodies experience gravity continuously
* Bodies experience fluid resistance when in "water"
*/
// Liquid class
class Liquid {
// Liquid is a rectangle
float x,y,w,h;
// Coefficient of drag
float c;
Liquid(float x_, float y_, float w_, float h_, float c_) {
x = x_;
y = y_;
w = w_;
h = h_;
c = c_;
}
// Is the Mover in the Liquid?
boolean contains(Mover m) {
PVector l = m.location;
if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) {
return true;
}
else {
return false;
}
}
// Calculate drag force
PVector drag(Mover m) {
// Magnitude is coefficient * speed squared
float speed = m.velocity.mag();
float dragMagnitude = c * speed * speed;
// Direction is inverse of velocity
PVector dragForce = m.velocity.get();
dragForce.mult(-1);
// Scale according to magnitude
// dragForce.setMag(dragMagnitude);
dragForce.normalize();
dragForce.mult(dragMagnitude);
return dragForce;
}
void display() {
noStroke();
fill(50);
rect(x,y,w,h);
}
}

View File

@@ -1,64 +0,0 @@
/**
* Forces (Gravity and Fluid Resistence) with Vectors
* by Daniel Shiffman.
*
* Demonstration of multiple force acting on bodies (Mover class)
* Bodies experience gravity continuously
* Bodies experience fluid resistance when in "water"
*/
class Mover {
// location, velocity, and acceleration
PVector location;
PVector velocity;
PVector acceleration;
// Mass is tied to size
float mass;
Mover(float m, float x, float y) {
mass = m;
location = new PVector(x, y);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
}
// Newton's 2nd law: F = M * A
// or A = F / M
void applyForce(PVector force) {
// Divide by mass
PVector f = PVector.div(force, mass);
// Accumulate all forces in acceleration
acceleration.add(f);
}
void update() {
// Velocity changes according to acceleration
velocity.add(acceleration);
// Location changes by velocity
location.add(velocity);
// We must clear acceleration each frame
acceleration.mult(0);
}
// Draw Mover
void display() {
stroke(0);
strokeWeight(2);
fill(127, 200);
ellipse(location.x, location.y, mass*16, mass*16);
}
// Bounce off bottom of window
void checkEdges() {
if (location.y > height) {
velocity.y *= -0.9; // A little dampening when hitting the bottom
location.y = height;
}
}
}

View File

@@ -1,72 +0,0 @@
/**
* Forces (Gravity and Fluid Resistence) with Vectors
* by Daniel Shiffman.
*
* Demonstration of multiple force acting on bodies (Mover class)
* Bodies experience gravity continuously
* Bodies experience fluid resistance when in "water"
*/
// Five moving bodies
Mover[] movers = new Mover[11];
// Liquid
Liquid liquid;
void setup() {
size(800, 200);
smooth();
reset();
// Create liquid object
liquid = new Liquid(0, height/2, width, height/2, 0.1);
}
void draw() {
background(255);
// Draw water
liquid.display();
for (int i = 0; i < movers.length; i++) {
// Is the Mover in the liquid?
if (liquid.contains(movers[i])) {
// Calculate drag force
PVector dragForce = liquid.drag(movers[i]);
// Apply drag force to Mover
movers[i].applyForce(dragForce);
}
// Gravity is scaled by mass here!
PVector gravity = new PVector(0, 0.1*movers[i].mass);
// Apply gravity
movers[i].applyForce(gravity);
// Update and display
movers[i].update();
movers[i].display();
movers[i].checkEdges();
}
fill(0);
text("click mouse to reset",10,30);
}
void mousePressed() {
reset();
}
// Restart all the Mover objects randomly
void reset() {
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.5, 3), 40+i*70, 0);
}
}

View File

@@ -1,62 +0,0 @@
/**
* Forces (Gravity and Fluid Resistence) with Vectors
* by Daniel Shiffman.
*
* Demonstration of multiple force acting on bodies (Mover class)
* Bodies experience gravity continuously
* Bodies experience fluid resistance when in "water"
*/
// Liquid class
class Liquid {
// Liquid is a rectangle
float x,y,w,h;
// Coefficient of drag
float c;
Liquid(float x_, float y_, float w_, float h_, float c_) {
x = x_;
y = y_;
w = w_;
h = h_;
c = c_;
}
// Is the Mover in the Liquid?
boolean contains(Mover m) {
PVector l = m.location;
if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) {
return true;
}
else {
return false;
}
}
// Calculate drag force
PVector drag(Mover m) {
// Magnitude is coefficient * speed squared
float speed = m.velocity.mag();
float dragMagnitude = c * speed * speed;
// Direction is inverse of velocity
PVector dragForce = m.velocity.get();
dragForce.mult(-1);
// Scale according to magnitude
// dragForce.setMag(dragMagnitude);
dragForce.normalize();
dragForce.mult(dragMagnitude);
return dragForce;
}
void display() {
noStroke();
fill(50);
rect(x,y,w,h);
}
}

View File

@@ -1,64 +0,0 @@
/**
* Forces (Gravity and Fluid Resistence) with Vectors
* by Daniel Shiffman.
*
* Demonstration of multiple force acting on bodies (Mover class)
* Bodies experience gravity continuously
* Bodies experience fluid resistance when in "water"
*/
class Mover {
// location, velocity, and acceleration
PVector location;
PVector velocity;
PVector acceleration;
// Mass is tied to size
float mass;
Mover(float m, float x, float y) {
mass = m;
location = new PVector(x, y);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
}
// Newton's 2nd law: F = M * A
// or A = F / M
void applyForce(PVector force) {
// Divide by mass
PVector f = PVector.div(force, mass);
// Accumulate all forces in acceleration
acceleration.add(f);
}
void update() {
// Velocity changes according to acceleration
velocity.add(acceleration);
// Location changes by velocity
location.add(velocity);
// We must clear acceleration each frame
acceleration.mult(0);
}
// Draw Mover
void display() {
stroke(0);
strokeWeight(2*2.25);
fill(127,200);
ellipse(location.x, location.y, mass*16, mass*16);
}
// Bounce off bottom of window
void checkEdges() {
if (location.y > height) {
velocity.y *= -0.9; // A little dampening when hitting the bottom
location.y = height;
}
}
}

View File

@@ -1,74 +0,0 @@
/**
* Forces (Gravity and Fluid Resistence) with Vectors
* by Daniel Shiffman.
*
* Demonstration of multiple force acting on bodies (Mover class)
* Bodies experience gravity continuously
* Bodies experience fluid resistance when in "water"
*/
// Five moving bodies
Mover[] movers = new Mover[5];
// Liquid
Liquid liquid;
void setup() {
size(450, 450);
smooth();
randomSeed(1);
reset();
// Create liquid object
liquid = new Liquid(0, height/2, width, height/2, 0.1);
}
void draw() {
background(255);
// Draw water
liquid.display();
for (int i = 0; i < movers.length; i++) {
// Is the Mover in the liquid?
if (liquid.contains(movers[i])) {
// Calculate drag force
PVector dragForce = liquid.drag(movers[i]);
// Apply drag force to Mover
movers[i].applyForce(dragForce);
}
// Gravity is scaled by mass here!
PVector gravity = new PVector(0, 0.1*movers[i].mass);
// Apply gravity
movers[i].applyForce(gravity);
// Update and display
movers[i].update();
movers[i].display();
movers[i].checkEdges();
}
fill(255);
//text("click mouse to reset",10,30);
if (frameCount % 20 == 0) saveFrame("ch2_05_####.png");
}
void mousePressed() {
reset();
}
// Restart all the Mover objects randomly
void reset() {
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.5*2.25,3*2.25), 20*2.25+i*40*2.25, 0);
}
}

View File

@@ -1,77 +0,0 @@
// Attraction
// Daniel Shiffman <http://www.shiffman.net>
// A class for a draggable attractive body in our world
class Attractor {
float mass; // Mass, tied to size
float G; // Gravitational Constant
PVector location; // Location
boolean dragging = false; // Is the object being dragged?
boolean rollover = false; // Is the mouse over the ellipse?
PVector dragOffset; // holds the offset for when object is clicked on
Attractor() {
location = new PVector(width/2,height/2);
mass = 20;
G = 1;
dragOffset = new PVector(0.0,0.0);
}
PVector attract(Mover m) {
PVector force = PVector.sub(location,m.location); // Calculate direction of force
float d = force.mag(); // Distance between objects
d = constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction)
float strength = (G * mass * m.mass) / (d * d); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
return force;
}
// Method to display
void display() {
ellipseMode(CENTER);
strokeWeight(4);
stroke(0);
if (dragging) fill (50);
else if (rollover) fill(100);
else fill(175,200);
ellipse(location.x,location.y,mass*2,mass*2);
}
// The methods below are for mouse interaction
void clicked(int mx, int my) {
float d = dist(mx,my,location.x,location.y);
if (d < mass) {
dragging = true;
dragOffset.x = location.x-mx;
dragOffset.y = location.y-my;
}
}
void hover(int mx, int my) {
float d = dist(mx,my,location.x,location.y);
if (d < mass) {
rollover = true;
}
else {
rollover = false;
}
}
void stopDragging() {
dragging = false;
}
void drag() {
if (dragging) {
location.x = mouseX + dragOffset.x;
location.y = mouseY + dragOffset.y;
}
}
}

View File

@@ -1,51 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover() {
location = new PVector(400,50);
velocity = new PVector(1,0);
acceleration = new PVector(0,0);
mass = 1;
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
strokeWeight(2);
fill(127);
ellipse(location.x,location.y,16,16);
}
void checkEdges() {
if (location.x > width) {
location.x = 0;
} else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
velocity.y *= -1;
location.y = height;
}
}
}

View File

@@ -1,36 +0,0 @@
Mover m;
Attractor a;
void setup() {
size(800,200);
smooth();
m = new Mover();
a = new Attractor();
}
void draw() {
background(255);
PVector force = a.attract(m);
m.applyForce(force);
m.update();
a.drag();
a.hover(mouseX,mouseY);
a.display();
m.display();
}
void mousePressed() {
a.clicked(mouseX,mouseY);
}
void mouseReleased() {
a.stopDragging();
}

View File

@@ -1,77 +0,0 @@
// Attraction
// Daniel Shiffman <http://www.shiffman.net>
// A class for a draggable attractive body in our world
class Attractor {
float mass; // Mass, tied to size
float G; // Gravitational Constant
PVector location; // Location
boolean dragging = false; // Is the object being dragged?
boolean rollover = false; // Is the mouse over the ellipse?
PVector dragOffset; // holds the offset for when object is clicked on
Attractor() {
location = new PVector(width/2,height/2);
mass = 20;
G = 1;
dragOffset = new PVector(0.0,0.0);
}
PVector attract(Mover m) {
PVector force = PVector.sub(location,m.location); // Calculate direction of force
float d = force.mag(); // Distance between objects
d = constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction)
float strength = (G * mass * m.mass) / (d * d); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
return force;
}
// Method to display
void display() {
ellipseMode(CENTER);
strokeWeight(4);
stroke(0);
if (dragging) fill (50);
else if (rollover) fill(100);
else fill(175,200);
ellipse(location.x,location.y,mass*2,mass*2);
}
// The methods below are for mouse interaction
void clicked(int mx, int my) {
float d = dist(mx,my,location.x,location.y);
if (d < mass) {
dragging = true;
dragOffset.x = location.x-mx;
dragOffset.y = location.y-my;
}
}
void hover(int mx, int my) {
float d = dist(mx,my,location.x,location.y);
if (d < mass) {
rollover = true;
}
else {
rollover = false;
}
}
void stopDragging() {
dragging = false;
}
void drag() {
if (dragging) {
location.x = mouseX + dragOffset.x;
location.y = mouseY + dragOffset.y;
}
}
}

View File

@@ -1,33 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x, float y) {
mass = m;
location = new PVector(random(width), random(height));
velocity = new PVector(1, 0);
acceleration = new PVector(0, 0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force, mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
strokeWeight(2);
fill(0,100);
ellipse(location.x, location.y, mass*25, mass*25);
}
}

View File

@@ -1,46 +0,0 @@
Mover[] movers = new Mover[10];
Attractor a;
void setup() {
size(800, 200);
smooth();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.1, 2), random(width), random(height));
}
a = new Attractor();
}
void draw() {
background(255);
a.display();
a.drag();
a.hover(mouseX, mouseY);
for (int i = 0; i < movers.length; i++) {
PVector force = a.attract(movers[i]);
movers[i].applyForce(force);
movers[i].update();
movers[i].display();
}
}
void mousePressed() {
a.clicked(mouseX, mouseY);
}
void mouseReleased() {
a.stopDragging();
}

View File

@@ -1,48 +0,0 @@
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x, float y) {
mass = m;
location = new PVector(x, y);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force, mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
void display() {
stroke(0);
strokeWeight(2);
fill(0, 100);
ellipse(location.x, location.y, mass*24, mass*24);
}
PVector attract(Mover m) {
PVector force = PVector.sub(location, m.location); // Calculate direction of force
float distance = force.mag(); // Distance between objects
distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction
float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
return force;
}
}

View File

@@ -1,42 +0,0 @@
Mover[] movers = new Mover[20];
float g = 0.4;
void setup() {
size(800,200);
smooth();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.1,2),random(width),random(height));
}
}
void draw() {
background(255);
for (int i = 0; i < movers.length; i++) {
for (int j = 0; j < movers.length; j++) {
if (i != j) {
PVector force = movers[j].attract(movers[i]);
movers[i].applyForce(force);
}
}
movers[i].update();
movers[i].display();
}
}

View File

@@ -1,70 +0,0 @@
/**
* Additive Wave
* by Daniel Shiffman.
*
* Create a more complex wave by adding two waves together.
*/
// Maybe better for this answer to be OOP???
int xspacing = 8; // How far apart should each horizontal location be spaced
int w; // Width of entire wave
int maxwaves = 5; // total # of waves to add together
float theta = 0.0;
float[] amplitude = new float[maxwaves]; // Height of wave
float[] dx = new float[maxwaves]; // Value for incrementing X, to be calculated as a function of period and xspacing
float[] yvalues; // Using an array to store height values for the wave (not entirely necessary)
void setup() {
size(640,360);
colorMode(RGB, 255, 255, 255, 100);
smooth();
w = width + 16;
for (int i = 0; i < maxwaves; i++) {
amplitude[i] = random(10,30);
float period = random(100,300); // How many pixels before the wave repeats
dx[i] = (TWO_PI / period) * xspacing;
}
yvalues = new float[w/xspacing];
}
void draw() {
background(0);
calcWave();
renderWave();
}
void calcWave() {
// Increment theta (try different values for 'angular velocity' here
theta += 0.02;
// Set all height values to zero
for (int i = 0; i < yvalues.length; i++) {
yvalues[i] = 0;
}
// Accumulate wave height values
for (int j = 0; j < maxwaves; j++) {
float x = theta;
for (int i = 0; i < yvalues.length; i++) {
// Every other wave is cosine instead of sine
if (j % 2 == 0) yvalues[i] += sin(x)*amplitude[j];
else yvalues[i] += cos(x)*amplitude[j];
x+=dx[j];
}
}
}
void renderWave() {
// A simple way to draw the wave with an ellipse at each location
noStroke();
fill(255,50);
ellipseMode(CENTER);
for (int x = 0; x < yvalues.length; x++) {
ellipse(x*xspacing,height/2+yvalues[x],16,16);
}
}

View File

@@ -1,46 +0,0 @@
// Attraction Array with Oscillating objects around each Crawler
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code, Spring 2012
// Click and drag attractive body to move throughout space
Crawler[] crawlers = new Crawler[6];
Attractor a;
void setup() {
size(640,360);
smooth();
// Some random bodies
for (int i = 0; i < crawlers.length; i++) {
crawlers[i] = new Crawler();
}
// Create an attractive body
a = new Attractor(new PVector(width/2,height/2),20,0.4);
}
void draw() {
background(255);
a.rollover(mouseX,mouseY);
a.go();
for (int i = 0; i < crawlers.length; i++) {
// Calculate a force exerted by "attractor" on "Crawler"
PVector f = a.attract(crawlers[i]);
// Apply that force to the Crawler
crawlers[i].applyForce(f);
// Update and render
crawlers[i].update();
crawlers[i].display();
}
}
void mousePressed() {
a.clicked(mouseX,mouseY);
}
void mouseReleased() {
a.stopDragging();
}

View File

@@ -1,81 +0,0 @@
// Attraction
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code, Spring 2009
// A class for a draggable attractive body in our world
class Attractor {
float mass; // Mass, tied to size
float G; // Gravitational Constant
PVector loc; // Location
boolean dragging = false; // Is the object being dragged?
boolean rollover = false; // Is the mouse over the ellipse?
PVector drag; // holds the offset for when object is clicked on
Attractor(PVector l_,float m_, float g_) {
loc = l_.get();
mass = m_;
G = g_;
drag = new PVector(0.0,0.0);
}
void go() {
render();
drag();
}
PVector attract(Crawler c) {
PVector dir = PVector.sub(loc,c.loc); // Calculate direction of force
float d = dir.mag(); // Distance between objects
d = constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
dir.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction)
float force = (G * mass * c.mass) / (d * d); // Calculate gravitional force magnitude
dir.mult(force); // Get force vector --> magnitude * direction
return dir;
}
// Method to display
void render() {
ellipseMode(CENTER);
stroke(0,100);
if (dragging) fill (50);
else if (rollover) fill(100);
else fill(175,50);
ellipse(loc.x,loc.y,mass*2,mass*2);
}
// The methods below are for mouse interaction
void clicked(int mx, int my) {
float d = dist(mx,my,loc.x,loc.y);
if (d < mass) {
dragging = true;
drag.x = loc.x-mx;
drag.y = loc.y-my;
}
}
void rollover(int mx, int my) {
float d = dist(mx,my,loc.x,loc.y);
if (d < mass) {
rollover = true;
} else {
rollover = false;
}
}
void stopDragging() {
dragging = false;
}
void drag() {
if (dragging) {
loc.x = mouseX + drag.x;
loc.y = mouseY + drag.y;
}
}
}

View File

@@ -1,56 +0,0 @@
// Attraction
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code, Spring 2012
// A class to describe a thing in our world, has vectors for location, velocity, and acceleration
// Also includes scalar values for mass, maximum velocity, and elasticity
class Crawler {
PVector loc;
PVector vel;
PVector acc;
float mass;
Oscillator osc;
Crawler() {
acc = new PVector();
vel = new PVector(random(-1,1),random(-1,1));
loc = new PVector(random(width),random(height));
mass = random(8,16);
osc = new Oscillator(mass*2);
}
void applyForce(PVector force) {
PVector f = force.get();
f.div(mass);
acc.add(f);
}
// Method to update location
void update() {
vel.add(acc);
loc.add(vel);
// Multiplying by 0 sets the all the components to 0
acc.mult(0);
osc.update(vel.mag()/10);
}
// Method to display
void display() {
float angle = vel.heading2D();
pushMatrix();
translate(loc.x,loc.y);
rotate(angle);
ellipseMode(CENTER);
stroke(0);
fill(175,100);
ellipse(0,0,mass*2,mass*2);
osc.display(loc);
popMatrix();
}
}

View File

@@ -1,35 +0,0 @@
// Attraction Array with Oscillating objects around each thing
// Daniel Shiffman <http://www.shiffman.net>
// Nature of Code, Spring 2009
class Oscillator {
// Because we are going to oscillate along the x and y axis we can use PVector for two angles, amplitudes, etc.!
float theta;
float amplitude;
Oscillator(float r) {
// Initialize randomly
theta = 0;
amplitude = r;
}
// Update theta and offset
void update(float thetaVel) {
theta += thetaVel;
}
// Display based on a location
void display(PVector loc) {
float x = map(cos(theta),-1,1,0,amplitude);
stroke(0);
fill(50);
line(0,0,x,0);
ellipse(x,0,8,8);
}
}

View File

@@ -1,24 +0,0 @@
float angle = 0;
void setup() {
size(750, 150);
smooth();
}
void draw() {
background(255);
fill(127);
stroke(0);
rectMode(CENTER);
translate(width/2, height/2);
rotate(angle);
line(-50, 0, 50, 0);
stroke(0);
strokeWeight(2);
fill(127);
ellipse(50, 0, 16, 16);
ellipse(-50, 0, 16, 16);
angle += 0.05;
}

View File

@@ -1,30 +0,0 @@
// Nature of Code
// Daniel Shiffman
// http://www.learningprocessing.com
// A Polar coordinate, radius now starts at 0 to spiral outwards
float r = 0;
float theta = 0;
void setup() {
size(750,200);
background(255);
smooth();
}
void draw() {
// Polar to Cartesian conversion
float x = r * cos(theta);
float y = r * sin(theta);
// Draw an ellipse at x,y
noStroke();
fill(0);
// Adjust for center of window
ellipse(x+width/2, y+height/2, 16, 16);
// Increment the angle
theta += 0.01;
// Increment the radius
r += 0.05;
}

View File

@@ -1,41 +0,0 @@
// Nature of Code 2011
// Daniel Shiffman
// Chapter 3: Asteroids exercise
// http://www.shiffman.net
// Mover object
Spaceship ship;
void setup() {
size(750, 200);
smooth();
ship = new Spaceship();
}
void draw() {
background(255);
// Update location
ship.update();
// Wrape edges
ship.wrapEdges();
// Draw ship
ship.display();
fill(0);
text("left right arrows to turn, z to thrust",10,height-5);
// Turn or thrust the ship depending on what key is pressed
if (keyPressed) {
if (key == CODED && keyCode == LEFT) {
ship.turn(-0.03);
} else if (key == CODED && keyCode == RIGHT) {
ship.turn(0.03);
} else if (key == 'z' || key == 'Z') {
ship.thrust();
}
}
}

View File

@@ -1,97 +0,0 @@
// Nature of Code 2011
// Daniel Shiffman
// Chapter 3: Asteroids
class Spaceship {
// All of our regular motion stuff
PVector location;
PVector velocity;
PVector acceleration;
// Arbitrary damping to slow down ship
float damping = 0.995;
float topspeed = 6;
// Variable for heading!
float heading = 0;
// Size
float r = 16;
// Are we thrusting (to color boosters)
boolean thrusting = false;
Spaceship() {
location = new PVector(width/2,height/2);
velocity = new PVector();
acceleration = new PVector();
}
// Standard Euler integration
void update() {
velocity.add(acceleration);
velocity.mult(damping);
velocity.limit(topspeed);
location.add(velocity);
acceleration.mult(0);
}
// Newton's law: F = M * A
void applyForce(PVector force) {
PVector f = force.get();
//f.div(mass); // ignoring mass right now
acceleration.add(f);
}
// Turn changes angle
void turn(float a) {
heading += a;
}
// Apply a thrust force
void thrust() {
// Offset the angle since we drew the ship vertically
float angle = heading - PI/2;
// Polar to cartesian for force vector!
PVector force = new PVector(cos(angle),sin(angle));
force.mult(0.1);
applyForce(force);
// To draw booster
thrusting = true;
}
void wrapEdges() {
float buffer = r*2;
if (location.x > width + buffer) location.x = -buffer;
else if (location.x < -buffer) location.x = width+buffer;
if (location.y > height + buffer) location.y = -buffer;
else if (location.y < -buffer) location.y = height+buffer;
}
// Draw the ship
void display() {
stroke(0);
strokeWeight(2);
pushMatrix();
translate(location.x,location.y+r);
rotate(heading);
fill(175);
if (thrusting) fill(255,0,0);
// Booster rockets
rect(-r/2,r,r/3,r/2);
rect(r/2,r,r/3,r/2);
fill(175);
// A triangle
beginShape();
vertex(-r,r);
vertex(0,-r);
vertex(r,r);
endShape(CLOSE);
rectMode(CENTER);
popMatrix();
thrusting = false;
}
}

View File

@@ -1,31 +0,0 @@
// Sine Wave
// Daniel Shiffman <http://www.shiffman.net>
// Two wave objects
Wave wave0;
Wave wave1;
void setup() {
size(750,200);
smooth();
// Initialize a wave with starting point, width, amplitude, and period
wave0 = new Wave(new PVector(50,75),100,20,500);
wave1 = new Wave(new PVector(300,100),300,40,220);
}
void draw() {
background(255);
// Update and display waves
wave0.calculate();
wave0.display();
wave1.calculate();
wave1.display();
}

View File

@@ -1,45 +0,0 @@
class Wave {
int xspacing = 8; // How far apart should each horizontal location be spaced
int w; // Width of entire wave
PVector origin; // Where does the wave's first point start
float theta = 0.0; // Start angle at 0
float amplitude; // Height of wave
float period; // How many pixels before the wave repeats
float dx; // Value for incrementing X, to be calculated as a function of period and xspacing
float[] yvalues; // Using an array to store height values for the wave (not entirely necessary)
Wave(PVector o, int w_, float a, float p) {
origin = o.get();
w = w_;
period = p;
amplitude = a;
dx = (TWO_PI / period) * xspacing;
yvalues = new float[w/xspacing];
}
void calculate() {
// Increment theta (try different values for 'angular velocity' here
theta += 0.02;
// For every x value, calculate a y value with sine function
float x = theta;
for (int i = 0; i < yvalues.length; i++) {
yvalues[i] = sin(x)*amplitude;
x+=dx;
}
}
void display() {
// A simple way to draw the wave with an ellipse at each location
for (int x = 0; x < yvalues.length; x++) {
stroke(0);
fill(0,50);
ellipseMode(CENTER);
ellipse(origin.x+x*xspacing,origin.y+yvalues[x],48,48);
}
}
}

Some files were not shown because too many files have changed in this diff Show More