From 06bb00cc172037efa31d37fce2530ca11622e5fd Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 7 Mar 2022 00:11:12 +0100 Subject: [PATCH] Latex for sums, fixing bugs related to expression simplification. Also removing some debug and unused code. --- .../ad5001/LogarithmPlotter/js/math/latex.js | 16 ++++++-- .../LogarithmPlotter/js/objs/phasebode.js | 2 +- .../LogarithmPlotter/js/objs/sequence.js | 31 -------------- .../js/objs/sommegainsbode.js | 41 +++---------------- .../js/objs/sommephasesbode.js | 37 +++-------------- LogarithmPlotter/util/latex.py | 5 +-- 6 files changed, 28 insertions(+), 104 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index e036960..5d73a16 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -20,6 +20,7 @@ .import "../expr-eval.js" as ExprEval + /** * Puts element within parenthesis. * @@ -32,14 +33,20 @@ function par(elem) { /** * Checks if the element contains at least one of the elements of - * the string array contents , and returns the parenthesis version if so. + * the string array contents, but not at the first position of the string, + * and returns the parenthesis version if so. * * @param {string} elem - element to put within parenthesis. * @param {Array} contents - Array of elements to put within parenthesis. * @returns {string} */ function parif(elem, contents) { - return contents.some(x => elem.toString().includes(x)) ? par(elem) : elem + elem = elem.toString() + if(elem[0] != "(" && elem[elem.length-1] != ")" && contents.some(x => elem.indexOf(x) > 0)) + return par(elem) + if(elem[0] == "(" && elem[elem.length-1] == ")") + return elem.substr(1, elem.length-2) + return elem } @@ -154,7 +161,10 @@ function expressionToLatex(tokens) { nstack.push(par(n1) + f + par(n2)); break; case '*': - nstack.push(parif(n1,['+','-']) + " \\times " + parif(n2,['+','-'])); + if(n2 == "\\pi" || n2 == "e" || n2 == "x" || n2 == "n") + nstack.push(parif(n1,['+','-']) + n2) + else + nstack.push(parif(n1,['+','-']) + " \\times " + parif(n2,['+','-'])); break; case '/': nstack.push("\\frac{" + n1 + "}{" + n2 + "}"); diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index bedf9c7..4413de8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -55,7 +55,7 @@ class PhaseBode extends Common.ExecutableObject { om_0.name = Common.getNewName('ω') om_0.color = this.color om_0.labelContent = 'name' - om_0.labelPosition = this.phase.execute() >= 0 ? 'bottom' : 'top' + om_0.labelPosition = this.phase.execute() >= 0 ? 'above' : 'below' HistoryLib.history.addToHistory(new HistoryLib.CreateNewObject(om_0.name, 'Point', om_0.export())) labelPosition = 'below' } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js index 5ed7238..484b7a4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js @@ -126,37 +126,6 @@ class Sequence extends Common.ExecutableObject { // Label this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) - /*var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(this.execute(this.labelX)) - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - }*/ } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js index 20c17ba..8f5854c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js @@ -23,6 +23,7 @@ .import "../objects.js" as Objects .import "../mathlib.js" as MathLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex class SommeGainsBode extends Common.DrawableObject { @@ -30,10 +31,6 @@ class SommeGainsBode extends Common.DrawableObject { static displayType(){return qsTr('Bode Magnitudes Sum')} static displayTypeMultiple(){return qsTr('Bode Magnitudes Sum')} static createable() {return false} - /*static properties() {return { - 'labelPosition': new P.Enum('above', 'below', 'left', 'right', 'above-left', 'above-right', 'below-left', 'below-right'), - 'labelX': 'number' - }}*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', @@ -56,6 +53,10 @@ class SommeGainsBode extends Common.DrawableObject { return `${this.name} = ${Objects.getObjectsName('Gain Bode').join(' + ')}` } + getLatexString() { + return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Gain Bode').map(Latex.variable).join(' + ')}` + } + execute(x = 0) { for(var [dbfn, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { @@ -136,37 +137,7 @@ class SommeGainsBode extends Common.DrawableObject { F.Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R) if(inDrawDom.includes(this.labelX)) { // Label - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(dbfn.execute(this.labelX)) - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - } + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js index 98a5fcc..bfa6c4b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js @@ -22,6 +22,7 @@ .import "../objects.js" as Objects .import "../mathlib.js" as MathLib .import "../parameters.js" as P +.import "../math/latex.js" as Latex class SommePhasesBode extends Common.ExecutableObject { @@ -55,6 +56,10 @@ class SommePhasesBode extends Common.ExecutableObject { return `${this.name} = ${Objects.getObjectsName('Phase Bode').join(' + ')}` } + getLatexString() { + return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Phase Bode').map(Latex.variable).join(' + ')}` + } + execute(x=1) { if(typeof x == 'string') x = MathLib.executeExpression(x) for(var i = 0; i < this.om0xList.length-1; i++) { @@ -122,37 +127,7 @@ class SommePhasesBode extends Common.ExecutableObject { } // Label - var text = this.getLabel() - ctx.font = `${canvas.textsize}px sans-serif` - var textSize = canvas.measureText(ctx, text) - var posX = canvas.x2px(this.labelX) - var posY = canvas.y2px(this.execute(this.labelX)) - switch(this.labelPosition) { - case 'above': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height) - break; - case 'below': - canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY+textSize.height) - break; - case 'left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height/2) - break; - case 'right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height/2) - break; - case 'above-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height) - break; - case 'above-right': - canvas.drawVisibleText(ctx, text, posX, posY-textSize.height) - break; - case 'below-left': - canvas.drawVisibleText(ctx, text, posX-textSize.width, posY+textSize.height) - break; - case 'below-right': - canvas.drawVisibleText(ctx, text, posX, posY+textSize.height) - break; - } + this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index e76fd3e..17b2efe 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -81,8 +81,8 @@ class Latex(QObject): Renders a latex string into a png file. """ export_path = path.join(self.tempdir.name, f'{hash(latex_markup)}_{font_size}_{color.rgb()}') - print(export_path) if self.latexSupported and not path.exists(export_path + ".png"): + print("Rendering", latex_markup, export_path) # Generating file try: self.create_latex_doc(export_path, latex_markup) @@ -90,7 +90,7 @@ class Latex(QObject): self.convert_dvi_to_png(export_path, font_size, color) self.cleanup(export_path) except Exception as e: # One of the processes failed. A message will be sent every time. - raise e + pass img = QImage(export_path + ".png"); # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' @@ -146,7 +146,6 @@ class Latex(QObject): QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") .format(" ".join(process), proc.returncode, str(out, 'utf8')+"\n"+str(err,'utf8'))) raise Exception(" ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, 'utf8')+"\n"+str(err,'utf8')) - print(out) except TimeoutExpired as e: # Process timed out proc.kill()