d20ec5cad67463872f6aa5336bea3bb9ddb6b14ed27e50067e567c43d4ac6bf4.json 84 KB

1
  1. {"ast":null,"code":"import { Matrix, Vector3 } from \"../Maths/math.vector.js\";\n// This implementation was based on the original MIT-licensed TRACE repository\n// from https://github.com/septagon/TRACE.\n/**\n * Generic implementation of Levenshtein distance.\n */\nvar Levenshtein;\n(function (Levenshtein) {\n /**\n * Alphabet from which to construct sequences to be compared using Levenshtein\n * distance.\n */\n class Alphabet {\n /**\n * Serialize the Alphabet to JSON string.\n * @returns JSON serialization\n */\n serialize() {\n const jsonObject = {};\n const characters = new Array(this._characterToIdx.size);\n this._characterToIdx.forEach((v, k) => {\n characters[v] = k;\n });\n jsonObject[\"characters\"] = characters;\n jsonObject[\"insertionCosts\"] = this._insertionCosts;\n jsonObject[\"deletionCosts\"] = this._deletionCosts;\n jsonObject[\"substitutionCosts\"] = this._substitutionCosts;\n return JSON.stringify(jsonObject);\n }\n /**\n * Parse an Alphabet from a JSON serialization.\n * @param json JSON string to deserialize\n * @returns deserialized Alphabet\n */\n static Deserialize(json) {\n const jsonObject = JSON.parse(json);\n const alphabet = new Alphabet(jsonObject[\"characters\"]);\n alphabet._insertionCosts = jsonObject[\"insertionCosts\"];\n alphabet._deletionCosts = jsonObject[\"deletionCosts\"];\n alphabet._substitutionCosts = jsonObject[\"substitutionCosts\"];\n return alphabet;\n }\n /**\n * Create a new Alphabet.\n * @param characters characters of the alphabet\n * @param charToInsertionCost function mapping characters to insertion costs\n * @param charToDeletionCost function mapping characters to deletion costs\n * @param charsToSubstitutionCost function mapping character pairs to substitution costs\n */\n constructor(characters, charToInsertionCost = null, charToDeletionCost = null, charsToSubstitutionCost = null) {\n var _charToInsertionCost, _charToDeletionCost, _charsToSubstitutionC;\n charToInsertionCost = (_charToInsertionCost = charToInsertionCost) !== null && _charToInsertionCost !== void 0 ? _charToInsertionCost : () => 1;\n charToDeletionCost = (_charToDeletionCost = charToDeletionCost) !== null && _charToDeletionCost !== void 0 ? _charToDeletionCost : () => 1;\n charsToSubstitutionCost = (_charsToSubstitutionC = charsToSubstitutionCost) !== null && _charsToSubstitutionC !== void 0 ? _charsToSubstitutionC : (a, b) => a === b ? 0 : 1;\n this._characterToIdx = new Map();\n this._insertionCosts = new Array(characters.length);\n this._deletionCosts = new Array(characters.length);\n this._substitutionCosts = new Array(characters.length);\n let c;\n for (let outerIdx = 0; outerIdx < characters.length; ++outerIdx) {\n c = characters[outerIdx];\n this._characterToIdx.set(c, outerIdx);\n this._insertionCosts[outerIdx] = charToInsertionCost(c);\n this._deletionCosts[outerIdx] = charToDeletionCost(c);\n this._substitutionCosts[outerIdx] = new Array(characters.length);\n for (let innerIdx = outerIdx; innerIdx < characters.length; ++innerIdx) {\n this._substitutionCosts[outerIdx][innerIdx] = charsToSubstitutionCost(c, characters[innerIdx]);\n }\n }\n }\n /**\n * Get the index (internally-assigned number) for a character.\n * @param char character\n * @returns index\n */\n getCharacterIdx(char) {\n return this._characterToIdx.get(char);\n }\n /**\n * Get the insertion cost of a character from its index.\n * @param idx character index\n * @returns insertion cost\n */\n getInsertionCost(idx) {\n return this._insertionCosts[idx];\n }\n /**\n * Get the deletion cost of a character from its index.\n * @param idx character index\n * @returns deletion cost\n */\n getDeletionCost(idx) {\n return this._deletionCosts[idx];\n }\n /**\n * Gets the cost to substitute two characters. NOTE: this cost is\n * required to be bi-directional, meaning it cannot matter which of\n * the provided characters is being removed and which is being inserted.\n * @param idx1 the first character index\n * @param idx2 the second character index\n * @returns substitution cost\n */\n getSubstitutionCost(idx1, idx2) {\n const min = Math.min(idx1, idx2);\n const max = Math.max(idx1, idx2);\n return this._substitutionCosts[min][max];\n }\n }\n Levenshtein.Alphabet = Alphabet;\n /**\n * Character sequence intended to be compared against other Sequences created\n * with the same Alphabet in order to compute Levenshtein distance.\n */\n class Sequence {\n /**\n * Serialize to JSON string. JSON representation does NOT include the Alphabet\n * from which this Sequence was created; Alphabet must be independently\n * serialized.\n * @returns JSON string\n */\n serialize() {\n return JSON.stringify(this._characters);\n }\n /**\n * Deserialize from JSON string and Alphabet. This should be the same Alphabet\n * from which the Sequence was originally created, which must be serialized and\n * deserialized independently so that it can be passed in here.\n * @param json JSON string representation of Sequence\n * @param alphabet Alphabet from which Sequence was originally created\n * @returns Sequence\n */\n static Deserialize(json, alphabet) {\n const sequence = new Sequence([], alphabet);\n sequence._characters = JSON.parse(json);\n return sequence;\n }\n /**\n * Create a new Sequence.\n * @param characters characters in the new Sequence\n * @param alphabet Alphabet, which must include all used characters\n */\n constructor(characters, alphabet) {\n if (characters.length > Sequence._MAX_SEQUENCE_LENGTH) {\n throw new Error(\"Sequences longer than \" + Sequence._MAX_SEQUENCE_LENGTH + \" not supported.\");\n }\n this._alphabet = alphabet;\n this._characters = characters.map(c => this._alphabet.getCharacterIdx(c));\n }\n /**\n * Get the distance between this Sequence and another.\n * @param other sequence to compare to\n * @returns Levenshtein distance\n */\n distance(other) {\n return Sequence._Distance(this, other);\n }\n /**\n * Compute the Levenshtein distance between two Sequences.\n * @param a first Sequence\n * @param b second Sequence\n * @returns Levenshtein distance\n */\n static _Distance(a, b) {\n const alphabet = a._alphabet;\n if (alphabet !== b._alphabet) {\n throw new Error(\"Cannot Levenshtein compare Sequences built from different alphabets.\");\n }\n const aChars = a._characters;\n const bChars = b._characters;\n const aLength = aChars.length;\n const bLength = bChars.length;\n const costMatrix = Sequence._CostMatrix;\n costMatrix[0][0] = 0;\n for (let idx = 0; idx < aLength; ++idx) {\n costMatrix[idx + 1][0] = costMatrix[idx][0] + alphabet.getInsertionCost(aChars[idx]);\n }\n for (let idx = 0; idx < bLength; ++idx) {\n costMatrix[0][idx + 1] = costMatrix[0][idx] + alphabet.getInsertionCost(bChars[idx]);\n }\n for (let aIdx = 0; aIdx < aLength; ++aIdx) {\n for (let bIdx = 0; bIdx < bLength; ++bIdx) {\n Sequence._InsertionCost = costMatrix[aIdx + 1][bIdx] + alphabet.getInsertionCost(bChars[bIdx]);\n Sequence._DeletionCost = costMatrix[aIdx][bIdx + 1] + alphabet.getDeletionCost(aChars[aIdx]);\n Sequence._SubstitutionCost = costMatrix[aIdx][bIdx] + alphabet.getSubstitutionCost(aChars[aIdx], bChars[bIdx]);\n costMatrix[aIdx + 1][bIdx + 1] = Math.min(Sequence._InsertionCost, Sequence._DeletionCost, Sequence._SubstitutionCost);\n }\n }\n return costMatrix[aLength][bLength];\n }\n }\n // Scratch values\n Sequence._MAX_SEQUENCE_LENGTH = 256;\n Sequence._CostMatrix = [...Array(Sequence._MAX_SEQUENCE_LENGTH + 1)].map(() => new Array(Sequence._MAX_SEQUENCE_LENGTH + 1));\n Levenshtein.Sequence = Sequence;\n})(Levenshtein || (Levenshtein = {}));\n/**\n * A 3D trajectory consisting of an order list of vectors describing a\n * path of motion through 3D space.\n */\nexport class Trajectory {\n /**\n * Serialize to JSON.\n * @returns serialized JSON string\n */\n serialize() {\n return JSON.stringify(this);\n }\n /**\n * Deserialize from JSON.\n * @param json serialized JSON string\n * @returns deserialized Trajectory\n */\n static Deserialize(json) {\n const jsonObject = JSON.parse(json);\n const trajectory = new Trajectory(jsonObject[\"_segmentLength\"]);\n trajectory._points = jsonObject[\"_points\"].map(pt => {\n return new Vector3(pt[\"_x\"], pt[\"_y\"], pt[\"_z\"]);\n });\n return trajectory;\n }\n /**\n * Create a new empty Trajectory.\n * @param segmentLength radius of discretization for Trajectory points\n */\n constructor(segmentLength = 0.01) {\n this._points = [];\n this._segmentLength = segmentLength;\n }\n /**\n * Get the length of the Trajectory.\n * @returns length of the Trajectory\n */\n getLength() {\n return this._points.length * this._segmentLength;\n }\n /**\n * Append a new point to the Trajectory.\n * NOTE: This implementation has many allocations.\n * @param point point to append to the Trajectory\n */\n add(point) {\n let numPoints = this._points.length;\n if (numPoints === 0) {\n this._points.push(point.clone());\n } else {\n const getT = () => this._segmentLength / Vector3.Distance(this._points[numPoints - 1], point);\n for (let t = getT(); t <= 1.0; t = getT()) {\n const newPoint = this._points[numPoints - 1].scale(1.0 - t);\n point.scaleAndAddToRef(t, newPoint);\n this._points.push(newPoint);\n ++numPoints;\n }\n }\n }\n /**\n * Create a new Trajectory with a segment length chosen to make it\n * probable that the new Trajectory will have a specified number of\n * segments. This operation is imprecise.\n * @param targetResolution number of segments desired\n * @returns new Trajectory with approximately the requested number of segments\n */\n resampleAtTargetResolution(targetResolution) {\n const resampled = new Trajectory(this.getLength() / targetResolution);\n this._points.forEach(pt => {\n resampled.add(pt);\n });\n return resampled;\n }\n /**\n * Convert Trajectory segments into tokenized representation. This\n * representation is an array of numbers where each nth number is the\n * index of the token which is most similar to the nth segment of the\n * Trajectory.\n * @param tokens list of vectors which serve as discrete tokens\n * @returns list of indices of most similar token per segment\n */\n tokenize(tokens) {\n const tokenization = [];\n const segmentDir = new Vector3();\n for (let idx = 2; idx < this._points.length; ++idx) {\n if (Trajectory._TransformSegmentDirToRef(this._points[idx - 2], this._points[idx - 1], this._points[idx], segmentDir)) {\n tokenization.push(Trajectory._TokenizeSegment(segmentDir, tokens));\n }\n }\n return tokenization;\n }\n /**\n * Transform the rotation (i.e., direction) of a segment to isolate\n * the relative transformation represented by the segment. This operation\n * may or may not succeed due to singularities in the equations that define\n * motion relativity in this context.\n * @param priorVec the origin of the prior segment\n * @param fromVec the origin of the current segment\n * @param toVec the destination of the current segment\n * @param result reference to output variable\n * @returns whether or not transformation was successful\n */\n static _TransformSegmentDirToRef(priorVec, fromVec, toVec, result) {\n const DOT_PRODUCT_SAMPLE_REJECTION_THRESHOLD = 0.98;\n fromVec.subtractToRef(priorVec, Trajectory._ForwardDir);\n Trajectory._ForwardDir.normalize();\n fromVec.scaleToRef(-1, Trajectory._InverseFromVec);\n Trajectory._InverseFromVec.normalize();\n if (Math.abs(Vector3.Dot(Trajectory._ForwardDir, Trajectory._InverseFromVec)) > DOT_PRODUCT_SAMPLE_REJECTION_THRESHOLD) {\n return false;\n }\n Vector3.CrossToRef(Trajectory._ForwardDir, Trajectory._InverseFromVec, Trajectory._UpDir);\n Trajectory._UpDir.normalize();\n Matrix.LookAtLHToRef(priorVec, fromVec, Trajectory._UpDir, Trajectory._LookMatrix);\n toVec.subtractToRef(fromVec, Trajectory._FromToVec);\n Trajectory._FromToVec.normalize();\n Vector3.TransformNormalToRef(Trajectory._FromToVec, Trajectory._LookMatrix, result);\n return true;\n }\n /**\n * Determine which token vector is most similar to the\n * segment vector.\n * @param segment segment vector\n * @param tokens token vector list\n * @returns index of the most similar token to the segment\n */\n static _TokenizeSegment(segment, tokens) {\n Trajectory._BestMatch = 0;\n Trajectory._Score = Vector3.Dot(segment, tokens[0]);\n Trajectory._BestScore = Trajectory._Score;\n for (let idx = 1; idx < tokens.length; ++idx) {\n Trajectory._Score = Vector3.Dot(segment, tokens[idx]);\n if (Trajectory._Score > Trajectory._BestScore) {\n Trajectory._BestMatch = idx;\n Trajectory._BestScore = Trajectory._Score;\n }\n }\n return Trajectory._BestMatch;\n }\n}\nTrajectory._ForwardDir = new Vector3();\nTrajectory._InverseFromVec = new Vector3();\nTrajectory._UpDir = new Vector3();\nTrajectory._FromToVec = new Vector3();\nTrajectory._LookMatrix = new Matrix();\n/**\n * Collection of vectors intended to be used as the basis of Trajectory\n * tokenization for Levenshtein distance comparison. Canonically, a\n * Vector3Alphabet will resemble a \"spikeball\" of vectors distributed\n * roughly evenly over the surface of the unit sphere.\n */\nclass Vector3Alphabet {\n /**\n * Helper method to create new \"spikeball\" Vector3Alphabets. Uses a naive\n * optimize-from-random strategy to space points around the unit sphere\n * surface as a simple alternative to really doing the math to tile the\n * sphere.\n * @param alphabetSize size of the desired alphabet\n * @param iterations number of iterations over which to optimize the \"spikeball\"\n * @param startingStepSize distance factor to move points in early optimization iterations\n * @param endingStepSize distance factor to move points in late optimization iterations\n * @param fixedValues alphabet \"characters\" that are required and cannot be moved by optimization\n * @returns a new randomly generated and optimized Vector3Alphabet of the specified size\n */\n static Generate(alphabetSize = 64, iterations = 256, startingStepSize = 0.1, endingStepSize = 0.001, fixedValues = []) {\n const EPSILON = 0.001;\n const EPSILON_SQUARED = EPSILON * EPSILON;\n const alphabet = new Vector3Alphabet(alphabetSize);\n for (let idx = 0; idx < alphabetSize; ++idx) {\n alphabet.chars[idx] = new Vector3(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);\n alphabet.chars[idx].normalize();\n }\n for (let idx = 0; idx < fixedValues.length; ++idx) {\n alphabet.chars[idx].copyFrom(fixedValues[idx]);\n }\n let stepSize;\n let distSq;\n const force = new Vector3();\n const scratch = new Vector3();\n const lerp = (l, r, t) => (1.0 - t) * l + t * r;\n for (let iteration = 0; iteration < iterations; ++iteration) {\n stepSize = lerp(startingStepSize, endingStepSize, iteration / (iterations - 1));\n for (let idx = fixedValues.length; idx < alphabet.chars.length; ++idx) {\n force.copyFromFloats(0, 0, 0);\n alphabet.chars.forEach(pt => {\n alphabet.chars[idx].subtractToRef(pt, scratch);\n distSq = scratch.lengthSquared();\n if (distSq > EPSILON_SQUARED) {\n scratch.scaleAndAddToRef(1 / (scratch.lengthSquared() * distSq), force);\n }\n });\n force.scaleInPlace(stepSize);\n alphabet.chars[idx].addInPlace(force);\n alphabet.chars[idx].normalize();\n }\n }\n return alphabet;\n }\n /**\n * Serialize to JSON.\n * @returns JSON serialization\n */\n serialize() {\n return JSON.stringify(this.chars);\n }\n /**\n * Deserialize from JSON.\n * @param json JSON serialization\n * @returns deserialized Vector3Alphabet\n */\n static Deserialize(json) {\n const jsonObject = JSON.parse(json);\n const alphabet = new Vector3Alphabet(jsonObject.length);\n for (let idx = 0; idx < jsonObject.length; ++idx) {\n alphabet.chars[idx] = new Vector3(jsonObject[idx][\"_x\"], jsonObject[idx][\"_y\"], jsonObject[idx][\"_z\"]);\n }\n return alphabet;\n }\n constructor(size) {\n this.chars = new Array(size);\n }\n}\n/**\n * Class which formalizes the manner in which a Vector3Alphabet is used to tokenize and\n * describe a Trajectory. This class houses the functionality which determines what\n * attributes of Trajectories are and are not considered important, such as scale.\n */\nclass TrajectoryDescriptor {\n /**\n * Serialize to JSON.\n * @returns JSON serialization\n */\n serialize() {\n return JSON.stringify(this._sequences.map(sequence => sequence.serialize()));\n }\n /**\n * Deserialize from JSON string and Alphabet. This should be the same Alphabet\n * from which the descriptor was originally created, which must be serialized and\n * deserialized independently so that it can be passed in here.\n * @param json JSON serialization\n * @param alphabet Alphabet from which descriptor was originally created\n * @returns deserialized TrajectoryDescriptor\n */\n static Deserialize(json, alphabet) {\n const descriptor = new TrajectoryDescriptor();\n descriptor._sequences = JSON.parse(json).map(s => Levenshtein.Sequence.Deserialize(s, alphabet));\n return descriptor;\n }\n /**\n * Create a new TrajectoryDescriptor to describe a provided Trajectory according\n * to the provided alphabets.\n * @param trajectory Trajectory to be described\n * @param vector3Alphabet Vector3Alphabet to be used to tokenize the Trajectory\n * @param levenshteinAlphabet Levenshtein.Alphabet to be used as basis for comparison with other descriptors\n * @returns TrajectoryDescriptor describing provided Trajectory\n */\n static CreateFromTrajectory(trajectory, vector3Alphabet, levenshteinAlphabet) {\n return TrajectoryDescriptor.CreateFromTokenizationPyramid(TrajectoryDescriptor._GetTokenizationPyramid(trajectory, vector3Alphabet), levenshteinAlphabet);\n }\n /**\n * Create a new TrajectoryDescriptor from a pre-existing pyramid of tokens.\n * NOTE: This function exists to support an outdated serialization mechanism and should\n * be deleted if it is no longer useful.\n * @param pyramid tokenization pyramid\n * @param levenshteinAlphabet Levenshtein.Alphabet to be uses as basis for comparison with other descriptors\n * @returns TrajectoryDescriptor describing the Trajectory from which the pyramid was built\n */\n static CreateFromTokenizationPyramid(pyramid, levenshteinAlphabet) {\n const descriptor = new TrajectoryDescriptor();\n descriptor._sequences = pyramid.map(tokens => new Levenshtein.Sequence(tokens, levenshteinAlphabet));\n return descriptor;\n }\n constructor() {\n this._sequences = [];\n }\n /**\n * Create the tokenization pyramid for the provided Trajectory according to the given\n * Vector3Alphabet.\n * @param trajectory Trajectory to be tokenized\n * @param alphabet Vector3Alphabet containing tokens\n * @param targetResolution finest resolution of descriptor\n * @returns tokenization pyramid for Trajectory\n */\n static _GetTokenizationPyramid(trajectory, alphabet, targetResolution = TrajectoryDescriptor._FINEST_DESCRIPTOR_RESOLUTION) {\n const pyramid = [];\n for (let res = targetResolution; res > 4; res = Math.floor(res / 2)) {\n pyramid.push(trajectory.resampleAtTargetResolution(res).tokenize(alphabet.chars));\n }\n return pyramid;\n }\n /**\n * Calculate a distance metric between this TrajectoryDescriptor and another. This is\n * essentially a similarity score and does not directly represent Euclidean distance,\n * edit distance, or any other formal distance metric.\n * @param other TrajectoryDescriptor from which to determine distance\n * @returns distance, a nonnegative similarity score where larger values indicate dissimilarity\n */\n distance(other) {\n let totalDistance = 0;\n let weight;\n for (let idx = 0; idx < this._sequences.length; ++idx) {\n weight = Math.pow(2, idx);\n totalDistance += weight * this._sequences[idx].distance(other._sequences[idx]);\n }\n return totalDistance;\n }\n}\nTrajectoryDescriptor._FINEST_DESCRIPTOR_RESOLUTION = 32;\n/**\n * A set of TrajectoryDescriptors defined to be \"the same.\" This is essentially a helper\n * class to facilitate methods of Trajectory clustering.\n */\nclass TrajectoryClass {\n /**\n * Serialize to JSON.\n * @returns JSON serialization\n */\n serialize() {\n const jsonObject = {};\n jsonObject.descriptors = this._descriptors.map(desc => desc.serialize());\n jsonObject.centroidIdx = this._centroidIdx;\n jsonObject.averageDistance = this._averageDistance;\n return JSON.stringify(jsonObject);\n }\n /**\n * Deserialize from JSON string and Alphabet. This should be the same Alphabet\n * from which the descriptors were originally created, which must be serialized and\n * deserialized independently so that it can be passed in here.\n * @param json JSON string representation\n * @param alphabet Alphabet from which TrajectoryDescriptors were originally created\n * @returns deserialized TrajectoryDescriptor\n */\n static Deserialize(json, alphabet) {\n const jsonObject = JSON.parse(json);\n const described = new TrajectoryClass();\n described._descriptors = jsonObject.descriptors.map(s => TrajectoryDescriptor.Deserialize(s, alphabet));\n described._centroidIdx = jsonObject.centroidIdx;\n described._averageDistance = jsonObject.averageDistance;\n return described;\n }\n /**\n * Create a new DescribedTrajectory.\n * @param descriptors currently-known TrajectoryDescriptors, if any\n */\n constructor(descriptors = []) {\n this._descriptors = descriptors;\n this._centroidIdx = -1;\n this._averageDistance = 0;\n this._refreshDescription();\n }\n /**\n * Add a new TrajectoryDescriptor to the list of descriptors known to describe\n * this same DescribedTrajectory.\n * @param descriptor descriptor to be added\n */\n add(descriptor) {\n this._descriptors.push(descriptor);\n this._refreshDescription();\n }\n /**\n * Compute the cost, which is inversely related to the likelihood that the provided\n * TrajectoryDescriptor describes a Trajectory that is considered to be the same as\n * the class represented by this DescribedTrajectory.\n * @param descriptor the descriptor to be costed\n * @returns cost of the match, which is a nonnegative similarity metric where larger values indicate dissimilarity\n */\n getMatchCost(descriptor) {\n return descriptor.distance(this._descriptors[this._centroidIdx]) / this._averageDistance;\n }\n /**\n * Compute the minimum distance between the queried TrajectoryDescriptor and a\n * descriptor which is a member of this collection. This is an alternative way of\n * conceptualizing match cost from getMatchCost(), and it serves a different function.\n * @param descriptor the descriptor to find the minimum distance to\n * @returns minimum descriptor distance to a member descriptor of this DescribedTrajectory\n */\n getMatchMinimumDistance(descriptor) {\n return Math.min(...this._descriptors.map(desc => desc.distance(descriptor)));\n }\n /**\n * Refreshes the internal representation of this DescribedTrajectory.\n */\n _refreshDescription() {\n this._centroidIdx = -1;\n let sum;\n const distances = this._descriptors.map(a => {\n sum = 0;\n this._descriptors.forEach(b => {\n sum += a.distance(b);\n });\n return sum;\n });\n for (let idx = 0; idx < distances.length; ++idx) {\n if (this._centroidIdx < 0 || distances[idx] < distances[this._centroidIdx]) {\n this._centroidIdx = idx;\n }\n }\n this._averageDistance = 0;\n this._descriptors.forEach(desc => {\n this._averageDistance += desc.distance(this._descriptors[this._centroidIdx]);\n });\n if (this._descriptors.length > 0) {\n this._averageDistance = Math.max(this._averageDistance / this._descriptors.length, TrajectoryClass._MIN_AVERAGE_DISTANCE);\n }\n }\n}\nTrajectoryClass._MIN_AVERAGE_DISTANCE = 1;\n/**\n * Class representing a set of known, named trajectories to which Trajectories can be\n * added and using which Trajectories can be recognized.\n */\nexport class TrajectoryClassifier {\n /**\n * Serialize to JSON.\n * @returns JSON serialization\n */\n serialize() {\n const jsonObject = {};\n jsonObject.maximumAllowableMatchCost = this._maximumAllowableMatchCost;\n jsonObject.vector3Alphabet = this._vector3Alphabet.serialize();\n jsonObject.levenshteinAlphabet = this._levenshteinAlphabet.serialize();\n jsonObject.nameToDescribedTrajectory = [];\n this._nameToDescribedTrajectory.forEach((described, name) => {\n jsonObject.nameToDescribedTrajectory.push(name);\n jsonObject.nameToDescribedTrajectory.push(described.serialize());\n });\n return JSON.stringify(jsonObject);\n }\n /**\n * Deserialize from JSON.\n * @param json JSON serialization\n * @returns deserialized TrajectorySet\n */\n static Deserialize(json) {\n const jsonObject = JSON.parse(json);\n const classifier = new TrajectoryClassifier();\n classifier._maximumAllowableMatchCost = jsonObject.maximumAllowableMatchCost;\n classifier._vector3Alphabet = Vector3Alphabet.Deserialize(jsonObject.vector3Alphabet);\n classifier._levenshteinAlphabet = Levenshtein.Alphabet.Deserialize(jsonObject.levenshteinAlphabet);\n for (let idx = 0; idx < jsonObject.nameToDescribedTrajectory.length; idx += 2) {\n classifier._nameToDescribedTrajectory.set(jsonObject.nameToDescribedTrajectory[idx], TrajectoryClass.Deserialize(jsonObject.nameToDescribedTrajectory[idx + 1], classifier._levenshteinAlphabet));\n }\n return classifier;\n }\n /**\n * Initialize a new empty TrajectorySet with auto-generated Alphabets.\n * VERY naive, need to be generating these things from known\n * sets. Better version later, probably eliminating this one.\n * @returns auto-generated TrajectorySet\n */\n static Generate() {\n const vecs = Vector3Alphabet.Generate(64, 256, 0.1, 0.001, [Vector3.Forward()]);\n const charIdxs = new Array(vecs.chars.length);\n for (let idx = 0; idx < charIdxs.length; ++idx) {\n charIdxs[idx] = idx;\n }\n const alphabet = new Levenshtein.Alphabet(charIdxs, idx => idx === 0 ? 0 : 1, idx => idx === 0 ? 0 : 1, (a, b) => Math.min(1 - Vector3.Dot(vecs.chars[a], vecs.chars[b]), 1));\n const trajectorySet = new TrajectoryClassifier();\n trajectorySet._vector3Alphabet = vecs;\n trajectorySet._levenshteinAlphabet = alphabet;\n return trajectorySet;\n }\n constructor() {\n this._maximumAllowableMatchCost = 4;\n this._nameToDescribedTrajectory = new Map();\n }\n /**\n * Add a new Trajectory to the set with a given name.\n * @param trajectory new Trajectory to be added\n * @param classification name to which to add the Trajectory\n */\n addTrajectoryToClassification(trajectory, classification) {\n if (!this._nameToDescribedTrajectory.has(classification)) {\n this._nameToDescribedTrajectory.set(classification, new TrajectoryClass());\n }\n this._nameToDescribedTrajectory.get(classification).add(TrajectoryDescriptor.CreateFromTrajectory(trajectory, this._vector3Alphabet, this._levenshteinAlphabet));\n }\n /**\n * Remove a known named trajectory and all Trajectories associated with it.\n * @param classification name to remove\n * @returns whether anything was removed\n */\n deleteClassification(classification) {\n return this._nameToDescribedTrajectory.delete(classification);\n }\n /**\n * Attempt to recognize a Trajectory from among all the classifications\n * already known to the classifier.\n * @param trajectory Trajectory to be recognized\n * @returns classification of Trajectory if recognized, null otherwise\n */\n classifyTrajectory(trajectory) {\n const descriptor = TrajectoryDescriptor.CreateFromTrajectory(trajectory, this._vector3Alphabet, this._levenshteinAlphabet);\n const allowableMatches = [];\n this._nameToDescribedTrajectory.forEach((trajectoryClass, classification) => {\n if (trajectoryClass.getMatchCost(descriptor) < this._maximumAllowableMatchCost) {\n allowableMatches.push(classification);\n }\n });\n if (allowableMatches.length === 0) {\n return null;\n }\n let bestIdx = 0;\n let bestMatch = this._nameToDescribedTrajectory.get(allowableMatches[bestIdx]).getMatchMinimumDistance(descriptor);\n let match;\n for (let idx = 0; idx < allowableMatches.length; ++idx) {\n match = this._nameToDescribedTrajectory.get(allowableMatches[idx]).getMatchMinimumDistance(descriptor);\n if (match < bestMatch) {\n bestMatch = match;\n bestIdx = idx;\n }\n }\n return allowableMatches[bestIdx];\n }\n}","map":{"version":3,"names":["Matrix","Vector3","Levenshtein","Alphabet","serialize","jsonObject","characters","Array","_characterToIdx","size","forEach","v","k","_insertionCosts","_deletionCosts","_substitutionCosts","JSON","stringify","Deserialize","json","parse","alphabet","constructor","charToInsertionCost","charToDeletionCost","charsToSubstitutionCost","_charToInsertionCost","_charToDeletionCost","_charsToSubstitutionC","a","b","Map","length","c","outerIdx","set","innerIdx","getCharacterIdx","char","get","getInsertionCost","idx","getDeletionCost","getSubstitutionCost","idx1","idx2","min","Math","max","Sequence","_characters","sequence","_MAX_SEQUENCE_LENGTH","Error","_alphabet","map","distance","other","_Distance","aChars","bChars","aLength","bLength","costMatrix","_CostMatrix","aIdx","bIdx","_InsertionCost","_DeletionCost","_SubstitutionCost","Trajectory","trajectory","_points","pt","segmentLength","_segmentLength","getLength","add","point","numPoints","push","clone","getT","Distance","t","newPoint","scale","scaleAndAddToRef","resampleAtTargetResolution","targetResolution","resampled","tokenize","tokens","tokenization","segmentDir","_TransformSegmentDirToRef","_TokenizeSegment","priorVec","fromVec","toVec","result","DOT_PRODUCT_SAMPLE_REJECTION_THRESHOLD","subtractToRef","_ForwardDir","normalize","scaleToRef","_InverseFromVec","abs","Dot","CrossToRef","_UpDir","LookAtLHToRef","_LookMatrix","_FromToVec","TransformNormalToRef","segment","_BestMatch","_Score","_BestScore","Vector3Alphabet","Generate","alphabetSize","iterations","startingStepSize","endingStepSize","fixedValues","EPSILON","EPSILON_SQUARED","chars","random","copyFrom","stepSize","distSq","force","scratch","lerp","l","r","iteration","copyFromFloats","lengthSquared","scaleInPlace","addInPlace","TrajectoryDescriptor","_sequences","descriptor","s","CreateFromTrajectory","vector3Alphabet","levenshteinAlphabet","CreateFromTokenizationPyramid","_GetTokenizationPyramid","pyramid","_FINEST_DESCRIPTOR_RESOLUTION","res","floor","totalDistance","weight","pow","TrajectoryClass","descriptors","_descriptors","desc","centroidIdx","_centroidIdx","averageDistance","_averageDistance","described","_refreshDescription","getMatchCost","getMatchMinimumDistance","sum","distances","_MIN_AVERAGE_DISTANCE","TrajectoryClassifier","maximumAllowableMatchCost","_maximumAllowableMatchCost","_vector3Alphabet","_levenshteinAlphabet","nameToDescribedTrajectory","_nameToDescribedTrajectory","name","classifier","vecs","Forward","charIdxs","trajectorySet","addTrajectoryToClassification","classification","has","deleteClassification","delete","classifyTrajectory","allowableMatches","trajectoryClass","bestIdx","bestMatch","match"],"sources":["F:/workspace/202226701027/huinongbao-app/node_modules/@babylonjs/core/Misc/trajectoryClassifier.js"],"sourcesContent":["import { Matrix, Vector3 } from \"../Maths/math.vector.js\";\n// This implementation was based on the original MIT-licensed TRACE repository\n// from https://github.com/septagon/TRACE.\n/**\n * Generic implementation of Levenshtein distance.\n */\nvar Levenshtein;\n(function (Levenshtein) {\n /**\n * Alphabet from which to construct sequences to be compared using Levenshtein\n * distance.\n */\n class Alphabet {\n /**\n * Serialize the Alphabet to JSON string.\n * @returns JSON serialization\n */\n serialize() {\n const jsonObject = {};\n const characters = new Array(this._characterToIdx.size);\n this._characterToIdx.forEach((v, k) => {\n characters[v] = k;\n });\n jsonObject[\"characters\"] = characters;\n jsonObject[\"insertionCosts\"] = this._insertionCosts;\n jsonObject[\"deletionCosts\"] = this._deletionCosts;\n jsonObject[\"substitutionCosts\"] = this._substitutionCosts;\n return JSON.stringify(jsonObject);\n }\n /**\n * Parse an Alphabet from a JSON serialization.\n * @param json JSON string to deserialize\n * @returns deserialized Alphabet\n */\n static Deserialize(json) {\n const jsonObject = JSON.parse(json);\n const alphabet = new Alphabet(jsonObject[\"characters\"]);\n alphabet._insertionCosts = jsonObject[\"insertionCosts\"];\n alphabet._deletionCosts = jsonObject[\"deletionCosts\"];\n alphabet._substitutionCosts = jsonObject[\"substitutionCosts\"];\n return alphabet;\n }\n /**\n * Create a new Alphabet.\n * @param characters characters of the alphabet\n * @param charToInsertionCost function mapping characters to insertion costs\n * @param charToDeletionCost function mapping characters to deletion costs\n * @param charsToSubstitutionCost function mapping character pairs to substitution costs\n */\n constructor(characters, charToInsertionCost = null, charToDeletionCost = null, charsToSubstitutionCost = null) {\n charToInsertionCost = charToInsertionCost ?? (() => 1);\n charToDeletionCost = charToDeletionCost ?? (() => 1);\n charsToSubstitutionCost = charsToSubstitutionCost ?? ((a, b) => (a === b ? 0 : 1));\n this._characterToIdx = new Map();\n this._insertionCosts = new Array(characters.length);\n this._deletionCosts = new Array(characters.length);\n this._substitutionCosts = new Array(characters.length);\n let c;\n for (let outerIdx = 0; outerIdx < characters.length; ++outerIdx) {\n c = characters[outerIdx];\n this._characterToIdx.set(c, outerIdx);\n this._insertionCosts[outerIdx] = charToInsertionCost(c);\n this._deletionCosts[outerIdx] = charToDeletionCost(c);\n this._substitutionCosts[outerIdx] = new Array(characters.length);\n for (let innerIdx = outerIdx; innerIdx < characters.length; ++innerIdx) {\n this._substitutionCosts[outerIdx][innerIdx] = charsToSubstitutionCost(c, characters[innerIdx]);\n }\n }\n }\n /**\n * Get the index (internally-assigned number) for a character.\n * @param char character\n * @returns index\n */\n getCharacterIdx(char) {\n return this._characterToIdx.get(char);\n }\n /**\n * Get the insertion cost of a character from its index.\n * @param idx character index\n * @returns insertion cost\n */\n getInsertionCost(idx) {\n return this._insertionCosts[idx];\n }\n /**\n * Get the deletion cost of a character from its index.\n * @param idx character index\n * @returns deletion cost\n */\n getDeletionCost(idx) {\n return this._deletionCosts[idx];\n }\n /**\n * Gets the cost to substitute two characters. NOTE: this cost is\n * required to be bi-directional, meaning it cannot matter which of\n * the provided characters is being removed and which is being inserted.\n * @param idx1 the first character index\n * @param idx2 the second character index\n * @returns substitution cost\n */\n getSubstitutionCost(idx1, idx2) {\n const min = Math.min(idx1, idx2);\n const max = Math.max(idx1, idx2);\n return this._substitutionCosts[min][max];\n }\n }\n Levenshtein.Alphabet = Alphabet;\n /**\n * Character sequence intended to be compared against other Sequences created\n * with the same Alphabet in order to compute Levenshtein distance.\n */\n class Sequence {\n /**\n * Serialize to JSON string. JSON representation does NOT include the Alphabet\n * from which this Sequence was created; Alphabet must be independently\n * serialized.\n * @returns JSON string\n */\n serialize() {\n return JSON.stringify(this._characters);\n }\n /**\n * Deserialize from JSON string and Alphabet. This should be the same Alphabet\n * from which the Sequence was originally created, which must be serialized and\n * deserialized independently so that it can be passed in here.\n * @param json JSON string representation of Sequence\n * @param alphabet Alphabet from which Sequence was originally created\n * @returns Sequence\n */\n static Deserialize(json, alphabet) {\n const sequence = new Sequence([], alphabet);\n sequence._characters = JSON.parse(json);\n return sequence;\n }\n /**\n * Create a new Sequence.\n * @param characters characters in the new Sequence\n * @param alphabet Alphabet, which must include all used characters\n */\n constructor(characters, alphabet) {\n if (characters.length > Sequence._MAX_SEQUENCE_LENGTH) {\n throw new Error(\"Sequences longer than \" + Sequence._MAX_SEQUENCE_LENGTH + \" not supported.\");\n }\n this._alphabet = alphabet;\n this._characters = characters.map((c) => this._alphabet.getCharacterIdx(c));\n }\n /**\n * Get the distance between this Sequence and another.\n * @param other sequence to compare to\n * @returns Levenshtein distance\n */\n distance(other) {\n return Sequence._Distance(this, other);\n }\n /**\n * Compute the Levenshtein distance between two Sequences.\n * @param a first Sequence\n * @param b second Sequence\n * @returns Levenshtein distance\n */\n static _Distance(a, b) {\n const alphabet = a._alphabet;\n if (alphabet !== b._alphabet) {\n throw new Error(\"Cannot Levenshtein compare Sequences built from different alphabets.\");\n }\n const aChars = a._characters;\n const bChars = b._characters;\n const aLength = aChars.length;\n const bLength = bChars.length;\n const costMatrix = Sequence._CostMatrix;\n costMatrix[0][0] = 0;\n for (let idx = 0; idx < aLength; ++idx) {\n costMatrix[idx + 1][0] = costMatrix[idx][0] + alphabet.getInsertionCost(aChars[idx]);\n }\n for (let idx = 0; idx < bLength; ++idx) {\n costMatrix[0][idx + 1] = costMatrix[0][idx] + alphabet.getInsertionCost(bChars[idx]);\n }\n for (let aIdx = 0; aIdx < aLength; ++aIdx) {\n for (let bIdx = 0; bIdx < bLength; ++bIdx) {\n Sequence._InsertionCost = costMatrix[aIdx + 1][bIdx] + alphabet.getInsertionCost(bChars[bIdx]);\n Sequence._DeletionCost = costMatrix[aIdx][bIdx + 1] + alphabet.getDeletionCost(aChars[aIdx]);\n Sequence._SubstitutionCost = costMatrix[aIdx][bIdx] + alphabet.getSubstitutionCost(aChars[aIdx], bChars[bIdx]);\n costMatrix[aIdx + 1][bIdx + 1] = Math.min(Sequence._InsertionCost, Sequence._DeletionCost, Sequence._SubstitutionCost);\n }\n }\n return costMatrix[aLength][bLength];\n }\n }\n // Scratch values\n Sequence._MAX_SEQUENCE_LENGTH = 256;\n Sequence._CostMatrix = [...Array(Sequence._MAX_SEQUENCE_LENGTH + 1)].map(() => new Array(Sequence._MAX_SEQUENCE_LENGTH + 1));\n Levenshtein.Sequence = Sequence;\n})(Levenshtein || (Levenshtein = {}));\n/**\n * A 3D trajectory consisting of an order list of vectors describing a\n * path of motion through 3D space.\n */\nexport class Trajectory {\n /**\n * Serialize to JSON.\n * @returns serialized JSON string\n */\n serialize() {\n return JSON.stringify(this);\n }\n /**\n * Deserialize from JSON.\n * @param json serialized JSON string\n * @returns deserialized Trajectory\n */\n static Deserialize(json) {\n const jsonObject = JSON.parse(json);\n const trajectory = new Trajectory(jsonObject[\"_segmentLength\"]);\n trajectory._points = jsonObject[\"_points\"].map((pt) => {\n return new Vector3(pt[\"_x\"], pt[\"_y\"], pt[\"_z\"]);\n });\n return trajectory;\n }\n /**\n * Create a new empty Trajectory.\n * @param segmentLength radius of discretization for Trajectory points\n */\n constructor(segmentLength = 0.01) {\n this._points = [];\n this._segmentLength = segmentLength;\n }\n /**\n * Get the length of the Trajectory.\n * @returns length of the Trajectory\n */\n getLength() {\n return this._points.length * this._segmentLength;\n }\n /**\n * Append a new point to the Trajectory.\n * NOTE: This implementation has many allocations.\n * @param point point to append to the Trajectory\n */\n add(point) {\n let numPoints = this._points.length;\n if (numPoints === 0) {\n this._points.push(point.clone());\n }\n else {\n const getT = () => this._segmentLength / Vector3.Distance(this._points[numPoints - 1], point);\n for (let t = getT(); t <= 1.0; t = getT()) {\n const newPoint = this._points[numPoints - 1].scale(1.0 - t);\n point.scaleAndAddToRef(t, newPoint);\n this._points.push(newPoint);\n ++numPoints;\n }\n }\n }\n /**\n * Create a new Trajectory with a segment length chosen to make it\n * probable that the new Trajectory will have a specified number of\n * segments. This operation is imprecise.\n * @param targetResolution number of segments desired\n * @returns new Trajectory with approximately the requested number of segments\n */\n resampleAtTargetResolution(targetResolution) {\n const resampled = new Trajectory(this.getLength() / targetResolution);\n this._points.forEach((pt) => {\n resampled.add(pt);\n });\n return resampled;\n }\n /**\n * Convert Trajectory segments into tokenized representation. This\n * representation is an array of numbers where each nth number is the\n * index of the token which is most similar to the nth segment of the\n * Trajectory.\n * @param tokens list of vectors which serve as discrete tokens\n * @returns list of indices of most similar token per segment\n */\n tokenize(tokens) {\n const tokenization = [];\n const segmentDir = new Vector3();\n for (let idx = 2; idx < this._points.length; ++idx) {\n if (Trajectory._TransformSegmentDirToRef(this._points[idx - 2], this._points[idx - 1], this._points[idx], segmentDir)) {\n tokenization.push(Trajectory._TokenizeSegment(segmentDir, tokens));\n }\n }\n return tokenization;\n }\n /**\n * Transform the rotation (i.e., direction) of a segment to isolate\n * the relative transformation represented by the segment. This operation\n * may or may not succeed due to singularities in the equations that define\n * motion relativity in this context.\n * @param priorVec the origin of the prior segment\n * @param fromVec the origin of the current segment\n * @param toVec the destination of the current segment\n * @param result reference to output variable\n * @returns whether or not transformation was successful\n */\n static _TransformSegmentDirToRef(priorVec, fromVec, toVec, result) {\n const DOT_PRODUCT_SAMPLE_REJECTION_THRESHOLD = 0.98;\n fromVec.subtractToRef(priorVec, Trajectory._ForwardDir);\n Trajectory._ForwardDir.normalize();\n fromVec.scaleToRef(-1, Trajectory._InverseFromVec);\n Trajectory._InverseFromVec.normalize();\n if (Math.abs(Vector3.Dot(Trajectory._ForwardDir, Trajectory._InverseFromVec)) > DOT_PRODUCT_SAMPLE_REJECTION_THRESHOLD) {\n return false;\n }\n Vector3.CrossToRef(Trajectory._ForwardDir, Trajectory._InverseFromVec, Trajectory._UpDir);\n Trajectory._UpDir.normalize();\n Matrix.LookAtLHToRef(priorVec, fromVec, Trajectory._UpDir, Trajectory._LookMatrix);\n toVec.subtractToRef(fromVec, Trajectory._FromToVec);\n Trajectory._FromToVec.normalize();\n Vector3.TransformNormalToRef(Trajectory._FromToVec, Trajectory._LookMatrix, result);\n return true;\n }\n /**\n * Determine which token vector is most similar to the\n * segment vector.\n * @param segment segment vector\n * @param tokens token vector list\n * @returns index of the most similar token to the segment\n */\n static _TokenizeSegment(segment, tokens) {\n Trajectory._BestMatch = 0;\n Trajectory._Score = Vector3.Dot(segment, tokens[0]);\n Trajectory._BestScore = Trajectory._Score;\n for (let idx = 1; idx < tokens.length; ++idx) {\n Trajectory._Score = Vector3.Dot(segment, tokens[idx]);\n if (Trajectory._Score > Trajectory._BestScore) {\n Trajectory._BestMatch = idx;\n Trajectory._BestScore = Trajectory._Score;\n }\n }\n return Trajectory._BestMatch;\n }\n}\nTrajectory._ForwardDir = new Vector3();\nTrajectory._InverseFromVec = new Vector3();\nTrajectory._UpDir = new Vector3();\nTrajectory._FromToVec = new Vector3();\nTrajectory._LookMatrix = new Matrix();\n/**\n * Collection of vectors intended to be used as the basis of Trajectory\n * tokenization for Levenshtein distance comparison. Canonically, a\n * Vector3Alphabet will resemble a \"spikeball\" of vectors distributed\n * roughly evenly over the surface of the unit sphere.\n */\nclass Vector3Alphabet {\n /**\n * Helper method to create new \"spikeball\" Vector3Alphabets. Uses a naive\n * optimize-from-random strategy to space points around the unit sphere\n * surface as a simple alternative to really doing the math to tile the\n * sphere.\n * @param alphabetSize size of the desired alphabet\n * @param iterations number of iterations over which to optimize the \"spikeball\"\n * @param startingStepSize distance factor to move points in early optimization iterations\n * @param endingStepSize distance factor to move points in late optimization iterations\n * @param fixedValues alphabet \"characters\" that are required and cannot be moved by optimization\n * @returns a new randomly generated and optimized Vector3Alphabet of the specified size\n */\n static Generate(alphabetSize = 64, iterations = 256, startingStepSize = 0.1, endingStepSize = 0.001, fixedValues = []) {\n const EPSILON = 0.001;\n const EPSILON_SQUARED = EPSILON * EPSILON;\n const alphabet = new Vector3Alphabet(alphabetSize);\n for (let idx = 0; idx < alphabetSize; ++idx) {\n alphabet.chars[idx] = new Vector3(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);\n alphabet.chars[idx].normalize();\n }\n for (let idx = 0; idx < fixedValues.length; ++idx) {\n alphabet.chars[idx].copyFrom(fixedValues[idx]);\n }\n let stepSize;\n let distSq;\n const force = new Vector3();\n const scratch = new Vector3();\n const lerp = (l, r, t) => (1.0 - t) * l + t * r;\n for (let iteration = 0; iteration < iterations; ++iteration) {\n stepSize = lerp(startingStepSize, endingStepSize, iteration / (iterations - 1));\n for (let idx = fixedValues.length; idx < alphabet.chars.length; ++idx) {\n force.copyFromFloats(0, 0, 0);\n alphabet.chars.forEach((pt) => {\n alphabet.chars[idx].subtractToRef(pt, scratch);\n distSq = scratch.lengthSquared();\n if (distSq > EPSILON_SQUARED) {\n scratch.scaleAndAddToRef(1 / (scratch.lengthSquared() * distSq), force);\n }\n });\n force.scaleInPlace(stepSize);\n alphabet.chars[idx].addInPlace(force);\n alphabet.chars[idx].normalize();\n }\n }\n return alphabet;\n }\n /**\n * Serialize to JSON.\n * @returns JSON serialization\n */\n serialize() {\n return JSON.stringify(this.chars);\n }\n /**\n * Deserialize from JSON.\n * @param json JSON serialization\n * @returns deserialized Vector3Alphabet\n */\n static Deserialize(json) {\n const jsonObject = JSON.parse(json);\n const alphabet = new Vector3Alphabet(jsonObject.length);\n for (let idx = 0; idx < jsonObject.length; ++idx) {\n alphabet.chars[idx] = new Vector3(jsonObject[idx][\"_x\"], jsonObject[idx][\"_y\"], jsonObject[idx][\"_z\"]);\n }\n return alphabet;\n }\n constructor(size) {\n this.chars = new Array(size);\n }\n}\n/**\n * Class which formalizes the manner in which a Vector3Alphabet is used to tokenize and\n * describe a Trajectory. This class houses the functionality which determines what\n * attributes of Trajectories are and are not considered important, such as scale.\n */\nclass TrajectoryDescriptor {\n /**\n * Serialize to JSON.\n * @returns JSON serialization\n */\n serialize() {\n return JSON.stringify(this._sequences.map((sequence) => sequence.serialize()));\n }\n /**\n * Deserialize from JSON string and Alphabet. This should be the same Alphabet\n * from which the descriptor was originally created, which must be serialized and\n * deserialized independently so that it can be passed in here.\n * @param json JSON serialization\n * @param alphabet Alphabet from which descriptor was originally created\n * @returns deserialized TrajectoryDescriptor\n */\n static Deserialize(json, alphabet) {\n const descriptor = new TrajectoryDescriptor();\n descriptor._sequences = JSON.parse(json).map((s) => Levenshtein.Sequence.Deserialize(s, alphabet));\n return descriptor;\n }\n /**\n * Create a new TrajectoryDescriptor to describe a provided Trajectory according\n * to the provided alphabets.\n * @param trajectory Trajectory to be described\n * @param vector3Alphabet Vector3Alphabet to be used to tokenize the Trajectory\n * @param levenshteinAlphabet Levenshtein.Alphabet to be used as basis for comparison with other descriptors\n * @returns TrajectoryDescriptor describing provided Trajectory\n */\n static CreateFromTrajectory(trajectory, vector3Alphabet, levenshteinAlphabet) {\n return TrajectoryDescriptor.CreateFromTokenizationPyramid(TrajectoryDescriptor._GetTokenizationPyramid(trajectory, vector3Alphabet), levenshteinAlphabet);\n }\n /**\n * Create a new TrajectoryDescriptor from a pre-existing pyramid of tokens.\n * NOTE: This function exists to support an outdated serialization mechanism and should\n * be deleted if it is no longer useful.\n * @param pyramid tokenization pyramid\n * @param levenshteinAlphabet Levenshtein.Alphabet to be uses as basis for comparison with other descriptors\n * @returns TrajectoryDescriptor describing the Trajectory from which the pyramid was built\n */\n static CreateFromTokenizationPyramid(pyramid, levenshteinAlphabet) {\n const descriptor = new TrajectoryDescriptor();\n descriptor._sequences = pyramid.map((tokens) => new Levenshtein.Sequence(tokens, levenshteinAlphabet));\n return descriptor;\n }\n constructor() {\n this._sequences = [];\n }\n /**\n * Create the tokenization pyramid for the provided Trajectory according to the given\n * Vector3Alphabet.\n * @param trajectory Trajectory to be tokenized\n * @param alphabet Vector3Alphabet containing tokens\n * @param targetResolution finest resolution of descriptor\n * @returns tokenization pyramid for Trajectory\n */\n static _GetTokenizationPyramid(trajectory, alphabet, targetResolution = TrajectoryDescriptor._FINEST_DESCRIPTOR_RESOLUTION) {\n const pyramid = [];\n for (let res = targetResolution; res > 4; res = Math.floor(res / 2)) {\n pyramid.push(trajectory.resampleAtTargetResolution(res).tokenize(alphabet.chars));\n }\n return pyramid;\n }\n /**\n * Calculate a distance metric between this TrajectoryDescriptor and another. This is\n * essentially a similarity score and does not directly represent Euclidean distance,\n * edit distance, or any other formal distance metric.\n * @param other TrajectoryDescriptor from which to determine distance\n * @returns distance, a nonnegative similarity score where larger values indicate dissimilarity\n */\n distance(other) {\n let totalDistance = 0;\n let weight;\n for (let idx = 0; idx < this._sequences.length; ++idx) {\n weight = Math.pow(2, idx);\n totalDistance += weight * this._sequences[idx].distance(other._sequences[idx]);\n }\n return totalDistance;\n }\n}\nTrajectoryDescriptor._FINEST_DESCRIPTOR_RESOLUTION = 32;\n/**\n * A set of TrajectoryDescriptors defined to be \"the same.\" This is essentially a helper\n * class to facilitate methods of Trajectory clustering.\n */\nclass TrajectoryClass {\n /**\n * Serialize to JSON.\n * @returns JSON serialization\n */\n serialize() {\n const jsonObject = {};\n jsonObject.descriptors = this._descriptors.map((desc) => desc.serialize());\n jsonObject.centroidIdx = this._centroidIdx;\n jsonObject.averageDistance = this._averageDistance;\n return JSON.stringify(jsonObject);\n }\n /**\n * Deserialize from JSON string and Alphabet. This should be the same Alphabet\n * from which the descriptors were originally created, which must be serialized and\n * deserialized independently so that it can be passed in here.\n * @param json JSON string representation\n * @param alphabet Alphabet from which TrajectoryDescriptors were originally created\n * @returns deserialized TrajectoryDescriptor\n */\n static Deserialize(json, alphabet) {\n const jsonObject = JSON.parse(json);\n const described = new TrajectoryClass();\n described._descriptors = jsonObject.descriptors.map((s) => TrajectoryDescriptor.Deserialize(s, alphabet));\n described._centroidIdx = jsonObject.centroidIdx;\n described._averageDistance = jsonObject.averageDistance;\n return described;\n }\n /**\n * Create a new DescribedTrajectory.\n * @param descriptors currently-known TrajectoryDescriptors, if any\n */\n constructor(descriptors = []) {\n this._descriptors = descriptors;\n this._centroidIdx = -1;\n this._averageDistance = 0;\n this._refreshDescription();\n }\n /**\n * Add a new TrajectoryDescriptor to the list of descriptors known to describe\n * this same DescribedTrajectory.\n * @param descriptor descriptor to be added\n */\n add(descriptor) {\n this._descriptors.push(descriptor);\n this._refreshDescription();\n }\n /**\n * Compute the cost, which is inversely related to the likelihood that the provided\n * TrajectoryDescriptor describes a Trajectory that is considered to be the same as\n * the class represented by this DescribedTrajectory.\n * @param descriptor the descriptor to be costed\n * @returns cost of the match, which is a nonnegative similarity metric where larger values indicate dissimilarity\n */\n getMatchCost(descriptor) {\n return descriptor.distance(this._descriptors[this._centroidIdx]) / this._averageDistance;\n }\n /**\n * Compute the minimum distance between the queried TrajectoryDescriptor and a\n * descriptor which is a member of this collection. This is an alternative way of\n * conceptualizing match cost from getMatchCost(), and it serves a different function.\n * @param descriptor the descriptor to find the minimum distance to\n * @returns minimum descriptor distance to a member descriptor of this DescribedTrajectory\n */\n getMatchMinimumDistance(descriptor) {\n return Math.min(...this._descriptors.map((desc) => desc.distance(descriptor)));\n }\n /**\n * Refreshes the internal representation of this DescribedTrajectory.\n */\n _refreshDescription() {\n this._centroidIdx = -1;\n let sum;\n const distances = this._descriptors.map((a) => {\n sum = 0;\n this._descriptors.forEach((b) => {\n sum += a.distance(b);\n });\n return sum;\n });\n for (let idx = 0; idx < distances.length; ++idx) {\n if (this._centroidIdx < 0 || distances[idx] < distances[this._centroidIdx]) {\n this._centroidIdx = idx;\n }\n }\n this._averageDistance = 0;\n this._descriptors.forEach((desc) => {\n this._averageDistance += desc.distance(this._descriptors[this._centroidIdx]);\n });\n if (this._descriptors.length > 0) {\n this._averageDistance = Math.max(this._averageDistance / this._descriptors.length, TrajectoryClass._MIN_AVERAGE_DISTANCE);\n }\n }\n}\nTrajectoryClass._MIN_AVERAGE_DISTANCE = 1;\n/**\n * Class representing a set of known, named trajectories to which Trajectories can be\n * added and using which Trajectories can be recognized.\n */\nexport class TrajectoryClassifier {\n /**\n * Serialize to JSON.\n * @returns JSON serialization\n */\n serialize() {\n const jsonObject = {};\n jsonObject.maximumAllowableMatchCost = this._maximumAllowableMatchCost;\n jsonObject.vector3Alphabet = this._vector3Alphabet.serialize();\n jsonObject.levenshteinAlphabet = this._levenshteinAlphabet.serialize();\n jsonObject.nameToDescribedTrajectory = [];\n this._nameToDescribedTrajectory.forEach((described, name) => {\n jsonObject.nameToDescribedTrajectory.push(name);\n jsonObject.nameToDescribedTrajectory.push(described.serialize());\n });\n return JSON.stringify(jsonObject);\n }\n /**\n * Deserialize from JSON.\n * @param json JSON serialization\n * @returns deserialized TrajectorySet\n */\n static Deserialize(json) {\n const jsonObject = JSON.parse(json);\n const classifier = new TrajectoryClassifier();\n classifier._maximumAllowableMatchCost = jsonObject.maximumAllowableMatchCost;\n classifier._vector3Alphabet = Vector3Alphabet.Deserialize(jsonObject.vector3Alphabet);\n classifier._levenshteinAlphabet = Levenshtein.Alphabet.Deserialize(jsonObject.levenshteinAlphabet);\n for (let idx = 0; idx < jsonObject.nameToDescribedTrajectory.length; idx += 2) {\n classifier._nameToDescribedTrajectory.set(jsonObject.nameToDescribedTrajectory[idx], TrajectoryClass.Deserialize(jsonObject.nameToDescribedTrajectory[idx + 1], classifier._levenshteinAlphabet));\n }\n return classifier;\n }\n /**\n * Initialize a new empty TrajectorySet with auto-generated Alphabets.\n * VERY naive, need to be generating these things from known\n * sets. Better version later, probably eliminating this one.\n * @returns auto-generated TrajectorySet\n */\n static Generate() {\n const vecs = Vector3Alphabet.Generate(64, 256, 0.1, 0.001, [Vector3.Forward()]);\n const charIdxs = new Array(vecs.chars.length);\n for (let idx = 0; idx < charIdxs.length; ++idx) {\n charIdxs[idx] = idx;\n }\n const alphabet = new Levenshtein.Alphabet(charIdxs, (idx) => (idx === 0 ? 0 : 1), (idx) => (idx === 0 ? 0 : 1), (a, b) => Math.min(1 - Vector3.Dot(vecs.chars[a], vecs.chars[b]), 1));\n const trajectorySet = new TrajectoryClassifier();\n trajectorySet._vector3Alphabet = vecs;\n trajectorySet._levenshteinAlphabet = alphabet;\n return trajectorySet;\n }\n constructor() {\n this._maximumAllowableMatchCost = 4;\n this._nameToDescribedTrajectory = new Map();\n }\n /**\n * Add a new Trajectory to the set with a given name.\n * @param trajectory new Trajectory to be added\n * @param classification name to which to add the Trajectory\n */\n addTrajectoryToClassification(trajectory, classification) {\n if (!this._nameToDescribedTrajectory.has(classification)) {\n this._nameToDescribedTrajectory.set(classification, new TrajectoryClass());\n }\n this._nameToDescribedTrajectory.get(classification).add(TrajectoryDescriptor.CreateFromTrajectory(trajectory, this._vector3Alphabet, this._levenshteinAlphabet));\n }\n /**\n * Remove a known named trajectory and all Trajectories associated with it.\n * @param classification name to remove\n * @returns whether anything was removed\n */\n deleteClassification(classification) {\n return this._nameToDescribedTrajectory.delete(classification);\n }\n /**\n * Attempt to recognize a Trajectory from among all the classifications\n * already known to the classifier.\n * @param trajectory Trajectory to be recognized\n * @returns classification of Trajectory if recognized, null otherwise\n */\n classifyTrajectory(trajectory) {\n const descriptor = TrajectoryDescriptor.CreateFromTrajectory(trajectory, this._vector3Alphabet, this._levenshteinAlphabet);\n const allowableMatches = [];\n this._nameToDescribedTrajectory.forEach((trajectoryClass, classification) => {\n if (trajectoryClass.getMatchCost(descriptor) < this._maximumAllowableMatchCost) {\n allowableMatches.push(classification);\n }\n });\n if (allowableMatches.length === 0) {\n return null;\n }\n let bestIdx = 0;\n let bestMatch = this._nameToDescribedTrajectory.get(allowableMatches[bestIdx]).getMatchMinimumDistance(descriptor);\n let match;\n for (let idx = 0; idx < allowableMatches.length; ++idx) {\n match = this._nameToDescribedTrajectory.get(allowableMatches[idx]).getMatchMinimumDistance(descriptor);\n if (match < bestMatch) {\n bestMatch = match;\n bestIdx = idx;\n }\n }\n return allowableMatches[bestIdx];\n }\n}\n"],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}