Source: field.js

/*******************************************************************************
*   @file field.js
*   @brief A file containing the Field class
*
*   @author <a href='mailto:omareq08@gmail.com'> Omar Essilfie-Quaye </a>
*   @version 1.0
*   @date 22-Aug-2018
*
*******************************************************************************/

/**
*	A class representing an electrostatic field and all the particles that
*	create it.
*/
class Field {
	/**
	*	Create a Field
	*
	*	@param {number} width  - The width of the Field
	*	@param {number} height - The height of the Field
	*/
	constructor(width, height) {
		this.width = width;
		this.height = height;

		/**
		*	2D field vector array.
		*	@type {Array<Array<p5.Vector>>}
		*/
		this.field = [];
		arrayCopy(this.zeroField(), this.field);

		/**
		*	Particles stack.
		*	@type {Particle}
		*/
		this.particles = [];
	}

	/**
	*	Creates field array where all values are a zero vector.
	*
	*	@returns {Array<Array<p5.Vector>>} The 2D array containing the zero
	*		field vectors.
	*/
	zeroField() {
		let zero = createVector(0, 0);
		let zeroCol = [];

		for(let h = 0; h < this.height; h++) {
			zeroCol.push(zero.copy());
		}

		let row = [];

		for(let w = 0; w < this.width; w++) {
			let newCol = [];
			arrayCopy(zeroCol, newCol);
			row.push(newCol);
		}

		return row;
	}

	/**
	*	Adds a particle to the field particles stack.
	*	Calculates the new field vectors.
	*
	*	@param {Particle} part - The particle to be added to the field.
	*/
	addParticle(part) {
		this.particles.push(part);
		for(let w = 0; w < this.width; w+=this.space) {
			for(let h = 0; h < this.height; h+=this.space) {
				const px = part.pos.x;
				const py = part.pos.y;
				const pc = part.charge;

				const d2 = (px - w) * (px - w) + (py - h) * (py - h);

				const vx = w - px;
				const vy = h - py;
				const v = createVector(vx, vy);

				const e = v.mult(pc / d2);

				this.field[w][h] = p5.Vector.add(this.field[w][h], e);
			}
		}
	}

	/**
	*	Pops particle from the fields particles stack.
	*	Recalculates the field with the particle gone.
	*/
	popParticle() {
		let part = this.particles.pop();

		for(let w = 0; w < this.width; w++) {
			for(let h = 0; h < this.height; h++) {
				let px = part.pos.x;
				let py = part.pos.y;
				let pc = part.charge;

				let d2 = (px - w) * (px - w) + (py - h) * (py - h);

				let vx = w - px;
				let vy = h - py;
				let v = createVector(-vx, -vy);

				let e = v.mult(pc / d2);

				this.field[w][h] = p5.Vector.add(this.field[w][h], e);
			}
		}
	}

	/**
	*	Empties the particle stack.
	*	Zeros the field using {@link Field#zeroField}
	*/
	clear() {
		this.particles = [];
		arrayCopy(this.zeroField(), this.field);
	}

	/**
	*	Draws the field vectors. Draws the particles creating the field.
	*
	*	@param {number} space - The distance in pixels between each grid point.
	*	@param {number} scale - A scale factor that shortens or lengthens the
	*		field vectors that are drawn.
	*/
	draw(space, scale) {
		this.space = space;
		stroke(0);
		for(let w = 0; w < this.width; w += space) {
			for(let h = 0; h < this.height; h += space) {
				let v = this.field[w][h].copy();
				let l = v.mag();
				let theta = atan2(v.y, v.x);
				let x = scale * l * cos(theta);
				let y = scale * l * sin(theta);

				line(w, h, w + x, h + y);

				ellipse(w, h, space * 0.05, space * 0.05);

			}
		}

		for(let p = 0; p < this.particles.length; p++) {
			let part = this.particles[p];
			part.draw();
		}
	}
}

Documentation generated by JSDoc 4.0.2 on Sun Jan 26 2025 19:14:19 GMT-0800 (Pacific Standard Time)