Imperfect implementation, but working sequences.
This commit is contained in:
parent
7e47b3cdf9
commit
422aa5b4c7
6 changed files with 205 additions and 65 deletions
|
@ -71,7 +71,7 @@ Column {
|
|||
if(value.toString()=="NaN")
|
||||
value = ""
|
||||
}
|
||||
if(value != "" && valueInput.acceptableInput) {
|
||||
if(value !== "" && valueInput.acceptableInput) {
|
||||
control.model.setProperty(index, 'key', value)
|
||||
control.changed()
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ Column {
|
|||
if(value.toString()=="NaN")
|
||||
value = ""
|
||||
}
|
||||
if(value != "" && keyInput.acceptableInput) {
|
||||
if(value !== "" && keyInput.acceptableInput) {
|
||||
control.model.setProperty(index, 'val', value)
|
||||
control.changed()
|
||||
}
|
||||
|
@ -153,6 +153,7 @@ Column {
|
|||
var ret = []
|
||||
for(var i = 0; i < model.count; i++)
|
||||
ret.push(model.get(i).val)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,13 +128,12 @@ Canvas {
|
|||
drawVisibleText(ctx, "10"+Utils.textsup(xpow), x2px(Math.pow(10,xpow))-textSize/2, axisxpx+16+(6*(y==0)))
|
||||
}
|
||||
} else {
|
||||
for(var x = 0; x < 40*maxgradx; x += 1) {
|
||||
var drawX = x*yaxisstep1
|
||||
var txtX = yaxisstepExpr.simplify(x)
|
||||
for(var x = 1; x < drawMaxX; x += 1) {
|
||||
var drawX = x*xaxisstep1
|
||||
var txtX = xaxisstepExpr.simplify(x)
|
||||
var textSize = measureText(ctx, txtX, 6).height
|
||||
if(x != 0)
|
||||
drawVisibleText(ctx, txtX, x2px(drawX)-4, axisxpx+6+textSize)
|
||||
drawVisibleText(ctx, '-'+txtX, x2px(-drawX)-4, axisxpx+6+textSize)
|
||||
drawVisibleText(ctx, txtX, x2px(drawX)-4, axisxpx+6+textSize)
|
||||
drawVisibleText(ctx, '-'+txtX, x2px(-drawX)-4, axisxpx+6+textSize)
|
||||
}
|
||||
}
|
||||
for(var y = 0; y < drawMaxY; y += 1) {
|
||||
|
|
|
@ -359,6 +359,7 @@ ListView {
|
|||
|
||||
onChanged: {
|
||||
Objects.currentObjects[objEditor.objType][objEditor.objIndex][modelData[0]] = exportModel()
|
||||
Objects.currentObjects[objEditor.objType][objEditor.objIndex].update()
|
||||
objectListList.update()
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
const parser = new ExprEval.Parser()
|
||||
|
||||
var u = {1: 1, 2: 2, 3: 3}
|
||||
console.log(parser.parse('u[n]+u[n+1]+u[n+2]').simplify().evaluate({"u": u, 'n': 1}))
|
||||
|
||||
var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manualy
|
||||
"pi": Math.PI,
|
||||
|
@ -45,7 +44,7 @@ class Expression {
|
|||
}
|
||||
|
||||
isConstant() {
|
||||
return this.expr.indexOf("x") == -1
|
||||
return !this.expr.includes("x") && !this.expr.includes("n")
|
||||
}
|
||||
|
||||
execute(x = 1) {
|
||||
|
@ -81,33 +80,69 @@ function executeExpression(expr){
|
|||
class Sequence extends Expression {
|
||||
constructor(name, baseValues = {}, valuePlus = 1, expr = "") {
|
||||
// u[n+valuePlus] = expr
|
||||
console.log('Expression', expr)
|
||||
super(expr)
|
||||
this.name = name
|
||||
this.baseValues = baseValues
|
||||
this.valuePlus = valuePlus
|
||||
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()
|
||||
this.valuePlus = parseInt(valuePlus)
|
||||
}
|
||||
|
||||
isConstant() {
|
||||
return this.expr.indexOf("n") == -1
|
||||
}
|
||||
|
||||
execute(n = 0) {
|
||||
if(this.cached) return this.cachedValue
|
||||
if(n in this.baseValues) return this.baseValues[n]
|
||||
var vars = Object.assign({'n': n-this.valuePlus}, evalVariables)
|
||||
vars[this.name] = this.baseValues
|
||||
var un = this.calc.evaluate(vars)
|
||||
this.baseValues[n] = un
|
||||
return un
|
||||
execute(n = 1) {
|
||||
if(n in this.calcValues)
|
||||
return this.calcValues[n].evaluate(evalVariables)
|
||||
this.cache(n)
|
||||
return this.calcValues[n].evaluate(evalVariables)
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
cache(n = 1) {
|
||||
var str = this.calc.substitute('n', n-this.valuePlus).toString()
|
||||
for(var newn in this.calcValues) {
|
||||
var un = new RegExp(`${this.name}\\[${newn}\\]`, 'g')
|
||||
if(un.test(str)) {
|
||||
if (this.calcValues[newn] == undefined)
|
||||
this.cache(newn)
|
||||
str = str.replace(un, this.calcValues[newn])
|
||||
}
|
||||
}
|
||||
var expr = parser.parse(str).simplify()
|
||||
if(expr.evaluate(evalVariables) == 0) expr = parser.parse('0')
|
||||
console.log(n, expr.toString())
|
||||
expr = parser.parse(Utils.simplifyExpression(expr.toString())).simplify()
|
||||
this.calcValues[n] = expr
|
||||
}
|
||||
|
||||
toString(forceSign=false) {
|
||||
var str = Utils.makeExpressionReadable(this.calc.toString())
|
||||
if(str[0] != '-' && forceSign) str = '+' + str
|
||||
var subtxt = this.valuePlus == 0 ? 'ₙ' : Utils.textsub('n+' + this.valuePlus)
|
||||
var ret = `${this.name}${subtxt} = ${str}${this.baseValues.length == 0 ? '' : "\n"}`
|
||||
ret += Object.keys(this.baseValues).map(
|
||||
n => `${this.name}${Utils.textsub(n)} = ${this.baseValues[n]}`
|
||||
).join('; ')
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
var test = new Sequence('u', {0: 0, 1: 1}, 2, '3*u[n]+3')
|
||||
var test = new Sequence('u', {0: '0', 1: 'π'}, 2, '3*u[n]')
|
||||
console.log(test)
|
||||
for(var i=0; i<20; i++)
|
||||
for(var i=0; i<20; i++) {
|
||||
//console.log('u' + Utils.textsub(i) + ' = ' + test.simplify(i))
|
||||
console.log('u' + Utils.textsub(i) + ' = ' + test.execute(i))
|
||||
|
||||
}
|
||||
// Domains
|
||||
class Domain {
|
||||
constructor() {}
|
||||
|
|
|
@ -45,10 +45,10 @@ class DrawableObject {
|
|||
// or are instanciated by other objects.
|
||||
static createable() {return true}
|
||||
// Properties are set with key as property name and
|
||||
// value as it's type name (e.g 'Expression', 'string',
|
||||
// 'Point'...), an Array for enumerations,
|
||||
// a List instance for lists, a Dictionary instance for
|
||||
// dictionary
|
||||
// value as it's type name (e.g 'Expression', 'string'...),
|
||||
// an Enum for enumerations, an ObjectType for DrawableObjects
|
||||
// with a specific type, a List instance for lists, a
|
||||
// Dictionary instance for dictionaries...
|
||||
// Used for property modifier in the sidebar.
|
||||
static properties() {return {}}
|
||||
|
||||
|
@ -206,12 +206,16 @@ class Function extends ExecutableObject {
|
|||
'comment1': 'Ex: R+* (ℝ⁺*), N* (ℕ*), Z-* (ℤ⁻*), ]0;1[, {3;4;5}',
|
||||
'labelPosition': new P.Enum('above', 'below'),
|
||||
'displayMode': new P.Enum('application', 'function'),
|
||||
'labelX': 'number'
|
||||
'labelX': 'number',
|
||||
'comment1': 'The following parameters are used in case of non-continuous ensembles\n(E.g: ℕ, ℤ, sets like {0;3}...)',
|
||||
'drawPoints': 'Boolean',
|
||||
'drawDashedLines': 'Boolean'
|
||||
}}
|
||||
|
||||
constructor(name = null, visible = true, color = null, labelContent = 'name + value',
|
||||
expression = 'x', inDomain = 'RPE', outDomain = 'R',
|
||||
displayMode = 'application', labelPosition = 'above', labelX = 1) {
|
||||
displayMode = 'application', labelPosition = 'above', labelX = 1,
|
||||
drawPoints = true, drawDashedLines = true) {
|
||||
if(name == null) name = getNewName('fghjqlmnopqrstuvwabcde')
|
||||
super(name, visible, color, labelContent)
|
||||
this.type = 'Function'
|
||||
|
@ -224,6 +228,8 @@ class Function extends ExecutableObject {
|
|||
this.displayMode = displayMode
|
||||
this.labelPosition = labelPosition
|
||||
this.labelX = labelX
|
||||
this.drawPoints = drawPoints
|
||||
this.drawDashedLines = drawDashedLines
|
||||
}
|
||||
|
||||
getReadableString() {
|
||||
|
@ -237,7 +243,7 @@ class Function extends ExecutableObject {
|
|||
export() {
|
||||
return [this.name, this.visible, this.color.toString(), this.labelContent,
|
||||
this.expression.toEditableString(), this.inDomain.toString(), this.outDomain.toString(),
|
||||
this.displayMode, this.labelPosition, this.labelX]
|
||||
this.displayMode, this.labelPosition, this.labelX, this.drawPoints, this.drawDashedLines]
|
||||
}
|
||||
|
||||
execute(x = 1) {
|
||||
|
@ -257,13 +263,13 @@ class Function extends ExecutableObject {
|
|||
}
|
||||
|
||||
draw(canvas, ctx) {
|
||||
Function.drawFunction(canvas, ctx, this.expression, this.inDomain, this.outDomain)
|
||||
Function.drawFunction(canvas, ctx, this.expression, this.inDomain, this.outDomain, this.drawPoints, this.drawDashedLines)
|
||||
// Label
|
||||
var text = this.getLabel()
|
||||
ctx.font = "14px sans-serif"
|
||||
var textSize = canvas.measureText(ctx, text, 7)
|
||||
var posX = canvas.x2px(this.labelX)
|
||||
var posY = canvas.y2px(this.expression.execute(this.labelX))
|
||||
var posY = canvas.y2px(this.execute(this.labelX))
|
||||
switch(this.labelPosition) {
|
||||
case 'above':
|
||||
canvas.drawVisibleText(ctx, text, posX-textSize.width, posY-textSize.height)
|
||||
|
@ -275,32 +281,39 @@ class Function extends ExecutableObject {
|
|||
}
|
||||
}
|
||||
|
||||
static drawFunction(canvas, ctx, expr, inDomain, outDomain) {
|
||||
static drawFunction(canvas, ctx, expr, inDomain, outDomain, drawPoints = true, drawDash = true) {
|
||||
// Reusable in other objects.
|
||||
// Drawing small traits every 2px
|
||||
var pxprecision = 2
|
||||
var previousX = canvas.px2x(0)
|
||||
var previousY;
|
||||
if(inDomain instanceof MathLib.SpecialDomain && inDomain.moveSupported) {
|
||||
// Point based functions.
|
||||
previousX = inDomain.previous(previousX)
|
||||
if(previousX === null) previousX = inDomain.next(canvas.px2x(0))
|
||||
previousY = expr.execute(previousX)
|
||||
if(!drawPoints && !drawDash) return
|
||||
while(previousX !== null && canvas.x2px(previousX) < canvas.canvasSize.width) {
|
||||
var currentX = inDomain.next(previousX)
|
||||
var currentY = expr.execute(currentX)
|
||||
if(currentX === null) break;
|
||||
if((inDomain.includes(currentX) || inDomain.includes(previousX)) &&
|
||||
(outDomain.includes(currentY) || outDomain.includes(previousY))) {
|
||||
canvas.drawDashedLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY))
|
||||
ctx.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2)
|
||||
ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10)
|
||||
if(drawDash)
|
||||
canvas.drawDashedLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY))
|
||||
if(drawPoints) {
|
||||
ctx.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2)
|
||||
ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10)
|
||||
}
|
||||
}
|
||||
previousX = currentX
|
||||
previousY = currentY
|
||||
}
|
||||
// Drawing the last cross
|
||||
ctx.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2)
|
||||
ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10)
|
||||
if(drawPoints) {
|
||||
// Drawing the last cross
|
||||
ctx.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2)
|
||||
ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10)
|
||||
}
|
||||
} else {
|
||||
previousY = expr.execute(previousX)
|
||||
for(var px = pxprecision; px < canvas.canvasSize.width; px += pxprecision) {
|
||||
|
@ -843,6 +856,7 @@ class CursorX extends DrawableObject {
|
|||
}
|
||||
|
||||
getTargetElement() {
|
||||
// TODO: Use the dependency system instead.
|
||||
var elementTypes = Object.keys(currentObjects).filter(objType => types[objType].prototype instanceof ExecutableObject)
|
||||
return getObjectByName(this.targetElement, elementTypes)
|
||||
}
|
||||
|
@ -922,17 +936,65 @@ class Sequence extends ExecutableObject {
|
|||
static type(){return 'Sequence'}
|
||||
static typeMultiple(){return 'Sequences'}
|
||||
static properties() {return {
|
||||
'defaultExpression': new P.Dictionary('string', 'int', /^.+$/, /^(\d+)$/, '{name}[n+', '] = ', true),
|
||||
'drawPoints': 'Boolean',
|
||||
'drawDashedLines': 'Boolean',
|
||||
'defaultExpression': new P.Dictionary('string', 'int', /^.+$/, /^\d+$/, '{name}[n+', '] = ', true),
|
||||
'comment1': 'Note: Use {name}[n] to refer to {name}ₙ, {name}[n+1] for {name}ₙ₊₁...',
|
||||
'markedValues': new P.Dictionary('string', 'int', /^.+$/, /^(\d+)$/, '{name}[', '] = '),
|
||||
'baseValues': new P.Dictionary('string', 'int', /^.+$/, /^\d+$/, '{name}[', '] = '),
|
||||
}}
|
||||
|
||||
constructor(name = null, visible = true, color = null, labelContent = 'name + value',
|
||||
defaultExp = {1: "u[n]"}, markedValues = {0: 0}) {
|
||||
drawPoints = true, drawDashedLines = true, defaultExp = {1: "n"},
|
||||
baseValues = {0: 0}) {
|
||||
if(name == null) name = getNewName('uvwPSUVWabcde')
|
||||
super(name, visible, color, labelContent)
|
||||
this.drawPoints = drawPoints
|
||||
this.drawDashedLines = drawDashedLines
|
||||
this.defaultExpression = defaultExp
|
||||
this.markedValues = markedValues
|
||||
this.baseValues = baseValues
|
||||
this.update()
|
||||
}
|
||||
|
||||
export() {
|
||||
return [this.name, this.visible, this.color.toString(), this.labelContent,
|
||||
this.drawPoints, this.drawDashedLines, this.defaultExpression, this.baseValues]
|
||||
}
|
||||
|
||||
update() {
|
||||
super.update()
|
||||
if(
|
||||
this.sequence == null || this.baseValues != this.sequence.baseValues ||
|
||||
this.sequence.name != this.name ||
|
||||
this.sequence.expr != Object.values(this.defaultExpression)[0] ||
|
||||
this.sequence.valuePlus != Object.keys(this.defaultExpression)[0]
|
||||
)
|
||||
this.sequence = new MathLib.Sequence(
|
||||
this.name, this.baseValues,
|
||||
Object.keys(this.defaultExpression)[0],
|
||||
Object.values(this.defaultExpression)[0]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
getReadableString() {
|
||||
return this.sequence.toString()
|
||||
}
|
||||
|
||||
execute(x = 1) {
|
||||
if(x % 1 == 0)
|
||||
return this.sequence.execute(x)
|
||||
return null
|
||||
}
|
||||
canExecute(x = 1) {return x%1 == 0}
|
||||
// Simplify returns the simplified string of the expression.
|
||||
simplify(x = 1) {
|
||||
if(x % 1 == 0)
|
||||
return this.sequence.simplify(x)
|
||||
return null
|
||||
}
|
||||
|
||||
draw(canvas, ctx) {
|
||||
Function.drawFunction(canvas, ctx, this.sequence, canvas.logscalex ? MathLib.Domain.NE : MathLib.Domain.N, MathLib.Domain.R, this.drawPoints, this.drawDashedLines)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
var powerpos = {
|
||||
"-": "⁻",
|
||||
"+": "⁺",
|
||||
"=": "⁼",
|
||||
" ": " ",
|
||||
"0": "⁰",
|
||||
"1": "¹",
|
||||
"2": "²",
|
||||
|
@ -30,8 +33,6 @@ var powerpos = {
|
|||
"7": "⁷",
|
||||
"8": "⁸",
|
||||
"9": "⁹",
|
||||
"+": "⁺",
|
||||
"=": "⁼",
|
||||
"a": "ᵃ",
|
||||
"b": "ᵇ",
|
||||
"c": "ᶜ",
|
||||
|
@ -56,11 +57,14 @@ var powerpos = {
|
|||
"w": "ʷ",
|
||||
"x": "ˣ",
|
||||
"y": "ʸ",
|
||||
"z": "ᶻ",
|
||||
"z": "ᶻ"
|
||||
}
|
||||
|
||||
var indicepos = {
|
||||
"-": "₋",
|
||||
"+": "₊",
|
||||
"=": "₌",
|
||||
" ": " ",
|
||||
"0": "₀",
|
||||
"1": "₁",
|
||||
"2": "₂",
|
||||
|
@ -71,8 +75,6 @@ var indicepos = {
|
|||
"7": "₇",
|
||||
"8": "₈",
|
||||
"9": "₉",
|
||||
"+": "₊",
|
||||
"=": "₌",
|
||||
"a": "ₐ",
|
||||
"e": "ₑ",
|
||||
"h": "ₕ",
|
||||
|
@ -122,12 +124,46 @@ function textsub(text) {
|
|||
function simplifyExpression(str) {
|
||||
var replacements = [
|
||||
// Operations not done by parser.
|
||||
[// Decomposition way 2
|
||||
/(^.?|[+-] |\()([-.\d\w]+) ([*/]) \((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\)(.?$| [+-]|\))/g,
|
||||
"$1$2 $3 $4 $6 $2 $3 $7$9"
|
||||
],
|
||||
[ // Decomposition way 2
|
||||
/(^.?|[+-] |\()\((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\) ([*/]) ([-.\d\w]+)(.?$| [+-]|\))/g,
|
||||
"$1$8 $7 $2 $4 $8 $7 $5$9"
|
||||
],
|
||||
[ // Factorisation of π elements.
|
||||
/(([-\d\w.]+ [*/] )*)(pi|π)(( [/*] [-\d\w.]+)*) ([+-]) (([-\d\w.]+ [*/] )*)(pi|π)(( [/*] [-\d\w.]+)*)?/g,
|
||||
function(match, m1, n1, pi1, m2, ope2, n2, opeM, m3, n3, pi2, m4, ope4, n4) {
|
||||
// g1, g2, g3 , g4, g5, g6, g7, g8, g9, g10, g11,g12 , g13
|
||||
// We don't care about mx & pix, ope2 & ope4 are either / or * for n2 & n4.
|
||||
// n1 & n3 are multiplied, opeM is the main operation (- or +).
|
||||
// Putting all n in form of number
|
||||
//n2 = n2 == undefined ? 1 : parseFloat(n)
|
||||
n1 = m1 == undefined ? 1 : eval(m1 + '1')
|
||||
n2 = m2 == undefined ? 1 : eval('1' + m2)
|
||||
n3 = m3 == undefined ? 1 : eval(m3 + '1')
|
||||
n4 = m4 == undefined ? 1 : eval('1' + m4)
|
||||
//var [n1, n2, n3, n4] = [n1, n2, n3, n4].map(n => n == undefined ? 1 : parseFloat(n))
|
||||
// Falling back to * in case it does not exist (the corresponding n would be 1)
|
||||
var [ope2, ope4] = [ope2, ope4].map(ope => ope == '/' ? '/' : '*')
|
||||
var coeff1 = n1*n2
|
||||
var coeff2 = n3*n4
|
||||
var coefficient = coeff1+coeff2-(opeM == '-' ? 2*coeff2 : 0)
|
||||
|
||||
return `${coefficient} * π`
|
||||
}
|
||||
],
|
||||
[ // Removing parenthesis when content is only added from both sides.
|
||||
/(^.?|[+-] |\()\(([^)(]+)\)(.?$| [+-]|\))/g,
|
||||
function(match, b4, middle, after) {return `${b4}${middle}${after}`}
|
||||
],
|
||||
[ // Removing parenthesis when content is only multiplied.
|
||||
/(^.?|[*\/] |\()\(([^)(+-]+)\)(.?$| [*\/]|\))/g,
|
||||
/(^.?|[*\/] |\()\(([^)(+-]+)\)(.?$| [*\/+-]|\))/g,
|
||||
function(match, b4, middle, after) {return `${b4}${middle}${after}`}
|
||||
],
|
||||
[ // Removing parenthesis when content is only multiplied.
|
||||
/(^.?|[*\/-+] |\()\(([^)(+-]+)\)(.?$| [*\/]|\))/g,
|
||||
function(match, b4, middle, after) {return `${b4}${middle}${after}`}
|
||||
],
|
||||
[// Simplification additions/substractions.
|
||||
|
@ -176,26 +212,33 @@ function simplifyExpression(str) {
|
|||
}
|
||||
],
|
||||
// Simple simplifications
|
||||
[/(\s|^|\()0 \* (\([^)(]+\))/g, '$10'],
|
||||
[/(\s|^|\()0 \* ([^)(+-]+)/g, '$10'],
|
||||
[/(\([^)(]\)) \* 0(\s|$|\))/g, '0$2'],
|
||||
[/([^)(+-]) \* 0(\s|$|\))/g, '0$2'],
|
||||
[/(\s|^|\()1 (\*|\/) /g, '$1'],
|
||||
[/(\s|^|\()0 (\+|\-) /g, '$1'],
|
||||
[/ (\*|\/) 1(\s|$|\))/g, '$2'],
|
||||
[/ (\+|\-) 0(\s|$|\))/g, '$2'],
|
||||
[/(\s|^|\()0(\.0+)? \* (\([^)(]+\))/g, '$10'],
|
||||
[/(\s|^|\()0(\.0+)? \* ([^)(+-]+)/g, '$10'],
|
||||
[/(\([^)(]\)) \* 0(\.0+)?(\s|$|\))/g, '0$3'],
|
||||
[/([^)(+-]) \* 0(\.0+)?(\s|$|\))/g, '0$3'],
|
||||
[/(\s|^|\()1(\.0+)? (\*|\/) /g, '$1'],
|
||||
[/(\s|^|\()0(\.0+)? (\+|\-) /g, '$1'],
|
||||
[/ (\*|\/) 1(\.0+)?(\s|$|\))/g, '$3'],
|
||||
[/ (\+|\-) 0(\.0+)?(\s|$|\))/g, '$3'],
|
||||
[/(^| |\() /g, '$1'],
|
||||
[/ ($|\))/g, '$1'],
|
||||
]
|
||||
|
||||
// Replacements
|
||||
replacements.forEach(function(replacement){
|
||||
while(replacement[0].test(str))
|
||||
str = str.replace(replacement[0], replacement[1])
|
||||
})
|
||||
var found
|
||||
do {
|
||||
found = false
|
||||
for(var replacement of replacements)
|
||||
while(replacement[0].test(str)) {
|
||||
found = true
|
||||
str = str.replace(replacement[0], replacement[1])
|
||||
}
|
||||
} while(found)
|
||||
return str
|
||||
}
|
||||
|
||||
console.log(simplifyExpression("(4 * (4 * pi + pi)) + pi"))
|
||||
|
||||
function makeExpressionReadable(str) {
|
||||
var replacements = [
|
||||
// variables
|
||||
|
@ -209,6 +252,7 @@ function makeExpressionReadable(str) {
|
|||
[/\^([^ ]+)/g, function(match, p1) { return textsup(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'],
|
||||
[/\(([^)(+.\/-]+)\)/g, "$1"],
|
||||
|
@ -216,10 +260,9 @@ function makeExpressionReadable(str) {
|
|||
|
||||
str = simplifyExpression(str)
|
||||
// Replacements
|
||||
replacements.forEach(function(replacement){
|
||||
for(var replacement of replacements)
|
||||
while(replacement[0].test(str))
|
||||
str = str.replace(replacement[0], replacement[1])
|
||||
})
|
||||
return str
|
||||
}
|
||||
|
||||
|
@ -269,9 +312,8 @@ function parseName(str, removeUnallowed = true) {
|
|||
]
|
||||
if(!removeUnallowed) replacements.pop()
|
||||
// Replacements
|
||||
replacements.forEach(function(replacement){
|
||||
for(var replacement of replacements)
|
||||
str = str.replace(replacement[0], replacement[1])
|
||||
})
|
||||
return str
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue