Skip to content

Instantly share code, notes, and snippets.

@jared-hughes
Last active March 27, 2021 21:38
Show Gist options
  • Save jared-hughes/3c62c59ab3c010a569a0c61066786b2f to your computer and use it in GitHub Desktop.
Save jared-hughes/3c62c59ab3c010a569a0c61066786b2f to your computer and use it in GitHub Desktop.
Desmos Simulation Warp
// ==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