From 370402f30370e49ae99719ddf53519b2a2cd0073 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 20 Sep 2024 19:02:10 +0200 Subject: [PATCH] Fixing a particularly smelly bug in regard to X Cursor targetting causing issues with certain functions. --- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 4 +-- .../LogarithmPlotter/js/math/domain.mjs | 7 +++++ .../LogarithmPlotter/js/math/expression.mjs | 31 ++++++++++--------- .../LogarithmPlotter/js/math/sequence.mjs | 7 ++--- .../LogarithmPlotter/js/objs/common.mjs | 2 +- .../LogarithmPlotter/js/objs/phasebode.mjs | 2 +- .../LogarithmPlotter/js/objs/repartition.mjs | 2 +- .../LogarithmPlotter/js/objs/xcursor.mjs | 2 +- .../eu/ad5001/LogarithmPlotter/js/utils.mjs | 2 -- 9 files changed, 32 insertions(+), 27 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index 1e85788..d214be3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -291,7 +291,7 @@ class CanvasAPI extends Module { } else { for(let x = 1; x < this.axesSteps.x.maxDraw; x += 1) { let drawX = x*this.axesSteps.x.value - let txtX = this.axesSteps.x.expression.simplify(x).replace(/^\((.+)\)$/, '$1') + let txtX = this.axesSteps.x.expression.simplify(x).toString().replace(/^\((.+)\)$/, '$1') let textHeight = this.measureText(txtX).height this.drawVisibleText(txtX, this.x2px(drawX)-4, axisxpx+this.textsize/2+textHeight) this.drawVisibleText('-'+txtX, this.x2px(-drawX)-4, axisxpx+this.textsize/2+textHeight) @@ -301,7 +301,7 @@ class CanvasAPI extends Module { if(this.showygrad) { for(let y = 0; y < this.axesSteps.y.maxDraw; y += 1) { let drawY = y*this.axesSteps.y.value - let txtY = this.axesSteps.y.expression.simplify(y).replace(/^\((.+)\)$/, '$1') + let txtY = this.axesSteps.y.expression.simplify(y).toString().replace(/^\((.+)\)$/, '$1') textWidth = this._ctx.measureText(txtY).width this.drawVisibleText(txtY, axisypx-6-textWidth, this.y2px(drawY)+4+(10*(y===0))) if(y !== 0) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs index e2606c4..22b0154 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs @@ -199,6 +199,7 @@ export class Range extends Domain { } includes(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) return ((this.openBegin && x > this.begin.execute()) || (!this.openBegin && x >= this.begin.execute())) && ((this.openEnd && x < this.end.execute()) || (!this.openEnd && x <= this.end.execute())) @@ -257,16 +258,19 @@ export class SpecialDomain extends Domain { } includes(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) return this.isValid(x) } next(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) return this.nextValue(x) } previous(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) return this.prevValue(x) } @@ -315,6 +319,7 @@ export class DomainSet extends SpecialDomain { } includes(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) for(let value of this.values) if(x === value.execute()) return true @@ -322,6 +327,7 @@ export class DomainSet extends SpecialDomain { } next(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) if(x < this.executedValues[0]) return this.executedValues[0] for(let i = 1; i < this.values.length; i++) { @@ -333,6 +339,7 @@ export class DomainSet extends SpecialDomain { } previous(x) { + if(x instanceof Expression) x = x.execute() if(typeof x == 'string') x = executeExpression(x) if(x > this.executedValues[this.executedValues.length-1]) return this.executedValues[this.executedValues.length-1] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index 66cd044..3a0ebb4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -29,8 +29,14 @@ export class Expression { throw new Error('Expression parser not initialized.') if(!Modules.Objects) throw new Error('Objects API not initialized.') - this.expr = Utils.exponentsToExpression(expr) - this.calc = Modules.ExprParser.parse(this.expr).simplify() + if(typeof expr === "string") { + this.expr = Utils.exponentsToExpression(expr) + this.calc = Modules.ExprParser.parse(this.expr).simplify() + } else { + // Passed an expression here directly. + this.calc = expr.simplify() + this.expr = expr.toString() + } this.cached = this.isConstant() this.cachedValue = null if(this.cached && this.allRequirementsFullfilled()) @@ -72,19 +78,8 @@ export class Expression { simplify(x) { let expr = this.calc.substitute('x', x).simplify() - if(expr.evaluate() === 0) return '0' - let str = Utils.makeExpressionReadable(expr.toString()); - if(str !== undefined && str.match(/^\d*\.\d+$/)) { - if(str.split('.')[1].split('0').length > 7) { - // Likely rounding error - str = parseFloat(str.substring(0, str.length-1)).toString(); - } - } - return str - } - - duplicate() { - return new Expression(this.toEditableString()) + if(expr.evaluate() === 0) expr = '0' + return new Expression(expr) } toEditableString() { @@ -93,6 +88,12 @@ export class Expression { toString(forceSign=false) { let str = Utils.makeExpressionReadable(this.calc.toString()) + if(str !== undefined && str.match(/^\d*\.\d+$/)) { + if(str.split('.')[1].split('0').length > 7) { + // Likely rounding error + str = parseFloat(str.substring(0, str.length-1)).toString(); + } + } if(str[0] !== '-' && forceSign) str = '+' + str return str } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs index a1a96cd..677d68e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs @@ -52,10 +52,9 @@ export class Sequence extends Expr.Expression { } simplify(n = 1) { - if(n in this.calcValues) - return Utils.makeExpressionReadable(this.calcValues[n].toString()) - this.cache(n) - return Utils.makeExpressionReadable(this.calcValues[n].toString()) + if(!(n in this.calcValues)) + this.cache(n) + return this.calcValues[n].toString() } cache(n = 1) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 2c6270a..01ab8eb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -380,7 +380,7 @@ export class ExecutableObject extends DrawableObject { * Returns the simplified expression string for a given x. * * @param {number} x - * @returns {string} + * @returns {string|Expression} */ simplify(x = 1) {return '0'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index dcdd615..09895d9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -88,7 +88,7 @@ export default class PhaseBode extends ExecutableObject { return this.om_0.y.toString() } else { let newExp = this.om_0.y.toEditableString() + ' + ' + this.phase.toEditableString() - return (new Expression(newExp)).toString() + return new Expression(newExp) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index 89db16d..aeaf6e1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -81,7 +81,7 @@ export default class RepartitionFunction extends ExecutableObject { // Simplify returns the simplified string of the expression. simplify(x = 1) { - return this.execute(x) + return this.execute(x).toString() } getLabel() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 4ab8b3d..df8219b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -92,7 +92,7 @@ export default class XCursor extends DrawableObject { approx = approx.toPrecision(this.rounding + Math.round(approx).toString().length) } let simpl = t.simplify(this.x.toEditableString()) - return `${Latex.variable(t.name)}(${Latex.variable(this.name)}) = ${simpl.tokens ? Latex.expression(simpl.tokens) : simpl}` + + return `${Latex.variable(t.name)}(${Latex.variable(this.name)}) = ${simpl.latexMarkup ? simpl.latexMarkup : Latex.variable(simpl)}` + (this.approximate ? ' \\simeq ' + approx : '') } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs index 162e751..2e82be4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs @@ -272,8 +272,6 @@ export function makeExpressionReadable(str) { [/_([\d\w+-]+)/g, function(match, p1) { return textsub(p1) }], [/\[([^\[\]]+)\]/g, function(match, p1) { return textsub(p1) }], [/(\d|\))×/g, '$1'], - //[/×(\d|\()/g, '$1'], - [/([^a-z])\(([^)(+.\/-]+)\)/g, "$1×$2"], [/integral\((.+),\s?(.+),\s?["'](.+)["'],\s?["'](.+)["']\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { if(a.length < b.length) { return `∫${textsub(a)}${textsup(b)} ${body} d${by}`