kopia lustrzana https://github.com/villares/sketch-a-day
main
rodzic
160cc71764
commit
7f220d7e2e
|
|
@ -0,0 +1,18 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<!-- PLEASE NO CHANGES BELOW THIS LINE (UNTIL I SAY SO) -->
|
||||||
|
<script language="javascript" type="text/javascript" src="libraries/p5.min.js"></script>
|
||||||
|
<script language="javascript" type="text/javascript" src="sketch_2020_07_17a.js"></script>
|
||||||
|
<!-- OK, YOU CAN MAKE CHANGES BELOW THIS LINE AGAIN -->
|
||||||
|
|
||||||
|
<!-- This line removes any default padding and style.
|
||||||
|
You might only need one of these values set. -->
|
||||||
|
<style> body { padding: 0; margin: 0; } </style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,136 @@
|
||||||
|
// adapted from Khan Academy that adapts Dan Shiffman, natureofcode.com
|
||||||
|
// https://pt.khanacademy.org/computing/computer-programming/programming-natural-simulations/programming-particle-systems/a/particle-systems-with-forces
|
||||||
|
|
||||||
|
var gravity;
|
||||||
|
var particleSystem;
|
||||||
|
var repeller;
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
createCanvas(400, 400);
|
||||||
|
gravity = createVector(0, 0.2);
|
||||||
|
particleSystem = new ParticleSystem(createVector(width / 2, 50));
|
||||||
|
repeller = new Repeller(width / 2, 280);
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
background(214, 255, 171);
|
||||||
|
particleSystem.applyGravity();
|
||||||
|
particleSystem.applyRepeller(repeller);
|
||||||
|
repeller.display();
|
||||||
|
particleSystem.addParticle();
|
||||||
|
particleSystem.run();
|
||||||
|
fill(0);
|
||||||
|
text(particleSystem.particles.length, 20, 380);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var Repeller = function(x, y) {
|
||||||
|
this.power = 398;
|
||||||
|
this.position = createVector(x, y);
|
||||||
|
};
|
||||||
|
|
||||||
|
Repeller.prototype.display = function() {
|
||||||
|
stroke(255);
|
||||||
|
strokeWeight(2);
|
||||||
|
fill(127);
|
||||||
|
ellipse(this.position.x, this.position.y, 32, 32);
|
||||||
|
};
|
||||||
|
|
||||||
|
Repeller.prototype.calculateRepelForce = function(p) {
|
||||||
|
// Calculate direction of force
|
||||||
|
var dir = p5.Vector.sub(this.position, p.position);
|
||||||
|
// Distance between objects
|
||||||
|
var d = dir.mag();
|
||||||
|
// Normalize direction vector
|
||||||
|
dir.normalize();
|
||||||
|
// Keep distance within a reasonable range
|
||||||
|
d = constrain(d, 1, 100);
|
||||||
|
// Repelling force is inversely proportional to distance
|
||||||
|
var force = -1 * this.power / (d * d);
|
||||||
|
// Get force vector --> magnitude * direction
|
||||||
|
dir.mult(force);
|
||||||
|
return dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Particle = function(position) {
|
||||||
|
this.acceleration = createVector(0, 0);
|
||||||
|
this.velocity = createVector(random(-1, 1) / 5, 0);
|
||||||
|
this.position = position.copy();
|
||||||
|
this.timeToLive = 255.0;
|
||||||
|
this.mass = random(5, 20);
|
||||||
|
};
|
||||||
|
|
||||||
|
Particle.prototype.run = function() {
|
||||||
|
this.update();
|
||||||
|
this.display();
|
||||||
|
};
|
||||||
|
|
||||||
|
Particle.prototype.applyForce = function(force) {
|
||||||
|
var f = force.copy();
|
||||||
|
f.div(this.mass);
|
||||||
|
this.acceleration.add(f);
|
||||||
|
};
|
||||||
|
|
||||||
|
Particle.prototype.update = function() {
|
||||||
|
this.velocity.add(this.acceleration);
|
||||||
|
this.position.add(this.velocity);
|
||||||
|
this.acceleration.mult(0);
|
||||||
|
this.timeToLive -= 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Particle.prototype.display = function() {
|
||||||
|
stroke(0, 0, 0, this.timeToLive);
|
||||||
|
strokeWeight(2);
|
||||||
|
fill(255, 0, 0, this.timeToLive);
|
||||||
|
ellipse(this.position.x, this.position.y, this.mass, this.mass);
|
||||||
|
};
|
||||||
|
|
||||||
|
Particle.prototype.isDead = function() {
|
||||||
|
if (this.timeToLive < 0.0 || this.position.y > 410) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var ParticleSystem = function(position) {
|
||||||
|
this.origin = position.copy();
|
||||||
|
this.particles = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
ParticleSystem.prototype.addParticle = function() {
|
||||||
|
this.particles.push(new Particle(this.origin));
|
||||||
|
};
|
||||||
|
|
||||||
|
ParticleSystem.prototype.applyForce = function(f) {
|
||||||
|
for (var i = 0; i < this.particles.length; i++) {
|
||||||
|
this.particles[i].applyForce(f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ParticleSystem.prototype.applyGravity = function() {
|
||||||
|
for (var i = 0; i < this.particles.length; i++) {
|
||||||
|
var particleG = gravity.copy();
|
||||||
|
particleG.mult(this.particles[i].mass);
|
||||||
|
this.particles[i].applyForce(particleG);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ParticleSystem.prototype.applyRepeller = function(r) {
|
||||||
|
for (var i = 0; i < this.particles.length; i++) {
|
||||||
|
var p = this.particles[i];
|
||||||
|
var force = r.calculateRepelForce(p);
|
||||||
|
p.applyForce(force);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ParticleSystem.prototype.run = function() {
|
||||||
|
for (var i = this.particles.length - 1; i >= 0; i--) {
|
||||||
|
var p = this.particles[i];
|
||||||
|
p.run();
|
||||||
|
if (p.isDead()) {
|
||||||
|
this.particles.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
# adapted from Khan Academy that adapts Dan Shiffman, natureofcode.com
|
||||||
|
# https://pt.khanacademy.org/computing/computer-programming/programming-natural-simulations/programming-particle-systems/a/particle-systems-with-forces
|
||||||
|
# now ported to Processing Python mode
|
||||||
|
|
||||||
|
def setup():
|
||||||
|
global gravity, particleSystem, repeller
|
||||||
|
size(400, 400)
|
||||||
|
gravity = PVector(0, 0.2)
|
||||||
|
particleSystem = ParticleSystem(PVector(width / 2, 50))
|
||||||
|
repeller = Repeller(width / 2, 280)
|
||||||
|
|
||||||
|
|
||||||
|
def draw():
|
||||||
|
background(214, 255, 171)
|
||||||
|
particleSystem.applyGravity()
|
||||||
|
particleSystem.applyRepeller(repeller)
|
||||||
|
repeller.display()
|
||||||
|
particleSystem.addParticle()
|
||||||
|
particleSystem.run()
|
||||||
|
fill(0)
|
||||||
|
# text(len(particleSystem.particles), 20, 380)
|
||||||
|
text(frameRate, 20, 380)
|
||||||
|
|
||||||
|
|
||||||
|
class Repeller:
|
||||||
|
|
||||||
|
def __init__(self, x, y):
|
||||||
|
self.power = 398.0
|
||||||
|
self.position = PVector(x, y)
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
stroke(255)
|
||||||
|
strokeWeight(2)
|
||||||
|
fill(127)
|
||||||
|
ellipse(self.position.x, self.position.y, 32, 32)
|
||||||
|
|
||||||
|
def calculateRepelForce(self, p):
|
||||||
|
# Calculate direction of force
|
||||||
|
dir = self.position - p.position
|
||||||
|
# Distance between objects
|
||||||
|
d = dir.mag()
|
||||||
|
# Normalize direction vector
|
||||||
|
dir.normalize()
|
||||||
|
# Keep distance within a reasonable range
|
||||||
|
d = constrain(d, 1, 100)
|
||||||
|
# Repelling force is inversely proportional to distance
|
||||||
|
force = -1 * self.power / (d * d)
|
||||||
|
# Get force vector -= 1> magnitude * direction
|
||||||
|
dir.mult(force)
|
||||||
|
return dir
|
||||||
|
|
||||||
|
|
||||||
|
class Particle:
|
||||||
|
|
||||||
|
def __init__(self, position):
|
||||||
|
self.acceleration = PVector(0, 0)
|
||||||
|
self.velocity = PVector(random(-1, 1) / 5, 0)
|
||||||
|
self.position = position.copy()
|
||||||
|
self.timeToLive = 255.0
|
||||||
|
self.mass = random(5, 20)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.update()
|
||||||
|
self.display()
|
||||||
|
|
||||||
|
def applyForce(self, force):
|
||||||
|
f = force.copy()
|
||||||
|
f.div(self.mass)
|
||||||
|
self.acceleration.add(f)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.velocity.add(self.acceleration)
|
||||||
|
self.position.add(self.velocity)
|
||||||
|
self.acceleration.mult(0)
|
||||||
|
self.timeToLive -= 1
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
stroke(0, 0, 0, self.timeToLive)
|
||||||
|
strokeWeight(2)
|
||||||
|
fill(255, 0, 0, self.timeToLive)
|
||||||
|
ellipse(self.position.x, self.position.y, self.mass, self.mass)
|
||||||
|
|
||||||
|
def isDead(self):
|
||||||
|
if (self.timeToLive < 0.0 or self.position.y > 410):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
class ParticleSystem():
|
||||||
|
|
||||||
|
def __init__(self, position):
|
||||||
|
self.origin = position.copy()
|
||||||
|
self.particles = []
|
||||||
|
|
||||||
|
def addParticle(self):
|
||||||
|
self.particles.append(Particle(self.origin))
|
||||||
|
|
||||||
|
def applyForce(self, f):
|
||||||
|
for p in self.particles:
|
||||||
|
p.applyForce(f)
|
||||||
|
|
||||||
|
def applyGravity(self):
|
||||||
|
for p in self.particles:
|
||||||
|
particleG = gravity.copy()
|
||||||
|
particleG.mult(p.mass)
|
||||||
|
p.applyForce(particleG)
|
||||||
|
|
||||||
|
def applyRepeller(self, r):
|
||||||
|
for p in self.particles:
|
||||||
|
force = r.calculateRepelForce(p)
|
||||||
|
p.applyForce(force)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
for p in reversed(self.particles):
|
||||||
|
p.run()
|
||||||
|
if p.isDead():
|
||||||
|
self.particles.remove(p)
|
||||||
|
# for i in reversed(range(len(self.particles))):
|
||||||
|
# p = self.particles[i]
|
||||||
|
# p.run()
|
||||||
|
# if p.isDead():
|
||||||
|
# del self.particles[i]
|
||||||
Ładowanie…
Reference in New Issue