Latex for sums, fixing bugs related to expression simplification.
Some checks failed
continuous-integration/drone/push Build is failing

Also removing some debug and unused code.
This commit is contained in:
Adsooi 2022-03-07 00:11:12 +01:00
parent ec90779912
commit 06bb00cc17
Signed by: Ad5001
GPG key ID: EF45F9C6AFE20160
6 changed files with 28 additions and 104 deletions

View file

@ -20,6 +20,7 @@
.import "../expr-eval.js" as ExprEval .import "../expr-eval.js" as ExprEval
/** /**
* Puts element within parenthesis. * Puts element within parenthesis.
* *
@ -32,14 +33,20 @@ function par(elem) {
/** /**
* Checks if the element contains at least one of the elements of * 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 {string} elem - element to put within parenthesis.
* @param {Array} contents - Array of elements to put within parenthesis. * @param {Array} contents - Array of elements to put within parenthesis.
* @returns {string} * @returns {string}
*/ */
function parif(elem, contents) { 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)); nstack.push(par(n1) + f + par(n2));
break; break;
case '*': 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; break;
case '/': case '/':
nstack.push("\\frac{" + n1 + "}{" + n2 + "}"); nstack.push("\\frac{" + n1 + "}{" + n2 + "}");

View file

@ -55,7 +55,7 @@ class PhaseBode extends Common.ExecutableObject {
om_0.name = Common.getNewName('ω') om_0.name = Common.getNewName('ω')
om_0.color = this.color om_0.color = this.color
om_0.labelContent = 'name' 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())) HistoryLib.history.addToHistory(new HistoryLib.CreateNewObject(om_0.name, 'Point', om_0.export()))
labelPosition = 'below' labelPosition = 'below'
} }

View file

@ -126,37 +126,6 @@ class Sequence extends Common.ExecutableObject {
// Label // Label
this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) 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;
}*/
} }
} }

View file

@ -23,6 +23,7 @@
.import "../objects.js" as Objects .import "../objects.js" as Objects
.import "../mathlib.js" as MathLib .import "../mathlib.js" as MathLib
.import "../parameters.js" as P .import "../parameters.js" as P
.import "../math/latex.js" as Latex
class SommeGainsBode extends Common.DrawableObject { class SommeGainsBode extends Common.DrawableObject {
@ -30,10 +31,6 @@ class SommeGainsBode extends Common.DrawableObject {
static displayType(){return qsTr('Bode Magnitudes Sum')} static displayType(){return qsTr('Bode Magnitudes Sum')}
static displayTypeMultiple(){return qsTr('Bode Magnitudes Sum')} static displayTypeMultiple(){return qsTr('Bode Magnitudes Sum')}
static createable() {return false} 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 { static properties() {return {
[QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position,
[QT_TRANSLATE_NOOP('prop','labelX')]: 'number', [QT_TRANSLATE_NOOP('prop','labelX')]: 'number',
@ -56,6 +53,10 @@ class SommeGainsBode extends Common.DrawableObject {
return `${this.name} = ${Objects.getObjectsName('Gain Bode').join(' + ')}` 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) { execute(x = 0) {
for(var [dbfn, inDrawDom] of this.cachedParts) { for(var [dbfn, inDrawDom] of this.cachedParts) {
if(inDrawDom.includes(x)) { if(inDrawDom.includes(x)) {
@ -136,37 +137,7 @@ class SommeGainsBode extends Common.DrawableObject {
F.Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R) F.Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R)
if(inDrawDom.includes(this.labelX)) { if(inDrawDom.includes(this.labelX)) {
// Label // Label
var text = this.getLabel() this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX)))
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;
}
} }
} }
} }

View file

@ -22,6 +22,7 @@
.import "../objects.js" as Objects .import "../objects.js" as Objects
.import "../mathlib.js" as MathLib .import "../mathlib.js" as MathLib
.import "../parameters.js" as P .import "../parameters.js" as P
.import "../math/latex.js" as Latex
class SommePhasesBode extends Common.ExecutableObject { class SommePhasesBode extends Common.ExecutableObject {
@ -55,6 +56,10 @@ class SommePhasesBode extends Common.ExecutableObject {
return `${this.name} = ${Objects.getObjectsName('Phase Bode').join(' + ')}` 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) { execute(x=1) {
if(typeof x == 'string') x = MathLib.executeExpression(x) if(typeof x == 'string') x = MathLib.executeExpression(x)
for(var i = 0; i < this.om0xList.length-1; i++) { for(var i = 0; i < this.om0xList.length-1; i++) {
@ -122,37 +127,7 @@ class SommePhasesBode extends Common.ExecutableObject {
} }
// Label // Label
var text = this.getLabel() this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX)))
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;
}
} }
} }

View file

@ -81,8 +81,8 @@ class Latex(QObject):
Renders a latex string into a png file. Renders a latex string into a png file.
""" """
export_path = path.join(self.tempdir.name, f'{hash(latex_markup)}_{font_size}_{color.rgb()}') 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"): if self.latexSupported and not path.exists(export_path + ".png"):
print("Rendering", latex_markup, export_path)
# Generating file # Generating file
try: try:
self.create_latex_doc(export_path, latex_markup) 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.convert_dvi_to_png(export_path, font_size, color)
self.cleanup(export_path) self.cleanup(export_path)
except Exception as e: # One of the processes failed. A message will be sent every time. except Exception as e: # One of the processes failed. A message will be sent every time.
raise e pass
img = QImage(export_path + ".png"); 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 # 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()}' 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.") 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'))) .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')) 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: except TimeoutExpired as e:
# Process timed out # Process timed out
proc.kill() proc.kill()