Created
January 21, 2024 16:46
-
-
Save kardasis/ebf227a6a62103eef6dd4d81ec10f084 to your computer and use it in GitHub Desktop.
Modeling Charges on the surface of a sphere
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Vector } from 'p5' | |
type Vertex = { | |
position: Vector | |
velocity: Vector | |
neighbors: Vertex[] | |
charge: number | |
} | |
type Edge = [Vertex, Vertex] | |
export default class ChargeBall { | |
vertices: Vertex[] | |
edges: Edge[] | |
constructor (vertexCount: number) { | |
this.vertices = [] | |
this.edges = [] | |
for (var i = 0; i < vertexCount; i++) { | |
const position = new Vector( | |
2 * Math.random() - 1, | |
2 * Math.random() - 1, | |
2 * Math.random() - 1 | |
).normalize() | |
this.vertices.push({ | |
position, | |
velocity: new Vector(0, 0, 0), | |
neighbors: [], | |
charge: 2 * Math.random() - 1 | |
}) | |
} | |
this.edges = [] | |
for (let i = 0; i < this.vertices.length; i++) { | |
for (let j = i + 1; j < this.vertices.length; j++) { | |
this.addEdge(this.vertices[i], this.vertices[j]) | |
} | |
} | |
} | |
update (mode: string, dampening: number) { | |
this.vertices.forEach(vertex => { | |
let acc = new Vector(0, 0) | |
vertex.neighbors.forEach(n => { | |
const dist = Vector.sub(n.position, vertex.position).mag() | |
const direction = Vector.sub(vertex.position, n.position).normalize() | |
let chargeStrength | |
switch (mode) { | |
case 'attract': | |
chargeStrength = 1 | |
break | |
case 'repel': | |
chargeStrength = -1 | |
break | |
default: | |
chargeStrength = n.charge * vertex.charge | |
break | |
} | |
n.charge * vertex.charge | |
const dAcc = direction.mult(chargeStrength / (dist * dist)) | |
acc.add(dAcc) | |
}) | |
acc.mult(-0.00001) | |
vertex.velocity.add(acc) | |
vertex.velocity.sub(project(vertex.velocity, vertex.position)) // project velocity onto plane normal to position | |
vertex.position.add(vertex.velocity) | |
vertex.velocity.mult(dampening) | |
vertex.position.normalize() | |
}) | |
} | |
addEdge (a: Vertex, b: Vertex) { | |
b.neighbors.push(a) | |
a.neighbors.push(b) | |
this.edges.push([a, b]) | |
} | |
} | |
// project p onto v | |
function project (p: Vector, v: Vector) { | |
const vNorm = Vector.normalize(v) | |
return vNorm.mult(vNorm.dot(p)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment