A lot of changes related to latex:
Some checks reported errors
continuous-integration/drone/push Build was killed

- Implemented latex for functions
- Fixed Points with greek variable names
- Small changes to test1 to fit latex better
- History re/undos only redraw the graph every 4 change in order to speed up the process when re/undoing a lot of changes.
- Removing some debug related to latex
- Added latexMarkup property for domains, allowing them to be integrated into objects latex.
- Fixed issues related to derivatives and integrals on latex
- Fully fixed variable substitution for latex
- Fixed sequence crashing
- Adding getLatexLabel method for objects that have a latex label.
This commit is contained in:
Adsooi 2022-03-06 00:55:32 +01:00
parent ccf3de5783
commit 0975189615
Signed by: Ad5001
GPG key ID: EF45F9C6AFE20160
11 changed files with 144 additions and 57 deletions

View file

@ -124,13 +124,15 @@ Item {
}
/*!
\qmlmethod void History::undo()
\qmlmethod void History::undo(bool updateObjectList = true)
Undoes the historylib.Action at the top of the undo stack and pushes it to the top of the redo stack.
By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false.
*/
function undo() {
function undo(updateObjectList = true) {
if(undoStack.length > 0) {
var action = undoStack.pop()
action.undo()
if(updateObjectList)
objectLists.update()
redoStack.push(action)
undoCount--;
@ -140,13 +142,15 @@ Item {
}
/*!
\qmlmethod void History::redo()
\qmlmethod void History::redo(bool updateObjectList = true)
Redoes the historylib.Action at the top of the redo stack and pushes it to the top of the undo stack.
By default, will update the graph and the object list. This behavior can be disabled by setting the \c updateObjectList to false.
*/
function redo() {
function redo(updateObjectList = true) {
if(redoStack.length > 0) {
var action = redoStack.pop()
action.redo()
if(updateObjectList)
objectLists.update()
undoStack.push(action)
undoCount++;
@ -186,7 +190,7 @@ Item {
property int toUndoCount: 0
onTriggered: {
if(toUndoCount > 0) {
historyObj.undo()
historyObj.undo(toUndoCount % 4 == 1) // Only redraw once every 4 changes.
toUndoCount--;
} else {
running = false;
@ -200,7 +204,7 @@ Item {
property int toRedoCount: 0
onTriggered: {
if(toRedoCount > 0) {
historyObj.redo()
historyObj.redo(toRedoCount % 4 == 1) // Only redraw once every 4 changes.
toRedoCount--;
} else {
running = false;

View file

@ -334,7 +334,7 @@ Canvas {
\note The \c x, \c y \c width and \c height properties here are relative to the canvas, not the plot.
*/
function drawVisibleImage(ctx, image, x, y, width, height) {
console.log("Drawing image", isImageLoaded(image), isImageError(image))
//console.log("Drawing image", isImageLoaded(image), isImageError(image))
markDirty(Qt.rect(x, y, width, height));
ctx.drawImage(image, x, y, width, height)
/*if(true || (x > 0 && x < canvasSize.width && y > 0 && y < canvasSize.height)) {

View file

@ -83,7 +83,7 @@ Item {
id: iconLabel
anchors.top: parent.top
anchors.topMargin: icon == "" ? 0 : 3
source: control.visible ? "../icons/" + control.icon : ""
source: control.visible && icon != "" ? "../icons/" + control.icon : ""
width: height
height: icon == "" || !visible ? 0 : 24
color: sysPalette.windowText

View file

@ -152,10 +152,15 @@ class Domain {
* Represents an empty set.
*/
class EmptySet extends Domain {
constructor() {
super()
this.displayName = "∅"
this.latexMarkup = "\\emptyset"
}
includes(x) { return false }
toString() { return "∅" }
toString() { return this.displayName }
union(domain) { return domain }
@ -177,6 +182,7 @@ class Range extends Domain {
this.openBegin = openBegin
this.openEnd = openEnd
this.displayName = (openBegin ? "]" : "[") + begin.toString() + ";" + end.toString() + (openEnd ? "[" : "]")
this.latexMarkup = `\\mathopen${openBegin ? "]" : "["}${this.begin.latexMarkup};${this.end.latexMarkup}\\mathclose${openEnd ? "[" : "]"}`
}
includes(x) {
@ -292,6 +298,8 @@ class DomainSet extends SpecialDomain {
}
this.executedValues.sort((a,b) => a-b)
this.values = this.executedValues.map(val => newVals[val])
this.displayName = "{" + this.values.join(";") + "}"
this.latexMarkup = `\\{${this.values.join(";")}\\}`
}
includes(x) {
@ -325,7 +333,7 @@ class DomainSet extends SpecialDomain {
}
toString() {
return "{" + this.values.join(";") + "}"
return this.displayName
}
union(domain) {
@ -397,6 +405,8 @@ class UnionDomain extends Domain {
super()
this.dom1 = dom1
this.dom2 = dom2
this.displayName = this.dom1.toString() + " " + this.dom2.toString()
this.latexMarkup = `${dom1.latexMarkup}\\cup${dom2.latexMarkup}`
}
includes(x) {
@ -404,7 +414,7 @@ class UnionDomain extends Domain {
}
toString() {
return this.dom1.toString() + " " + this.dom2.toString()
return this.displayName
}
union(domain) {
@ -441,6 +451,8 @@ class IntersectionDomain extends Domain {
super()
this.dom1 = dom1
this.dom2 = dom2
this.displayName = dom1.toString() + " ∩ " + dom2.toString()
this.latexMarkup = `${dom1.latexMarkup}\\cap${dom2.latexMarkup}`
}
includes(x) {
@ -448,7 +460,7 @@ class IntersectionDomain extends Domain {
}
toString() {
return this.dom1.toString() + " ∩ " + this.dom2.toString()
return this.displayName
}
union(domain) {
@ -484,6 +496,8 @@ class MinusDomain extends Domain {
super()
this.dom1 = dom1
this.dom2 = dom2
this.displayName = dom1.toString() + "" + dom2.toString()
this.latexMarkup = `${dom1.latexMarkup}\\setminus${dom2.latexMarkup}`
}
includes(x) {
@ -491,7 +505,7 @@ class MinusDomain extends Domain {
}
toString() {
return this.dom1.toString() + "" + this.dom2.toString()
return this.displayName
}
static import(frm) {
@ -505,33 +519,45 @@ class MinusDomain extends Domain {
Domain.RE = new MinusDomain("R", "{0}")
Domain.RE.displayName = "*"
Domain.RE.latexMarkup = "\\mathbb{R}^{*}"
Domain.R = new Range(-Infinity,Infinity,true,true)
Domain.R.displayName = ""
Domain.R.latexMarkup = "\\mathbb{R}"
Domain.RP = new Range(0,Infinity,true,false)
Domain.RP.displayName = "ℝ⁺"
Domain.RP.latexMarkup = "\\mathbb{R}^{+}"
Domain.RM = new Range(-Infinity,0,true,false)
Domain.RM.displayName = "ℝ⁻"
Domain.RM.latexMarkup = "\\mathbb{R}^{-}"
Domain.RPE = new Range(0,Infinity,true,true)
Domain.RPE.displayName = "ℝ⁺*"
Domain.RPE.latexMarkup = "\\mathbb{R}^{+*}"
Domain.RME = new Range(-Infinity,0,true,true)
Domain.RME.displayName = "ℝ⁻*"
Domain.RME.latexMarkup = "\\mathbb{R}^{+*}"
Domain.N = new SpecialDomain('', x => x%1==0 && x >= 0,
x => Math.max(Math.floor(x)+1, 0),
x => Math.max(Math.ceil(x)-1, 0))
Domain.N.latexMarkup = "\\mathbb{N}"
Domain.NE = new SpecialDomain('*', x => x%1==0 && x > 0,
x => Math.max(Math.floor(x)+1, 1),
x => Math.max(Math.ceil(x)-1, 1))
Domain.NE.latexMarkup = "\\mathbb{N}^{*}"
Domain.Z = new SpecialDomain('', x => x%1==0, x => Math.floor(x)+1, x => Math.ceil(x)-1)
Domain.Z.latexMarkup = "\\mathbb{Z}"
Domain.ZE = new SpecialDomain('*', x => x%1==0 && x != 0,
x => Math.floor(x)+1 == 0 ? Math.floor(x)+2 : Math.floor(x)+1,
x => Math.ceil(x)-1 == 0 ? Math.ceil(x)-2 : Math.ceil(x)-1)
Domain.ZE.latexMarkup = "\\mathbb{Z}^{*}"
Domain.ZM = new SpecialDomain('ℤ⁻', x => x%1==0 && x <= 0,
x => Math.min(Math.floor(x)+1, 0),
x => Math.min(Math.ceil(x)-1, 0))
Domain.ZM.latexMarkup = "\\mathbb{Z}^{-}"
Domain.ZME = new SpecialDomain('ℤ⁻*', x => x%1==0 && x < 0,
x => Math.min(Math.floor(x)+1, -1),
x => Math.min(Math.ceil(x)-1, -1))
Domain.ZME.latexMarkup = "\\mathbb{Z}^{-*}"
Domain.NLog = new SpecialDomain('ℕˡᵒᵍ',
x => x/Math.pow(10, x.toString().length-1) % 1 == 0 && x > 0,
function(x) {
@ -542,6 +568,7 @@ Domain.NLog = new SpecialDomain('ℕˡᵒᵍ',
var x10pow = Math.pow(10, x.toString().length-1)
return Math.max(1, (Math.ceil(x/x10pow)-1)*x10pow)
})
Domain.NLog.latexMarkup = "\\mathbb{N}^{log}"
var refedDomains = []

View file

@ -53,10 +53,10 @@ function parif(elem, contents) {
function functionToLatex(f, args) {
switch(f) {
case "derivative":
return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(by, 'g'), 'x') + '}{dx}';
return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}';
break;
case "integral":
return '\\int\\limits^{' + args[0] + '}_{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3];
return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2);
break;
case "sqrt":
return '\\sqrt\\left(' + args.join(', ') + '\\right)';
@ -92,19 +92,22 @@ function variableToLatex(vari) {
"ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ",
"ₜ","¹","²","³","⁴","⁵","⁶",
"⁷","⁸","⁹","⁰","₁","₂","₃",
"₄","₅","₆","₇","₈","₉","₀"]
let equivalchars = ["alpha","beta","gamma","delta","epsilon","zeta","eta",
"pi","theta","kappa","lambda","mu","xi","rho",
"sigma","sigma","tau","phi","chi","psi","omega",
"Gamma","Delta","Theta","Lambda","Xi","Pi","Sigma",
"Phy","Psi","Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}",
"₄","₅","₆","₇","₈","₉","₀",
"pi"]
let equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta","\\eta",
"\\pi","\\theta","\\kappa","\\lambda","\\mu","\\xi","\\rho",
"\\sigma","\\sigma","\\tau","\\phi","\\chi","\\psi","\\omega",
"\\Gamma","\\Delta","\\Theta","\\Lambda","\\Xi","\\Pi","\\Sigma",
"\\Phy","\\Psi","\\Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}",
"{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}",
"{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}",
"{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}",
"{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}"]
"{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}",
"\\pi"]
for(let i = 0; i < unicodechars.length; i++) {
//console.log(vari, unicodechars[i], equivalchars[i]);
if(vari.includes(unicodechars[i]))
vari = vari.replaceAll(unicodechars[i], equivalchars[i])
vari = vari.replace(new RegExp(unicodechars[i], 'g'), equivalchars[i])
}
return vari;
}
@ -140,7 +143,7 @@ function expressionToLatex(tokens) {
switch(f) {
case '-':
case '+':
nstack.push(n1 + this.ope + n2);
nstack.push(n1 + f + n2);
break;
case '||':
case 'or':
@ -148,7 +151,7 @@ function expressionToLatex(tokens) {
case 'and':
case '==':
case '!=':
nstack.push(par(n1) + this.ope + par(n2));
nstack.push(par(n1) + f + par(n2));
break;
case '*':
nstack.push(parif(n1,['+','-']) + " \\times " + parif(n2,['+','-']));
@ -182,7 +185,7 @@ function expressionToLatex(tokens) {
break;
case ExprEval.IVAR:
case ExprEval.IVARNAME:
nstack.push(variableToLatex(item.value));
nstack.push(variableToLatex(item.value.toString()));
break;
case ExprEval.IOP1: // Unary operator
n1 = nstack.pop();
@ -209,6 +212,7 @@ function expressionToLatex(tokens) {
f = nstack.pop();
// Handling various functions
nstack.push(functionToLatex(f, args))
break;
case ExprEval.IFUNDEF:
nstack.push(par(n1 + '(' + args.join(', ') + ') = ' + n2));
break;
@ -235,12 +239,7 @@ function expressionToLatex(tokens) {
}
}
if (nstack.length > 1) {
if (toJS) {
nstack = [ nstack.join(',') ];
} else {
nstack = [ nstack.join(';') ];
nstack = [ nstack.join(';') ]
}
}
console.log(nstack[0]);
return String(nstack[0]);
}

View file

@ -34,7 +34,7 @@ class Sequence extends Expr.Expression {
this.calcValues = Object.assign({}, baseValues)
for(var n in this.calcValues)
if(['string', 'number'].includes(typeof this.calcValues[n]))
this.calcValues[n] = parser.parse(this.calcValues[n].toString()).simplify().evaluate(C.evalVariables)
this.calcValues[n] = C.parser.parse(this.calcValues[n].toString()).simplify().evaluate(C.evalVariables)
this.valuePlus = parseInt(valuePlus)
}
@ -58,11 +58,11 @@ class Sequence extends Expr.Expression {
cache(n = 1) {
var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString())
var expr = parser.parse(str).simplify()
var expr = C.parser.parse(str).simplify()
var l = {'n': n-this.valuePlus} // Just in case, add n (for custom functions)
l[this.name] = this.calcValues
currentVars = Object.assign(l, C.evalVariables)
this.calcValues[n] = expr.evaluate(currentVars)
C.currentVars = Object.assign(l, C.evalVariables)
this.calcValues[n] = expr.evaluate(C.currentVars)
}
toString(forceSign=false) {

View file

@ -89,6 +89,18 @@ class DrawableObject {
}
getLabel() {
switch(this.labelContent) {
case 'name':
return this.name
case 'name + value':
return this.getReadableString()
case 'null':
return ''
}
}
getLatexLabel() {
switch(this.labelContent) {
case 'name':
return this.name

View file

@ -22,6 +22,7 @@
.import "../utils.js" as Utils
.import "../mathlib.js" as MathLib
.import "../parameters.js" as P
.import "../math/latex.js" as Latex
class Function extends Common.ExecutableObject {
@ -87,6 +88,14 @@ class Function extends Common.ExecutableObject {
}
}
toLatexString() {
if(this.displayMode == 'application') {
return `${Latex.variableToLatex(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup} & \\rightarrow & ${this.destinationDomain.latexMarkup}\\\\x & \\mapsto & ${this.expression.latexMarkup}\\end{array}`
} else {
return `\\begin{array}{l}${Latex.variableToLatex(this.name)}(x) = ${this.expression.latexMarkup}\\\\ D_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}`
}
}
export() {
return [this.name, this.visible, this.color.toString(), this.labelContent,
this.expression.toEditableString(), this.definitionDomain.toString(), this.destinationDomain.toString(),
@ -117,7 +126,41 @@ class Function extends Common.ExecutableObject {
var textSize = canvas.measureText(ctx, text)
var posX = canvas.x2px(this.labelX)
var posY = canvas.y2px(this.execute(this.labelX))
let drawLabel = function(canvas, ctx, ltxImg) {
switch(this.labelPosition) {
case 'above':
canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height)
break;
case 'below':
canvas.drawVisibleImage(ctx, ltxImg.source, posX-ltxImg.width/2, posY+10, ltxImg.width, ltxImg.height)
break;
case 'left':
canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-ltxImg.height/2, ltxImg.width, ltxImg.height)
break;
case 'right':
canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-ltxImg.height/2, ltxImg.width, ltxImg.height)
break;
case 'above-left':
canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY-(ltxImg.height+10), ltxImg.width, ltxImg.height)
break;
case 'above-right':
canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY-(ltxImg.height+10), ltxImg.width, ltxImg.height)
break;
case 'below-left':
canvas.drawVisibleImage(ctx, ltxImg.source, posX-(ltxImg.width+10), posY+10, ltxImg.width, ltxImg.height)
break;
case 'below-right':
canvas.drawVisibleImage(ctx, ltxImg.source, posX+10, posY+10, ltxImg.width, ltxImg.height)
break;
}
}
let ltxLabel = this.getLatexLabel();
if(ltxLabel != "")
canvas.renderLatexImage(ltxLabel, this.color, drawLabel.bind(this))
//canvas.drawVisibleImage(ctx, ltxImg.source, posX, posY)
/*switch(this.labelPosition) {
case 'above':
canvas.drawVisibleText(ctx, text, posX-textSize.width/2, posY-textSize.height)
break;
@ -142,13 +185,13 @@ class Function extends Common.ExecutableObject {
case 'below-right':
canvas.drawVisibleText(ctx, text, posX, posY+textSize.height)
break;
}
}*/
}
static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) {
// Reusable in other objects.
// Drawing small traits every 2px
var pxprecision = 0.2
// Drawing small traits every 0.2px
var pxprecision = 1
var previousX = canvas.px2x(0)
var previousY;
if(definitionDomain instanceof MathLib.SpecialDomain && definitionDomain.moveSupported) {

View file

@ -21,6 +21,7 @@
.import "common.js" as Common
.import "../mathlib.js" as MathLib
.import "../parameters.js" as P
.import "../math/latex.js" as Latex
class Point extends Common.DrawableObject {
@ -59,7 +60,7 @@ class Point extends Common.DrawableObject {
}
toLatexString() {
return `${this.name} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)`
return `${Latex.variableToLatex(this.name)} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)`
}
export() {
@ -86,41 +87,42 @@ class Point extends Common.DrawableObject {
}
let drawLabel = function(canvas, ctx, ltxImg) {
//console.log(JSON.stringify(ltxImg), canvas.isImageLoaded(ltxImg.source), this, this.labelPosition)
switch(this.labelPosition) {
case 'top':
case 'above':
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY-(ltxImg.height+4), ltxImg.width, ltxImg.height)
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY-(ltxImg.height+10), ltxImg.width, ltxImg.height)
break;
case 'bottom':
case 'below':
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY+4, ltxImg.width, ltxImg.height)
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-ltxImg.width/2, canvasY+10, ltxImg.width, ltxImg.height)
break;
case 'left':
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+4), canvasY+4, ltxImg.width, ltxImg.height)
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+10), canvasY-ltxImg.height/2, ltxImg.width, ltxImg.height)
break;
case 'right':
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+4, canvasY+4, ltxImg.width, ltxImg.height)
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+10, canvasY-ltxImg.height/2, ltxImg.width, ltxImg.height)
break;
case 'top-left':
case 'above-left':
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+4), canvasY-(ltxImg.height+4), ltxImg.width, ltxImg.height)
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+10), canvasY-(ltxImg.height+10), ltxImg.width, ltxImg.height)
break;
case 'top-right':
case 'above-right':
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+4, canvasY-(ltxImg.height+4), ltxImg.width, ltxImg.height)
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+10, canvasY-(ltxImg.height+10), ltxImg.width, ltxImg.height)
break;
case 'bottom-left':
case 'below-left':
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+4), canvasY+4, ltxImg.width, ltxImg.height)
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX-(ltxImg.width+10), canvasY+10, ltxImg.width, ltxImg.height)
break;
case 'bottom-right':
case 'below-right':
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+4, canvasY+4, ltxImg.width, ltxImg.height)
canvas.drawVisibleImage(ctx, ltxImg.source, canvasX+10, canvasY+10, ltxImg.width, ltxImg.height)
break;
}
}
canvas.renderLatexImage(this.getLabel(), this.color, drawLabel.bind(this))
let ltxLabel = this.getLatexLabel();
if(ltxLabel != "")
canvas.renderLatexImage(ltxLabel, this.color, drawLabel.bind(this))
//canvas.drawVisibleImage(ctx, ltxImg.source, canvasX, canvasY)
}
}

View file

@ -38,14 +38,14 @@ class Latex(QObject):
if not path.exists(exprpath):
fg = color.convertTo(QColor.Rgb)
fg = f'rgb {fg.redF()} {fg.greenF()} {fg.blueF()}'
preview('$$' + latexstring + '$$', viewer='file', filename=exprpath, dvioptions=[
preview('$${' + latexstring + '}$$', viewer='file', filename=exprpath, dvioptions=[
"-T", "tight",
"-z", "0",
"--truecolor",
f"-D {font_size * 72.27 / 10}", # See https://linux.die.net/man/1/dvipng#-D for convertion
f"-D {int(font_size * 72.27 / 100) * 10}", # See https://linux.die.net/man/1/dvipng#-D for convertion
"-bg", "Transparent",
"-fg", fg],
euler=True)
euler=False)
img = QImage(exprpath);
# 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'{exprpath},{img.width()},{img.height()}'

View file

@ -1 +1 @@
LPFv1{"xzoom":100,"yzoom":485,"xmin":-1,"ymax":1,"xaxisstep":"1","yaxisstep":"0.1","xaxislabel":"ω (rad/s)","yaxislabel":"G (dB)","logscalex":false,"linewidth":2,"showxgrad":true,"showygrad":true,"textsize":22,"history":[[["EditedProperty",["h","Function","labelX",3,2.5,false]],["EditedProperty",["h","Function","labelPosition","above-left","above",false]],["EditedProperty",["h","Function","labelPosition","above","left",false]],["EditedProperty",["h","Function","labelX",2.5,2,false]],["EditedProperty",["h","Function","labelX",2,2.2,false]],["EditedProperty",["h","Function","labelX",2.2,9,false]]],[]],"width":1908,"height":1005,"objects":{"Sequence":[["u",true,"#ff5500","name + value",true,true,{"1":"cos(u[n])"},{"0":"-1"},"above-left",8]],"Function":[["f",true,"#2b156d","name + value","integral((x + 1), x, \"cos (t)\", \"t\")","ℝ⁺*","","application","left",7,true,true],["g",true,"#ac539c","name + value","0.739083","","","application","below",-1,true,false],["h",true,"#00aa00","name + value","derivative(\"cos t\", \"t\", x)","","","application","left",9,true,true]],"Repartition":[["X",true,"#1E1EAF","name",true,true,{"0":"0.2","1":"0.1","2":"0.2"},"above",2.5]],"Point":[["A",true,"#060759","name + value","4","(-0.5)","top","●"]]},"type":"logplotv1"}
LPFv1{"xzoom":100,"yzoom":485,"xmin":-1,"ymax":1,"xaxisstep":"1","yaxisstep":"0.1","xaxislabel":"ω (rad/s)","yaxislabel":"G (dB)","logscalex":false,"linewidth":2,"showxgrad":true,"showygrad":true,"textsize":22,"history":[[["EditedProperty",["h","Function","labelX",3,2.5,false]],["EditedProperty",["h","Function","labelPosition","above-left","above",false]],["EditedProperty",["h","Function","labelPosition","above","left",false]],["EditedProperty",["h","Function","labelX",2.5,2,false]],["EditedProperty",["h","Function","labelX",2,2.2,false]],["EditedProperty",["h","Function","labelX",2.2,9,false]],["EditedProperty",["f","Function","labelPosition","left","above-left",false]],["EditedProperty",["f","Function","labelX",7,7.4,false]],["EditedProperty",["A","Point","y","(-0.5)","(-0.6)",true]]],[["EditedProperty",["A","Point","labelPosition","top","above",false]]]],"width":1908,"height":1005,"objects":{"Sequence":[["u",true,"#ff5500","name + value",true,true,{"1":"cos(u[n])"},{"0":"-1"},"above-left",8]],"Function":[["f",true,"#2b156d","name + value","integral((x + 1), x, \"cos (t)\", \"t\")","ℝ⁺*","","application","above-left",7.4,true,true],["g",true,"#ac539c","null","0.739083","","","application","below",-1,true,false],["h",true,"#00aa00","name + value","derivative(\"cos t\", \"t\", x)","","","application","left",9,true,true]],"Repartition":[["X",true,"#1E1EAF","name",true,true,{"0":"0.2","1":"0.1","2":"0.2"},"above",2.5]],"Point":[["A",true,"#060759","name + value","4","(-0.6)","top","●"]]},"type":"logplotv1"}