Compare commits

..

No commits in common. "038dd9f4a8e47f183eb46430fe50538eaaf94176" and "bc35b18da06464a924f75b101621c0686be7d962" have entirely different histories.

6 changed files with 22 additions and 45 deletions

View file

@ -301,7 +301,7 @@ Canvas {
} else { } else {
for(var x = 1; x < drawMaxX; x += 1) { for(var x = 1; x < drawMaxX; x += 1) {
var drawX = x*xaxisstep1 var drawX = x*xaxisstep1
var txtX = xaxisstepExpr.simplify(x).replace(/^\((.+)\)$/, '$1') var txtX = xaxisstepExpr.simplify(x)
var textSize = measureText(ctx, txtX, 6).height var textSize = measureText(ctx, txtX, 6).height
drawVisibleText(ctx, txtX, x2px(drawX)-4, axisxpx+textsize/2+textSize) drawVisibleText(ctx, txtX, x2px(drawX)-4, axisxpx+textsize/2+textSize)
drawVisibleText(ctx, '-'+txtX, x2px(-drawX)-4, axisxpx+textsize/2+textSize) drawVisibleText(ctx, '-'+txtX, x2px(-drawX)-4, axisxpx+textsize/2+textSize)
@ -311,7 +311,7 @@ Canvas {
if(showygrad) { if(showygrad) {
for(var y = 0; y < drawMaxY; y += 1) { for(var y = 0; y < drawMaxY; y += 1) {
var drawY = y*yaxisstep1 var drawY = y*yaxisstep1
var txtY = yaxisstepExpr.simplify(y).replace(/^\((.+)\)$/, '$1') var txtY = yaxisstepExpr.simplify(y)
var textSize = ctx.measureText(txtY).width var textSize = ctx.measureText(txtY).width
drawVisibleText(ctx, txtY, axisypx-6-textSize, y2px(drawY)+4+(10*(y==0))) drawVisibleText(ctx, txtY, axisypx-6-textSize, y2px(drawY)+4+(10*(y==0)))
if(y != 0) if(y != 0)

View file

@ -521,7 +521,7 @@ Expression.prototype.substitute = function (variable, expr) {
}; };
Expression.prototype.evaluate = function (values) { Expression.prototype.evaluate = function (values) {
values = Object.assign({}, values, this.parser.consts) values = values || {};
return evaluate(this.tokens, this, values); return evaluate(this.tokens, this, values);
}; };
@ -541,9 +541,8 @@ Expression.prototype.variables = function (options) {
var vars = []; var vars = [];
getSymbols(this.tokens, vars, options); getSymbols(this.tokens, vars, options);
var functions = this.functions; var functions = this.functions;
var consts = this.parser.consts
return vars.filter(function (name) { return vars.filter(function (name) {
return !(name in functions) && !(name in consts); return !(name in functions);
}); });
}; };
@ -581,7 +580,7 @@ function TokenStream(parser, expression) {
this.unaryOps = parser.unaryOps; this.unaryOps = parser.unaryOps;
this.binaryOps = parser.binaryOps; this.binaryOps = parser.binaryOps;
this.ternaryOps = parser.ternaryOps; this.ternaryOps = parser.ternaryOps;
this.builtinConsts = parser.builtinConsts; this.consts = parser.consts;
this.expression = expression; this.expression = expression;
this.savedPosition = 0; this.savedPosition = 0;
this.savedCurrent = null; this.savedCurrent = null;
@ -701,8 +700,8 @@ TokenStream.prototype.isConst = function () {
} }
if (i > startPos) { if (i > startPos) {
var str = this.expression.substring(startPos, i); var str = this.expression.substring(startPos, i);
if (str in this.builtinConsts) { if (str in this.consts) {
this.current = this.newToken(TNUMBER, this.builtinConsts[str]); this.current = this.newToken(TNUMBER, this.consts[str]);
this.pos += str.length; this.pos += str.length;
return true; return true;
} }
@ -1793,12 +1792,12 @@ class Parser {
join: arrayJoin join: arrayJoin
}; };
// These constants will automatically be replaced the MOMENT they are parsed. this.consts = {
// (Original consts from the parser) E: Math.E,
this.builtinConsts = {}; PI: Math.PI,
// These consts will only be replaced when the expression is evaluated. 'true': true,
this.consts = {} 'false': false
};
} }
parse(expr) { parse(expr) {

View file

@ -26,17 +26,13 @@ const DERIVATION_PRECISION = 0.1
var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually
"pi": Math.PI, "pi": Math.PI,
"PI": Math.PI,
"π": Math.PI, "π": Math.PI,
"inf": Infinity, "inf": Infinity,
"infinity": Infinity, "infinity": Infinity,
"Infinity": Infinity, "Infinity": Infinity,
"∞": Infinity, "∞": Infinity,
"e": Math.E, "e": Math.E,
"E": Math.E, "E": Math.E
"true": true,
"false": false
} }
var currentVars = {} var currentVars = {}
@ -58,4 +54,3 @@ parser.functions.derivative = function(f, variable, x) {
f = parser.parse(f).toJSFunction(variable, currentVars) f = parser.parse(f).toJSFunction(variable, currentVars)
return (f(x+DERIVATION_PRECISION/2)-f(x-DERIVATION_PRECISION/2))/DERIVATION_PRECISION return (f(x+DERIVATION_PRECISION/2)-f(x-DERIVATION_PRECISION/2))/DERIVATION_PRECISION
} }

View file

@ -27,8 +27,8 @@
*/ */
class Expression { class Expression {
constructor(expr) { constructor(expr) {
this.expr = Utils.exponentsToExpression(expr) this.expr = expr
this.calc = C.parser.parse(this.expr).simplify() this.calc = C.parser.parse(expr).simplify()
this.cached = this.isConstant() this.cached = this.isConstant()
this.cachedValue = this.cached && this.allRequirementsFullfilled() ? this.calc.evaluate(C.currentObjectsByName) : null this.cachedValue = this.cached && this.allRequirementsFullfilled() ? this.calc.evaluate(C.currentObjectsByName) : null
this.latexMarkup = Latex.expression(this.calc.tokens) this.latexMarkup = Latex.expression(this.calc.tokens)
@ -68,7 +68,6 @@ class Expression {
simplify(x) { simplify(x) {
var expr = this.calc.substitute('x', x).simplify() var expr = this.calc.substitute('x', x).simplify()
print(this.expr, this.calc.substitute('x', x), expr)
if(expr.evaluate() == 0) return '0' if(expr.evaluate() == 0) return '0'
var str = Utils.makeExpressionReadable(expr.toString()); var str = Utils.makeExpressionReadable(expr.toString());
if(str != undefined && str.match(/^\d*\.\d+$/)) { if(str != undefined && str.match(/^\d*\.\d+$/)) {

View file

@ -62,11 +62,6 @@ var powerpos = {
"z": "ᶻ" "z": "ᶻ"
} }
var exponents = [
"⁰","¹","²","³","⁴","⁵","⁶","⁷","⁸","⁹"
]
var exponentReg = new RegExp('(['+exponents.join('')+']+)', 'g')
var indicepos = { var indicepos = {
"-": "₋", "-": "₋",
"+": "₊", "+": "₊",
@ -256,14 +251,14 @@ function makeExpressionReadable(str) {
// Other // Other
[/ \* /g, '×'], [/ \* /g, '×'],
[/ \^ /g, '^'], [/ \^ /g, '^'],
[/\^\(([\d\w+-]+)\)/g, function(match, p1) { return textsup(p1) }], [/\^\(([^\^]+)\)/g, function(match, p1) { return textsup(p1) }],
[/\^([\d\w+-]+)/g, function(match, p1) { return textsup(p1) }], [/\^([^ "]+)/g, function(match, p1) { return textsup(p1) }],
[/_\(([\d\w+-]+)\)/g, function(match, p1) { return textsub(p1) }], [/_\(([^_]+)\)/g, function(match, p1) { return textsub(p1) }],
[/_([\d\w+-]+)/g, function(match, p1) { return textsub(p1) }], [/_([^ "]+)/g, function(match, p1) { return textsub(p1) }],
[/\[([^\[\]]+)\]/g, function(match, p1) { return textsub(p1) }], [/\[([^\[\]]+)\]/g, function(match, p1) { return textsub(p1) }],
[/(\d|\))×/g, '$1'], [/(\d|\))×/g, '$1'],
//[/×(\d|\()/g, '$1'], //[/×(\d|\()/g, '$1'],
[/([^a-z])\(([^)(+.\/-]+)\)/g, "$1×$2"], [/[^a-z]\(([^)(+.\/-]+)\)/g, "$1"],
[/integral\((.+),\s?(.+),\s?("|')(.+)("|'),\s?("|')(.+)("|')\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { [/integral\((.+),\s?(.+),\s?("|')(.+)("|'),\s?("|')(.+)("|')\)/g, function(match, a, b, p1, body, p2, p3, by, p4) {
if(a.length < b.length) { if(a.length < b.length) {
return `${textsub(a)}${textsup(b)} ${body} d${by}` return `${textsub(a)}${textsup(b)} ${body} d${by}`
@ -356,14 +351,3 @@ function getRandomColor() {
function escapeHTML(str) { function escapeHTML(str) {
return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;') ; return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;') ;
} }
/**
* Parses exponents and replaces them with expression values
* @param {string} expression - The expression to replace in.
* @return {string} The parsed expression
*/
function exponentsToExpression(expression) {
return expression.replace(exponentReg, (m, exp) => '^' + exp.split('').map((x) => exponents.indexOf(x)).join(''))
}

View file

@ -79,4 +79,4 @@ Language files translations located at LogarithmPlotter/i18n are licensed under
LogarithmPlotter includes [expr-eval](https://github.com/silentmatt/expr-eval) a port of [ndef.parser](https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html) by Raphael Graf &lt;r@undefined.ch&gt;, ported to javascript by Matthew Crumley &lt;email@matthewcrumley.com&gt; (http://silentmatt.com/), and then to QMLJS by Ad5001. LogarithmPlotter includes [expr-eval](https://github.com/silentmatt/expr-eval) a port of [ndef.parser](https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html) by Raphael Graf &lt;r@undefined.ch&gt;, ported to javascript by Matthew Crumley &lt;email@matthewcrumley.com&gt; (http://silentmatt.com/), and then to QMLJS by Ad5001.
The specific file (LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js) is licensed under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt). The code is licensed under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt).