import * as util from './utils.js' import AgentArray from './AgentArray.js' // Class Link instances form a link between two turtles, forming a graph. // Flyweight object creation, see Patch/Patches. // https://medium.com/dailyjs/two-headed-es6-classes-fe369c50b24 /** * Class Link instances form a link between two {@link Turtle}s, forming a graph * with the Turtles being the nodes, and the Links the edges. * * You do not call `new Link()`, instead class Links creates Link instances * via {@link Links#create} or {@link Links#createOne} * * I.e. class Turtles is a factory for all of it's Turtle instances. * So *don't* do this: */ class Link { static defaults = { width: 1, // THREE: must be 1. Canvas2D (unsupported) hidden: false, // Set by AgentSet agentSet: null, model: null, name: null, } static variables = { id: null, theta: 0, x: 0, y: 0, } constructor() { Object.assign(this, Link.defaults) } newInstance(agentProto) { const insstance = Object.create(agentProto) Object.assign(insstance, Link.variables) return insstance } init(from, to) { this.end0 = from this.end1 = to from.links.push(this) to.links.push(this) } // Remove this link from its agentset die() { if (this.id === -1) return this.agentSet.removeAgent(this) util.removeArrayItem(this.end0.links, this) util.removeArrayItem(this.end1.links, this) // Set id to -1, indicates that I've died. this.id = -1 } isDead() { return this.id === -1 } bothEnds() { return AgentArray.fromArray([this.end0, this.end1]) } length() { return this.end0.distance(this.end1) } // use getter, all the other headings are getters get heading() { const { x0, x1, y0, y1 } = this const rads = Math.atan2(y1 - y0, x1 - x0) return this.model.fromRads(rads) } otherEnd(turtle) { if (turtle === this.end0) return this.end1 if (turtle === this.end1) return this.end0 throw Error(`Link.otherEnd: turtle not a link turtle: ${turtle}`) } distanceXY(x, y) { return ( this.bothEnds() .map(t => t.distanceXY(x, y)) .sum() - this.length() ) } get x0() { return this.end0.x } get y0() { return this.end0.y } get z0() { return this.end0.z ? this.end0.z : 0 // REMIND: move to turtles } get x1() { return this.end1.x } get y1() { return this.end1.y } get z1() { return this.end1.z ? this.end1.z : 0 } } export default Link