Last active
March 27, 2021 21:38
-
-
Save jared-hughes/3c62c59ab3c010a569a0c61066786b2f to your computer and use it in GitHub Desktop.
Desmos Simulation Warp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Desmos Simulation Warp | |
// @namespace http://github.com/jared-hughes | |
// @version 0.1 | |
// @author fireflame241 | |
// @description Execute a simulation at warp speed | |
// @grant none | |
// @match https://*.desmos.com/calculator* | |
// ==/UserScript== | |
/*jshint esversion: 6 */ | |
/** | |
* Limitations: Only applies to simulations of the form x_i ← f_i(x_j) where f_i:R→R | |
* i.e. single-variable functions of numbers that return a number, applied only to | |
* variables that are changed in the simualation. | |
* | |
* Example graph: https://www.desmos.com/calculator/vkwa9dovn5. Try `warp(0, 1000)` in the console | |
* (0 is the index of the first simulation). | |
*/ | |
const rModelList = window.require('graphing-calc/models/list') | |
function getItemModelByIdentifier(name) { | |
return rModelList.getItemsByIdentifier(window.Calc.controller.listModel, name)[0] | |
} | |
function getValue (expr) { | |
return new Promise((resolve, reject) => { | |
// const helper = window.Calc.HelperExpression({latex: expr}) | |
// helper.observe('numericValue', () => resolve(helper.numericValue)) | |
resolve(getItemModelByIdentifier(expr).formula.constant_value) | |
}) | |
} | |
const variableRegex = '(\\w+(?:_\\{\\w+\\})?)' | |
const functionArgsRegex = `\\\\left\\((${variableRegex})\\\\right\\)` | |
const functionCallRegex = variableRegex + functionArgsRegex | |
window.warp = function warp (simulationIndex, numTicks) { | |
const exprs = window.Calc.getState().expressions.list | |
const rules = exprs[simulationIndex].clickableInfo.rules; | |
Promise.all(rules.map(e => getValue(e.assignment))).then(valuesList => { | |
let values = Object.fromEntries(rules.map((e,i) => [e.assignment, valuesList[i]])) | |
rules.forEach(e => { | |
const match = e.expression.match(new RegExp(functionCallRegex)) | |
e.arg = match[2] | |
const funcName = match[1] | |
const funcID = exprs.find(({latex}) => latex && latex.match(new RegExp(funcName + functionArgsRegex))).id | |
// to access compiled function from Calc.controller.grapher.graphSketches, the function must | |
// take a single variable as argument. | |
e.fn = window.Calc.controller.grapher.graphSketches[funcID].branches[0].compiled.fn | |
}) | |
const apply = ({assignment, fn, arg}) => [assignment,fn(values[arg])] | |
for (let i=0; i<numTicks; i++) { | |
const newValues = Object.fromEntries(rules.map(apply)) | |
values = newValues | |
} | |
console.log(values) | |
Object.entries(values).forEach(([assignment, value]) => { | |
window.Calc.setExpression({ | |
id: getItemModelByIdentifier(assignment).id, | |
latex: `${assignment}=${value}` | |
}) | |
}) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment