xxxxxxxxxx
115
// Constants
const GRAVITY = 0.001;
const NUM_PARTICLES = 100;
const MAX_DISTANCE_FROM_CENTER = 200;
// Matter.js aliases
const Engine = Matter.Engine;
const World = Matter.World;
const Bodies = Matter.Bodies;
const Vertices = Matter.Vertices;
const Body = Matter.Body;
// Global variables
let engine;
let world;
let particles = [];
let walls = [];
// Particle class
class Particle {
constructor(x, y, vertices) {
this.body = Bodies.fromVertices(x, y, vertices, { restitution: 0.5, density: 1 });
World.add(world, this.body);
}
display() {
const { x, y } = this.body.position;
const angle = this.body.angle;
const vertices = this.body.vertices;
push();
translate(x, y);
rotate(angle);
beginShape();
for (let v of vertices) {
vertex(v.x - x, v.y - y);
}
endShape(CLOSE);
pop();
}
attract(other) {
const dx = this.body.position.x - other.body.position.x;
const dy = this.body.position.y - other.body.position.y;
const distanceSq = Math.max(dx * dx + dy * dy, 100);
const massA = this.body.mass;
const massB = other.body.mass;
const strength = GRAVITY * (massA * massB) / distanceSq;
const force = {
x: (dx / Math.sqrt(distanceSq)) * strength,
y: (dy / Math.sqrt(distanceSq)) * strength,
};
Matter.Body.applyForce(other.body, other.body.position, force);
}
}
// p5.js setup function
function setup() {
createCanvas(windowWidth, windowHeight);
engine = Engine.create();
world = engine.world;
world.gravity.scale = 0; // Disable default gravity
// Create walls
const wallThickness = 50;
walls.push(Bodies.rectangle(width / 2, -wallThickness / 2, width + wallThickness * 2, wallThickness, { isStatic: true }));
walls.push(Bodies.rectangle(width / 2, height + wallThickness / 2, width + wallThickness * 2, wallThickness, { isStatic: true }));
walls.push(Bodies.rectangle(-wallThickness / 2, height / 2, wallThickness, height + wallThickness * 2, { isStatic: true }));
walls.push(Bodies.rectangle(width + wallThickness / 2, height / 2, wallThickness, height + wallThickness * 2, { isStatic: true }));
walls.forEach(wall => World.add(world, wall));
for (let i = 0; i < NUM_PARTICLES; i++) {
const angle = random(TWO_PI);
const distance = random(MAX_DISTANCE_FROM_CENTER);
const x = width / 2 + cos(angle) * distance;
const y = height / 2 + sin(angle) * distance;
const vertices = generateRandomConvexPolygon(5, 20);
particles.push(new Particle(x, y, vertices));
}
}
// p5.js draw function
function draw() {
background(0);
Engine.update(engine);
for (let i = 0; i < particles.length; i++) {
for (let j = i + 1; j < particles.length; j++) {
particles[i].attract(particles[j]);
}
particles[i].display();
}
}
// Helper function to generate random convex polygons
function generateRandomConvexPolygon(minSize, maxSize) {
const numVertices = floor(random(3, 7));
const angleStep = TWO_PI / numVertices;
const sizeRange = maxSize - minSize;
const vertices = [];
for (let i = 0; i < numVertices; i++) {
const angle = i * angleStep;
const distance = random(sizeRange) + minSize;
const x = cos(angle) * distance;
const y = sin(angle) * distance;
vertices.push({ x, y });
}
return Vertices.create(vertices);
}