UNPKG

romgrk-2d-geometry

Version:

Javascript library for 2d geometry

106 lines (90 loc) 4.3 kB
import Interval from './interval'; import { Color } from '../utils/constants'; class Node { left: Node right: Node parent: Node color: Color item: { key: any, value: any } max: Interval | undefined constructor(key = undefined, value = undefined, left = null, right = null, parent = null, color = Color.BLACK) { this.left = left; // reference to left child node this.right = right; // reference to right child node this.parent = parent; // reference to parent node this.color = color; this.item = { key: key, value: value }; // key is supposed to be instance of Interval /* If not, this should by an array of two numbers */ if (key && key instanceof Array && key.length == 2) { if (!Number.isNaN(key[0]) && !Number.isNaN(key[1])) { this.item.key = new Interval(Math.min(key[0], key[1]), Math.max(key[0], key[1])); } } this.max = this.item.key ? this.item.key.max : undefined; } isNil() { return (this.item.key === undefined && this.item.value === undefined && this.left === null && this.right === null && this.color === Color.BLACK); } _value_less_than(other_node) { return this.item.value && other_node.item.value && this.item.value.lessThan ? this.item.value.lessThan(other_node.item.value) : this.item.value < other_node.item.value; } lessThan(other_node) { // if tree stores only keys if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) { return this.item.key.lessThan(other_node.item.key); } else { // if tree stores keys and values return this.item.key.lessThan(other_node.item.key) || this.item.key.equalTo((other_node.item.key)) && this._value_less_than(other_node) } } _value_equal(other_node) { return this.item.value && other_node.item.value && this.item.value.equalTo ? this.item.value.equalTo(other_node.item.value) : this.item.value == other_node.item.value; } equalTo(other_node) { // if tree stores only keys if (this.item.value === this.item.key && other_node.item.value === other_node.item.key) { return this.item.key.equalTo(other_node.item.key); } else { // if tree stores keys and values return this.item.key.equalTo(other_node.item.key) && this._value_equal(other_node); } } intersect(other_node) { return this.item.key.intersect(other_node.item.key); } copy_data(other_node) { this.item.key = other_node.item.key; this.item.value = other_node.item.value; } update_max() { // use key (Interval) max property instead of key.high this.max = this.item.key ? this.item.key.max : undefined; if (this.right && this.right.max) { const comparableMax = this.item.key.constructor.comparableMax; // static method this.max = comparableMax(this.max, this.right.max); } if (this.left && this.left.max) { const comparableMax = this.item.key.constructor.comparableMax; // static method this.max = comparableMax(this.max, this.left.max); } } // Other_node does not intersect any node of left subtree, if this.left.max < other_node.item.key.low not_intersect_left_subtree(search_node) { const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method let high = this.left.max.high !== undefined ? this.left.max.high : this.left.max; return comparable_less_than(high, search_node.item.key.low); } // Other_node does not intersect right subtree if other_node.item.key.high < this.right.key.low not_intersect_right_subtree(search_node) { const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method let low = this.right.max.low !== undefined ? this.right.max.low : this.right.item.key.low; return comparable_less_than(search_node.item.key.high, low); } }; export default Node;