### Magnetic Field ðŸ§²

Anodes and cathode

```const nElectrodes = 4; //min=2 max=40 step=1
const electrodeRadius = 3; //min=1 max=10 step=.5
const emitterPattern = 1; //min=0 max=1 step=1 (Regular, Random)
const nElectronsPerElectrode = 300; //min=0 max=500 step=10
const electrodeLocation = 1; //min=0 max=1 step=1 (Random, Farthest candidate)
const nCandidates = 10; //min=1 max=20 step=1
const border=10; //min=0 max=10 step=1
const chargeRange=0; //min=0 max=1.5 step=.1
const electrodeNegPos=1; //min=0 max=1 step=1 (Random, Alternating)

if(nElectronsPerElectrode == 0) nElectronsPerElectrode = 1;
if(electrodeLocation == 0) nCandidates = 1;

// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(.4);

// Global code will be evaluated once.
const turtle = new Turtle();
const pi2 = 2 * Math.PI;

function normalize2(a) { const length = len2(a); return scale2(a,length<0.0001?1:1/length); }
function len2(a) { return Math.sqrt(lensq2(a)); }
function lensq2(a) { return dot2(a,a); }
function rot2(a) { return [Math.cos(a), -Math.sin(a), Math.sin(a), Math.cos(a)]; }
function trans2(m, a) { return [m[0]*a[0]+m[2]*a[1], m[1]*a[0]+m[3]*a[1]]; }
function scale2(a,b) { return [a[0]*b,a[1]*b]; }
function add2(a,b) { return [a[0]+b[0],a[1]+b[1]]; }
function sub2(a,b) { return [a[0]-b[0],a[1]-b[1]]; }
function dist2(a,b) { return Math.hypot(...sub2(a,b)); }
function lerp2(a,b,t) { return [a[0]*(1-t)+b[0]*t,a[1]*(1-t)+b[1]*t]; }
function dot2(a,b) { return a[0]*b[0]+a[1]*b[1] }
function mulf2(v, f) { return scale2(v,f); }
function multiply2(a2x2, a) { return [(a[0]*a2x2[0])+(a[1]*a2x2[1]),(a[0]*a2x2[2])+(a[1]*a2x2[3])]; }

class Electrode {
constructor (xy, r, v) {
this.pos = xy;
this.charge = v;
this.emitterCount = 0;
}
draw(t) {
for(let i = 0; i < 4; i++) {

t.jump(this.pos[0] - (this.radius / 2), this.pos[1]);
t.goto(this.pos[0] + (this.radius / 2), this.pos[1]);
if(this.charge >= 0) {
t.jump(this.pos[0], this.pos[1] - (this.radius / 2));
t.goto(this.pos[0], this.pos[1] + (this.radius / 2));
}
}
}
spawn() {
let a = Math.random() * pi2;
if(emitterPattern == '0') {
a = pi2 * (this.emitterCount++ / nElectronsPerElectrode);
}
return new Electron(
);
}
}

class Electron {
constructor (xy) {
this.pos = xy;
this.t = new Turtle();
this.t.jump(this.pos);
this.active = true;
}
step(electrodes) {
if(!this.active) return;
let force = [0,0];
let that = this;
electrodes.forEach(function(i) {
if(i == null) return;
let dSquared = (that.t.pos()[0] - i.pos[0])**2 + (that.t.pos()[1] - i.pos[1])**2;
let f = Math.sqrt(1/Math.sqrt(dSquared)) * -i.charge;
let direction = normalize2(sub2(that.t.pos(), i.pos));
});
//electrodes.filter((i) => i.charge >= 0).forEach(function(i) {
electrodes.forEach(function(i) {
if(
&&
) {
nextPos = approxIntersection(i, that.t.pos(), nextPos);
that.active = false;
}
}
//console.log('something to make it slow')
});
if( border > 0 && (
nextPos[0] < border - 100 || 100 - border < nextPos[0]
||
nextPos[1] < border - 100 || 100 - border < nextPos[1]
)) {
this.t.jump(nextPos);
} else {
this.t.goto(nextPos);
}
}
}

function approxIntersection(circle, sectionStart, sectionEnd) {
let lr = Math.sqrt((sectionEnd[0] - circle.pos[0])**2 + (sectionEnd[1] - circle.pos[1])**2 )
return null;
}

let angle = 0;
let dx = sectionEnd[0] - circle.pos[0];
let dy = sectionEnd[1] - circle.pos[1];
if(dx == 0) {
angle = Math.PI * (dy > 0? .5: 1.5);
} else {
let dydx = dy/dx;
angle = Math.atan(dy/dx);

if(dx < 0) {
angle += Math.PI
}
}

return [
]
}

const electrodes = [];
const negposflip = [-1, 1].sort((i) => Math.random() < .5);
let negpos = false;

for(let i = 0; i < nElectrodes; i++) {
let candidates = [];

for(let j = 0; j < nCandidates; j++) {
let x = (Math.random() * (200 - border - border - electrodeRadius - electrodeRadius)) - ((200 - border - border - electrodeRadius - electrodeRadius) / 2);
let y = (Math.random() * (200 - border - border - electrodeRadius - electrodeRadius)) - ((200 - border - border - electrodeRadius - electrodeRadius) / 2);

let candidate = [x, y];
let minDistance = 9999999;
for(let k = 0; k < electrodes.length; k++) {
let distance = dist2(electrodes[k].pos, candidate);
if(distance < minDistance) {
minDistance = distance;
}
}
candidates.push([minDistance, candidate]);
}

candidates.sort((a, b) => (a[0] < b[0]) ? 1 : -1);
electrodes.push(new Electrode(
candidates[0][1],
(.5 + (Math.random() * chargeRange)) * (electrodeNegPos == 1? (negpos == false? -1: 1): negposflip.length > 0? negposflip.pop() : Math.random() < .5? -1: 1)
));
negpos = !negpos;
}

let electrons = [];
let nElectrons = nElectronsPerElectrode;
electrodes.forEach((i) => i.draw(turtle));
electrodes.filter((i) => i.charge < 0).forEach(function (i) { for(let j = 0; j < nElectrons; j++) { electrons.push(i.spawn()) } });
// The walk function will be called until it returns false.
function walk(i) {
electrons.forEach(function(j) { j.step(electrodes) });
electrons = electrons.filter((i) => i.active);

return electrons.length > 0 && i < 50000;
}```