On this page

# Link.js

    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

Type anything to view search result