-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsph.js
91 lines (79 loc) · 2.37 KB
/
sph.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
var sph = {
gravity: 1,
pressure: 4,
viscosity: 8,
particles: [],
add_particle: function(x, y) {
this.particles.push({
position: math.complex(x, y),
wall: false,
density: 0,
force: math.complex(0, 0),
velocity: math.complex(0, 0),
});
},
add_wall: function(x, y) {
this.particles.push({
position: math.complex(x, y),
wall: true,
density: 0,
force: math.complex(0, 0),
velocity: math.complex(0, 0),
});
},
remove_particle: function(x, y) {
this.particles.forEach(function(particle, index, particles) {
if (particle.position.re == x && particle.position.im == y) {
particles.splice(index, 1);
}
});
},
clear: function() {
this.particles = [];
},
on_neighbours: function(particle, callback) {
this.particles.forEach(function(neighbour) {
// Get distance
var distance = math.subtract(particle.position, neighbour.position);
var weight = math.abs(distance) / 2 - 1;
// Only keep close particles
if (weight < 1) {
callback.apply(this, [particle, neighbour, distance, weight]);
}
}, this);
},
move: function() {
// Calculate density
this.particles.forEach(function(particle) {
particle.density = 0;
if (particle.wall) {
particle.density = 9;
return ;
}
this.on_neighbours(particle, function(particle, neighbour, distance, weight) {
particle.density += weight * weight;
});
}, this);
// Calculate external forces
this.particles.forEach(function(particle) {
particle.force = math.complex(0, this.gravity);
if (particle.wall)
return ;
this.on_neighbours(particle, function(particle, neighbour, distance, weight) {
var pressure = math.multiply(distance, (3 - particle.density - neighbour.density) * this.pressure);
var velocity = math.subtract(math.multiply(particle.velocity, this.viscosity),
math.multiply(neighbour.velocity, this.viscosity));
var force = math.divide(math.multiply(weight, math.add(pressure, velocity)), particle.density);
particle.force = math.add(particle.force, force);
});
}, this);
// Move
this.particles.forEach(function(particle) {
if (!particle.wall) {
console.log(particle);
particle.velocity = math.add(particle.velocity, math.divide(particle.force, 10));
particle.position = math.add(particle.position, particle.velocity);
}
}, this);
},
};