xxxxxxxxxx
230
"use strict"
class Particle {
constructor() {
this.pos = createVector()
this.vel = createVector()
this.acc = createVector()
this.mass = random(1,3)
this.rad = this.mass * 3
//colour
this.r = random(255)
this.g = random(255)
this.b = random(255)
this.a = 100;
}
applyAttraction(other) {
var distance = this.pos.dist(other.pos);
var magnitude = (C_GRAVITY * this.mass * other.mass) / (distance * distance);
var force = p5.Vector.sub(other.pos, this.pos);
force.normalize();
force.mult(magnitude);
//force.mult(-1); //make it repulsion
this.applyForce(force);
}
position(x, y, z) {
this.pos = createVector(x, y, z)
return this
}
velocity(x, y, z) {
this.vel = createVector(x, y, z)
return this
}
colour(r, g, b, a) {
this.r = r
this.g = g
this.b = b
this.a = a
return this
}
update() {
this.vel.mult(0.8)
this.vel.add(this.acc)
this.pos.add(this.vel)
this.acc.mult(0)
}
display() {
push()
translate(this.pos.x, this.pos.y, this.pos.z)
// fill(this.r, this.g, this.b, this.a)
sphere(this.rad*1.5)
pop()
}
checkFloor() {
if (this.pos.x > -FLOOR_SIZE / 2 && this.pos.x < FLOOR_SIZE / 2 &&
this.pos.z > -FLOOR_SIZE / 2 && this.pos.z < FLOOR_SIZE / 2) {
//if in the floor area
//they bounce
if (this.pos.y - this.rad < FLOOR_LEVEL) {
this.pos.y = FLOOR_LEVEL + this.rad
this.vel.y *= -1
//restitution
var co_res = map(this.mass, 1, 5, 0.99, 0.80)
this.vel.y *= co_res
}
}
}
checkFloorxWall() {
//x
if (this.pos.x < -FLOOR_SIZE / 2 || this.pos.x > FLOOR_SIZE / 2) {
this.vel.x *= -1
}
//z
if (this.pos.z < -FLOOR_SIZE / 2 || this.pos.z > FLOOR_SIZE / 2) {
this.vel.z *= -1
}
this.pos.x = constrain(this.pos.x, -FLOOR_SIZE / 2, FLOOR_SIZE / 2)
this.pos.z = constrain(this.pos.z, -FLOOR_SIZE / 2, FLOOR_SIZE / 2)
//if in the floor area
//they bounce
//floor or y
if (this.pos.y - this.rad < FLOOR_LEVEL) {
this.pos.y = FLOOR_LEVEL + this.rad
this.vel.y *= -1
//restitution
var co_res = map(this.mass, 1, 5, 0.99, 0.80)
this.vel.y *= co_res
}
//roof
if (this.pos.y + this.rad > -FLOOR_LEVEL) {
this.pos.y = -FLOOR_LEVEL - this.rad
this.vel.y *= -1
//restitution
var co_res = map(this.mass, 1, 5, 0.99, 0.80)
this.vel.y *= co_res
}
}
applyForce(force) {
force.div(this.mass)
this.acc.add(force)
}
checkCollision(other) {
var distance = this.pos.dist(other.pos)
if (distance < this.rad + other.rad) {
//collided!
//this. particle
var force = p5.Vector.sub(other.pos, this.pos)
force.normalize()
force.mult(this.vel.mag() * 0.8)
other.applyForce(force)
//other particle
force.mult(-1)
force.normalize()
force.mult(other.vel.mag() * 0.8)
this.applyForce(force)
}
}
}
var p
var C_GRAVITY = 2
var FLOOR_LEVEL = -100
var FLOOR_SIZE = 300
var particles = []
var attractors = []
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL) //remember to put WEBGL when you do 3D
colorMode(HSL)
for (var i = 0; i < 10; i++) {
particles[i] = new Particle()
.position(random(-FLOOR_SIZE, FLOOR_SIZE), random(FLOOR_LEVEL, -FLOOR_LEVEL), random(-FLOOR_SIZE, FLOOR_SIZE)) //if you set them in the same position, they'll explode like fireworks lol
.velocity(random(0, 1), random(0, 1), random(0, 1))
}
var followX = map(mouseX, 0, width, FLOOR_SIZE, -FLOOR_SIZE)
var followY = map(mouseY, 0, width, FLOOR_LEVEL, -FLOOR_LEVEL)
for (var j = 0; j < 1; j++) {
attractors[j] = new Particle()
.position(0, 0, 0)
//.velocity(5, 5, 5)
}
}
function draw() {
background(0)
scale(1, -1, 1) //to flip the y axis
//mouse rotation
var rotY = map(sin(frameCount*0.005), 0, width, -PI / 2, PI / 2) //rotate when you move the mouse
rotateY(rotY)
var rotX = map(sin(frameCount*0.005), 0, width, -PI / 6, PI / 6)
rotateX(rotX)
//floor
for (var i = -1; i <= 2; i += 2) {
push()
translate(0, FLOOR_LEVEL * (i), 0)
rotateX(PI / 2)
fill(255, 0)
plane(FLOOR_SIZE, FLOOR_SIZE)
pop()
}
//light
ambientLight(240, 100, 30) //r g b
pointLight(0, 100, 50, 0, 300, 0) //r g b x y z -- position of the light source
pointLight(120, 100, 50, 300, 0, 0) //r g b x y z -- position of the light source
pointLight(240, 100, 50, 0, 0, 300)
//attractors
for (var a = 0; a < attractors.length; a++) {
var attr = attractors[a]
attr.mass = 500
attr.rad = 50
attr.update()
attr.display()
}
//particles
for (var a = 0; a < particles.length; a++) {
//calling all the functions
var p = particles[a]
for (var b = 0; b < particles.length; b++) {
if (a != b) { //a can't be the same as b
//p.checkCollision(particles[b])
}
}
for (var c = 0; c < attractors.length; c++) {
p.applyAttraction(attractors[c])
}
if (p.pos.y < FLOOR_LEVEL + p.rad + 0.1) {
var friction = p.vel.copy()
friction.normalize()
friction.mult(-1)
friction.mult(0.5) // CO_FRICTION
friction.limit(p.vel.copy)
p.applyForce(friction)
}
p.checkFloorxWall()
p.update()
p.display()
}
}