mirror of
https://github.com/processing/processing4.git
synced 2026-01-29 11:21:06 +01:00
removing old nature of code examples before adding new ones
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
# The Nature of Code
|
||||
|
||||
       
|
||||
|
||||
# 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)
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
Network network;
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
smooth();
|
||||
network = new Network(4,3,1);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
network.display();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
mode=Standard
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
mode=Standard
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
mode=Standard
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package nn;
|
||||
|
||||
public class OutputNeuron extends Neuron {
|
||||
public OutputNeuron() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
mode=Standard
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
mode=JavaScript
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
mode=Standard
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
mode=Standard
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
mode=JavaScript
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
mode=JavaScript
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user