WarpPI/src/org/warp/picalculator/math/functions/Expression.java

721 lines
26 KiB
Java
Raw Normal View History

package org.warp.picalculator.math.functions;
2016-09-02 20:32:37 +02:00
import static org.warp.picalculator.Utils.ArrayToRegex;
import static org.warp.picalculator.Utils.concat;
import static org.warp.picalculator.device.graphicengine.Display.Render.glColor3f;
import static org.warp.picalculator.device.graphicengine.Display.Render.glDrawLine;
2016-09-02 20:32:37 +02:00
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
2016-09-02 20:32:37 +02:00
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.nevec.rjm.NumeroAvanzato;
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.Utils;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.Variable;
import org.warp.picalculator.math.Variables;
2016-09-02 20:32:37 +02:00
public class Expression extends FunctionMultipleValues {
2016-09-02 20:32:37 +02:00
public Expression() {
2016-09-02 20:32:37 +02:00
super();
}
public Expression(Function[] values) {
2016-09-02 20:32:37 +02:00
super(values);
}
private boolean initialParenthesis = false;
2016-09-02 20:32:37 +02:00
public Expression(String string) throws Error {
2016-09-02 20:32:37 +02:00
this(string, "", true);
}
public Expression(String string, String debugSpaces, boolean initialParenthesis) throws Error {
2016-09-02 20:32:37 +02:00
super();
this.initialParenthesis = initialParenthesis;
2016-09-02 20:32:37 +02:00
boolean isNumber = false;
// Determine if the expression is already a number:
2016-09-02 20:32:37 +02:00
// Determina se l'espressione è già un numero:
try {
new Number(string);
2016-09-02 20:32:37 +02:00
isNumber = true;
} catch (NumberFormatException ex) {
isNumber = false;
}
String processExpression = string;
Utils.debug.println(debugSpaces + "•Analyzing expression:" + processExpression);
if (isNumber){
// If the expression is already a number:
2016-09-02 20:32:37 +02:00
// Se l'espressione è già un numero:
Number t = new Number(string);
setVariables(new Function[] { t });
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + "•Result:" + t.toString());
} else {
// Else prepare the expression:
2016-09-02 20:32:37 +02:00
// Altrimenti prepara l'espressione:
debugSpaces += " ";
// IF the expression is not a number:
2016-09-02 20:32:37 +02:00
// Se l'espressione non è già un numero:
// Check if there are more than one equal symbol (=)
// Controlla se ci sono più di un uguale (=)
2016-09-02 20:32:37 +02:00
int equationsFound = 0;
int systemsFound = 0;
for (char c : processExpression.toCharArray()) {
if (("" + c).equals(MathematicalSymbols.EQUATION)) {
2016-09-02 20:32:37 +02:00
equationsFound += 1;
}
if (("" + c).equals(MathematicalSymbols.SYSTEM)) {
2016-09-02 20:32:37 +02:00
equationsFound += 1;
}
}
if (equationsFound == 1 && systemsFound == 0) {
processExpression = MathematicalSymbols.SYSTEM + processExpression;
2016-09-02 20:32:37 +02:00
systemsFound += 1;
}
if (equationsFound != systemsFound) {
throw new Error(Errors.SYNTAX_ERROR);
2016-09-02 20:32:37 +02:00
}
//Solve the exceeding symbols ++ and --
2016-09-02 20:32:37 +02:00
// Correggi i segni ++ e -- in eccesso
Pattern pattern = Pattern.compile("\\+\\++?|\\-\\-+?");
Matcher matcher = pattern.matcher(processExpression);
boolean symbolsChanged = false;
2016-09-02 20:32:37 +02:00
while (matcher.find()) {
symbolsChanged = true;
2016-09-02 20:32:37 +02:00
String correzione = "+";
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
matcher = pattern.matcher(processExpression);
}
// Correct the exceeding symbols +- and -+
2016-09-02 20:32:37 +02:00
// Correggi i segni +- e -+ in eccesso
pattern = Pattern.compile("\\+\\-|\\-\\+");
matcher = pattern.matcher(processExpression);
while (matcher.find()) {
symbolsChanged = true;
2016-09-02 20:32:37 +02:00
String correzione = "-";
processExpression = processExpression.substring(0, matcher.start(0)) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
matcher = pattern.matcher(processExpression);
}
2016-09-02 20:32:37 +02:00
// Rimuovi i segni appena dopo le parentesi
if (processExpression.contains("(+")) {
symbolsChanged = true;
2016-09-02 20:32:37 +02:00
processExpression = processExpression.replace("(+", "(");
}
// Cambia i segni appena prima le parentesi
if (processExpression.contains("-(")) {
symbolsChanged = true;
2016-09-02 20:32:37 +02:00
processExpression = processExpression.replace("-(", "-1*(");
}
// Rimuovi i segni appena dopo l'inizio
if (processExpression.startsWith("+")) {
symbolsChanged = true;
2016-09-02 20:32:37 +02:00
processExpression = processExpression.substring(1, processExpression.length());
}
// Rimuovi i + in eccesso
pattern = Pattern.compile("[" + ArrayToRegex(Utils.add(concat(MathematicalSymbols.signums(true, true), MathematicalSymbols.functions()), "(")) + "]\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true, true), MathematicalSymbols.functions()), new String[] { "(", ")" })) + "]+?[" + ArrayToRegex(concat(MathematicalSymbols.signums(true, true), MathematicalSymbols.functions())) + "]|[" + ArrayToRegex(concat(MathematicalSymbols.signums(true, true), MathematicalSymbols.functions())) + "]+?\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true, true), MathematicalSymbols.functions()), new String[] { "(", ")" })) + "]");
2016-09-02 20:32:37 +02:00
matcher = pattern.matcher(processExpression);
symbolsChanged = false;
2016-09-02 20:32:37 +02:00
while (matcher.find()) {
symbolsChanged = true;
2016-09-02 20:32:37 +02:00
String correzione = matcher.group(0).replaceFirst(Matcher.quoteReplacement("+"), "");
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
matcher = pattern.matcher(processExpression);
}
// Correggi i segni - in +-
pattern = Pattern.compile("[^" + Utils.ArrayToRegex(concat(concat(MathematicalSymbols.functions(), new String[] { MathematicalSymbols.PARENTHESIS_OPEN }), MathematicalSymbols.signums(true, true))) + "]-");
2016-09-02 20:32:37 +02:00
matcher = pattern.matcher(processExpression);
while (matcher.find()) {
symbolsChanged = true;
2016-09-02 20:32:37 +02:00
String correzione = "+-";
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
matcher = pattern.matcher(processExpression);
}
if (symbolsChanged) {
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + "•Resolved signs:" + processExpression);
}
// Aggiungi i segni * accanto alle parentesi
pattern = Pattern.compile("\\([^\\(]+?\\)");
matcher = pattern.matcher(processExpression);
symbolsChanged = false;
2016-09-02 20:32:37 +02:00
while (matcher.find()) {
symbolsChanged = true;
2016-09-02 20:32:37 +02:00
// sistema i segni * impliciti prima e dopo l'espressione.
String beforeexp = processExpression.substring(0, matcher.start(0));
String newexp = matcher.group(0).substring(1, matcher.group(0).length() - 1);
String afterexp = processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
if (Pattern.compile("[^\\-" + Utils.ArrayToRegex(Utils.add(concat(MathematicalSymbols.functions(), concat(MathematicalSymbols.signums(true, true), MathematicalSymbols.genericSyntax())), "(")) + "]$").matcher(beforeexp).find()) {
2016-09-02 20:32:37 +02:00
// Se la stringa precedente finisce con un numero
beforeexp += MathematicalSymbols.MULTIPLICATION;
2016-09-02 20:32:37 +02:00
}
if (Pattern.compile("^[^\\-" + Utils.ArrayToRegex(Utils.add(concat(MathematicalSymbols.functions(), concat(MathematicalSymbols.signums(true, true), MathematicalSymbols.genericSyntax())), ")")) + "]").matcher(afterexp).find()) {
2016-09-02 20:32:37 +02:00
// Se la stringa successiva inizia con un numero
afterexp = MathematicalSymbols.MULTIPLICATION + afterexp;
2016-09-02 20:32:37 +02:00
}
processExpression = beforeexp + "⑴" + newexp + "⑵" + afterexp;
matcher = pattern.matcher(processExpression);
}
processExpression = processExpression.replace("⑴", "(").replace("⑵", ")");
if (symbolsChanged) {
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + "•Added implicit multiplications:" + processExpression);
}
Utils.debug.println(debugSpaces + "•Subdivision in classes:");
debugSpaces += " ";
// Convert the expression to a list of objects
Expression imputRawParenthesis = new Expression();
imputRawParenthesis.setVariables(new Function[] {});
2016-09-02 20:32:37 +02:00
String tmp = "";
final String[] functions = concat(concat(concat(concat(MathematicalSymbols.functions(), MathematicalSymbols.parentheses()), MathematicalSymbols.signums(true, true)), MathematicalSymbols.variables()), MathematicalSymbols.genericSyntax());
2016-09-02 20:32:37 +02:00
for (int i = 0; i < processExpression.length(); i++) {
// Per ogni carattere cerca se è un numero o una funzione:
String charI = processExpression.charAt(i) + "";
if (Utils.isInArray(charI, functions)) {
2016-09-02 20:32:37 +02:00
// Finds the type of function fron the following list
2016-09-02 20:32:37 +02:00
// Cerca il tipo di funzione tra le esistenti
Function f = null;
2016-09-02 20:32:37 +02:00
switch (charI) {
case MathematicalSymbols.SUM:
f = new Sum(null, null);
2016-09-02 20:32:37 +02:00
break;
case MathematicalSymbols.SUM_SUBTRACTION:
f = new SumSubtraction(null, null);
break;
case MathematicalSymbols.MULTIPLICATION:
f = new Multiplication(null, null);
2016-09-02 20:32:37 +02:00
break;
case MathematicalSymbols.PRIORITARY_MULTIPLICATION:
f = new PrioritaryMultiplication(null, null);
2016-09-02 20:32:37 +02:00
break;
case MathematicalSymbols.DIVISION:
f = new Division(null, null);
2016-09-02 20:32:37 +02:00
break;
case MathematicalSymbols.NTH_ROOT:
f = new Root(null, null);
2016-09-02 20:32:37 +02:00
break;
case MathematicalSymbols.SQUARE_ROOT:
f = new RootSquare(null);
2016-09-02 20:32:37 +02:00
break;
case MathematicalSymbols.POWER:
f = new Power(null, null);
2016-09-02 20:32:37 +02:00
break;
case MathematicalSymbols.PARENTHESIS_OPEN:
// Find the last closed parenthesis
2016-09-02 20:32:37 +02:00
// cerca l'ultima parentesi chiusa
int startIndex = i;
int endIndex = -1;
int jumps = -1;
for (int i2 = startIndex; i2 < processExpression.length(); i2++) {
if ((processExpression.charAt(i2) + "").equals(MathematicalSymbols.PARENTHESIS_CLOSE)) {
2016-09-02 20:32:37 +02:00
if (jumps == 0) {
endIndex = i2;
break;
} else if (jumps > 0) {
jumps -= 1;
} else if (jumps < 0) {
throw new Error(Errors.UNBALANCED_BRACKETS);
2016-09-02 20:32:37 +02:00
}
} else if ((processExpression.charAt(i2) + "").equals(MathematicalSymbols.PARENTHESIS_OPEN)) {
2016-09-02 20:32:37 +02:00
jumps += 1;
}
}
if (endIndex == -1 || endIndex < startIndex) {
throw new Error(Errors.UNBALANCED_BRACKETS);
2016-09-02 20:32:37 +02:00
}
startIndex += 1;
i = startIndex;
String tmpExpr = "";
while (i < endIndex) {
tmpExpr += processExpression.charAt(i);
i++;
}
f = new Expression(tmpExpr, debugSpaces, false);
2016-09-02 20:32:37 +02:00
break;
default:
if (Utils.isInArray(charI, MathematicalSymbols.variables())) {
2016-09-02 20:32:37 +02:00
// Fallback
NumeroAvanzato na = NumeroAvanzato.ONE;
Variables iy = na.getVariableY();
2016-10-02 16:01:41 +02:00
Variable var1 = new Variable(charI.charAt(0), 1, 1);
List<Variable> newVariableList = iy.getVariablesList();
newVariableList.add(var1);
iy = new Variables(newVariableList.toArray(new Variable[newVariableList.size()]));
na = na.setVariableY(iy);
f = new Number(na);
2016-09-02 20:32:37 +02:00
} else {
throw new java.lang.RuntimeException("Il carattere " + charI + " non è tra le funzioni designate!\nAggiungerlo ad esse o rimuovere il carattere dall'espressione!");
}
}
if (f instanceof Expression) {
2016-09-02 20:32:37 +02:00
tmp = "";
} else if (f instanceof Number) {
if (imputRawParenthesis.getVariablesLength() == 0) {
2016-09-02 20:32:37 +02:00
if (tmp.length() > 0) {
imputRawParenthesis.addVariableToEnd(new Number(tmp));
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + "•Added value to expression:" + tmp);
imputRawParenthesis.addVariableToEnd(new PrioritaryMultiplication(null, null));
Utils.debug.println(debugSpaces + "•Added variable to expression:" + new PrioritaryMultiplication(null, null).getSymbol());
2016-09-02 20:32:37 +02:00
}
} else {
if (tmp.length() > 0) {
if (imputRawParenthesis.getVariable(imputRawParenthesis.getVariablesLength() - 1) instanceof Number) {
imputRawParenthesis.addVariableToEnd(new PrioritaryMultiplication(null, null));
Utils.debug.println(debugSpaces + "•Added variable to expression:" + new PrioritaryMultiplication(null, null).getSymbol());
2016-09-02 20:32:37 +02:00
}
if (tmp.equals("-")) {
tmp = "-1";
}
imputRawParenthesis.addVariableToEnd(new Number(tmp));
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + "•Added value to expression:" + tmp);
}
if (tmp.length() > 0 || imputRawParenthesis.getVariable(imputRawParenthesis.getVariablesLength() - 1) instanceof Number) {
imputRawParenthesis.addVariableToEnd(new PrioritaryMultiplication(null, null));
Utils.debug.println(debugSpaces + "•Added variable to expression:" + new PrioritaryMultiplication(null, null).getSymbol());
2016-09-02 20:32:37 +02:00
}
}
} else {
if (tmp.length() != 0) {
imputRawParenthesis.addVariableToEnd(new Number(tmp));
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + "•Added variable to expression:" + tmp);
}
}
imputRawParenthesis.addVariableToEnd(f);
Utils.debug.println(debugSpaces + "•Added variable to expression:" + f.getSymbol());
2016-09-02 20:32:37 +02:00
tmp = "";
} else {
try {
if (charI.equals("-") == false && charI.equals(".") == false) {
new BigDecimal(tmp + charI);
}
// Se il carattere è un numero intero, un segno
// negativo, o un punto
tmp += charI;
} catch (Exception exc) {
throw new java.lang.RuntimeException("Il carattere " + tmp + charI + " non è nè un numero nè un espressione presente nella lista completa!\nAggiungerlo ad essa o rimuovere il carattere dall'espressione!");
}
}
}
if (tmp.length() > 0) {
Utils.debug.println(debugSpaces + "•Added variable to expression:" + tmp);
try {
imputRawParenthesis.addVariableToEnd(new Number(tmp));
2016-09-02 20:32:37 +02:00
} catch (NumberFormatException ex) {
throw new Error(Errors.SYNTAX_ERROR);
2016-09-02 20:32:37 +02:00
}
tmp = "";
}
int dsl = debugSpaces.length();
debugSpaces = "";
for (int i = 0; i < dsl - 2; i++) {
debugSpaces += " ";
}
Utils.debug.println(debugSpaces + "•Finished the subdivision in classes.");
// Fine suddivisione di insieme
Utils.debug.println(debugSpaces + "•Removing useless parentheses");
for (int i = 0; i < imputRawParenthesis.variables.length; i++) {
if (imputRawParenthesis.variables[i] instanceof Expression) {
Expression par = (Expression) imputRawParenthesis.variables[i];
2016-09-02 20:32:37 +02:00
if (par.variables.length == 1) {
Function subFunz = par.variables[0];
if (subFunz instanceof Expression || subFunz instanceof Number) {
imputRawParenthesis.variables[i] = subFunz;
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + " •Useless parentheses removed");
}
}
}
}
// Inizia l'affinazione dell'espressione
Utils.debug.println(debugSpaces + "•Pushing classes...");
Function[] oldFunctionsArray = imputRawParenthesis.getVariables();
ArrayList<Function> oldFunctionsList = new ArrayList<Function>();
for (int i = 0; i < oldFunctionsArray.length; i++) {
Function funzione = oldFunctionsArray[i];
2016-09-02 20:32:37 +02:00
if (funzione != null) {
//Affinazione
if (funzione instanceof Root) {
if ((i - 1) >= 0 && oldFunctionsArray[i-1] instanceof Number && ((Number)oldFunctionsArray[i-1]).getTerm().isBigInteger(false) && ((Number)oldFunctionsArray[i-1]).getTerm().toBigInteger(false).compareTo(new BigInteger("2")) == 0) {
oldFunctionsArray[i] = null;
oldFunctionsArray[i-1] = null;
oldFunctionsList.remove(oldFunctionsList.size()-1);
2016-09-02 20:32:37 +02:00
i -= 1;
funzione = new RootSquare(null);
2016-09-02 20:32:37 +02:00
}
}
//Aggiunta della funzione alla lista grezza
oldFunctionsList.add(funzione);
2016-09-02 20:32:37 +02:00
}
}
if (oldFunctionsList.size() > 1) {
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + " •Correcting classes:");
int before = 0;
String step = "SN Functions";
2016-09-02 20:32:37 +02:00
int n = 0;
do {
before = oldFunctionsList.size();
2016-09-02 20:32:37 +02:00
int i = 0;
boolean change = false;
if (Utils.areThereEmptyPrioritaryMultiplications(oldFunctionsList)) {
step = "prioritary multiplications"; // PRIMA FASE
} else if (Utils.areThereOnlyEmptySNFunctions(oldFunctionsList)) {
step = "SN Functions"; // SECONDA FASE
} else if (Utils.areThereOnlyEmptyNSNFunctions(oldFunctionsList)) {
step = "NSN Functions"; // TERZA FASE
} else if (Utils.areThereEmptyMultiplications(oldFunctionsList)) {
step = "multiplications"; // QUARTA FASE
} else if (Utils.areThereEmptySums(oldFunctionsList)) {
step = "sums"; // QUINTA FASE
2016-09-02 20:32:37 +02:00
} else {
// fase = "errore";
System.out.println("WARN: ---> POSSIBILE ERRORE????? <---");// BOH
// throw new Errore(Errori.SYNTAX_ERROR);
while (oldFunctionsList.size() > 1) {
oldFunctionsList.set(0, new Multiplication(oldFunctionsList.get(0), oldFunctionsList.remove(1)));
2016-09-02 20:32:37 +02:00
}
}
Utils.debug.println(debugSpaces + " •Phase: "+step);
while (i < oldFunctionsList.size() && change == false && oldFunctionsList.size() > 1) {
Function funzioneTMP = oldFunctionsList.get(i);
if (funzioneTMP instanceof FunctionTwoValues) {
if (step != "SN Functions") {
2016-09-02 20:32:37 +02:00
if (
(step == "sums" && (funzioneTMP instanceof Sum || funzioneTMP instanceof SumSubtraction) == true && ((funzioneTMP instanceof AnteriorFunction && ((AnteriorFunction) funzioneTMP).variable == null) || (funzioneTMP instanceof FunctionTwoValues && ((FunctionTwoValues) funzioneTMP).variable1 == null && ((FunctionTwoValues) funzioneTMP).variable2 == null) || (!(funzioneTMP instanceof AnteriorFunction) && !(funzioneTMP instanceof FunctionTwoValues))))
2016-09-02 20:32:37 +02:00
||
(
step.equals("prioritary multiplications")
2016-09-02 20:32:37 +02:00
&&
(funzioneTMP instanceof PrioritaryMultiplication)
2016-09-02 20:32:37 +02:00
&&
((FunctionTwoValues) funzioneTMP).variable1 == null
2016-09-02 20:32:37 +02:00
&&
((FunctionTwoValues) funzioneTMP).variable2 == null
2016-09-02 20:32:37 +02:00
)
||
(
step.equals("multiplications")
2016-09-02 20:32:37 +02:00
&&
(
(funzioneTMP instanceof Multiplication)
2016-09-02 20:32:37 +02:00
||
(funzioneTMP instanceof Division)
2016-09-02 20:32:37 +02:00
)
&&
((FunctionTwoValues) funzioneTMP).variable1 == null
2016-09-02 20:32:37 +02:00
&&
((FunctionTwoValues) funzioneTMP).variable2 == null
2016-09-02 20:32:37 +02:00
)
||
(
step == "NSN Functions"
2016-09-02 20:32:37 +02:00
&&
(funzioneTMP instanceof Sum) == false
2016-09-02 20:32:37 +02:00
&&
(funzioneTMP instanceof SumSubtraction) == false
&&
(funzioneTMP instanceof Multiplication) == false
2016-09-02 20:32:37 +02:00
&&
(funzioneTMP instanceof PrioritaryMultiplication) == false
2016-09-02 20:32:37 +02:00
&&
(funzioneTMP instanceof Division) == false
2016-09-02 20:32:37 +02:00
&&
(
(
funzioneTMP instanceof AnteriorFunction
2016-09-02 20:32:37 +02:00
&&
((AnteriorFunction) funzioneTMP).variable == null
2016-09-02 20:32:37 +02:00
)
||
(
funzioneTMP instanceof FunctionTwoValues
2016-09-02 20:32:37 +02:00
&&
((FunctionTwoValues) funzioneTMP).variable1 == null
2016-09-02 20:32:37 +02:00
&&
((FunctionTwoValues) funzioneTMP).variable2 == null
2016-09-02 20:32:37 +02:00
)
||
(
!(funzioneTMP instanceof AnteriorFunction)
2016-09-02 20:32:37 +02:00
&&
!(funzioneTMP instanceof FunctionTwoValues)
2016-09-02 20:32:37 +02:00
)
)
)
) {
change = true;
if (i + 1 < oldFunctionsList.size() && i - 1 >= 0) {
((FunctionTwoValues) funzioneTMP).setVariable1((Function) oldFunctionsList.get(i - 1));
((FunctionTwoValues) funzioneTMP).setVariable2((Function) oldFunctionsList.get(i + 1));
oldFunctionsList.set(i, funzioneTMP);
2016-09-02 20:32:37 +02:00
// è importante togliere prima gli elementi
// in fondo e poi quelli davanti, perché gli
// indici scalano da destra a sinistra.
oldFunctionsList.remove(i + 1);
oldFunctionsList.remove(i - 1);
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getSymbol());
2016-09-02 20:32:37 +02:00
try {
Utils.debug.println(debugSpaces + " " + "var1=" + ((FunctionTwoValues) funzioneTMP).getVariable1().toString());
2016-09-02 20:32:37 +02:00
} catch (NullPointerException ex2) {}
try {
Utils.debug.println(debugSpaces + " " + "var2=" + ((FunctionTwoValues) funzioneTMP).getVariable2().toString());
2016-09-02 20:32:37 +02:00
} catch (NullPointerException ex2) {}
try {
Utils.debug.println(debugSpaces + " " + "(result)=" + ((FunctionTwoValues) funzioneTMP).toString());
2016-09-02 20:32:37 +02:00
} catch (NullPointerException ex2) {}
} else {
throw new java.lang.RuntimeException("Argomenti mancanti! Sistemare l'equazione!");
}
}
}
} else if (funzioneTMP instanceof AnteriorFunction) {
if ((step == "SN Functions" && ((AnteriorFunction) funzioneTMP).variable == null)) {
if (i + 1 < oldFunctionsList.size()) {
Function nextFunc = oldFunctionsList.get(i + 1);
if (nextFunc instanceof AnteriorFunction && ((AnteriorFunction)nextFunc).variable == null) {
2016-09-02 20:32:37 +02:00
} else {
change = true;
((AnteriorFunction) funzioneTMP).setVariable((Function) nextFunc);
oldFunctionsList.set(i, funzioneTMP);
2016-09-02 20:32:37 +02:00
// è importante togliere prima gli elementi in
// fondo e poi quelli davanti, perché gli indici
// scalano da destra a sinistra.
oldFunctionsList.remove(i + 1);
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getSymbol());
Function var = ((AnteriorFunction) funzioneTMP).getVariable();
2016-09-02 20:32:37 +02:00
if (var == null) {
Utils.debug.println(debugSpaces + " " + "var=null");
} else {
Utils.debug.println(debugSpaces + " " + "var=" + var.toString());
}
}
} else {
throw new java.lang.RuntimeException("Argomenti mancanti! Sistemare l'equazione!");
}
}
} else if (funzioneTMP instanceof Number || funzioneTMP instanceof Expression) {
2016-09-02 20:32:37 +02:00
if (n < 300) {
// Utils.debug.println(debugSpaces+" •Set variable
// to number:"+funzioneTMP.calcola());
}
} else {
throw new java.lang.RuntimeException("Tipo sconosciuto");
}
i++;
n++;
}
} while (((oldFunctionsList.size() != before || step != "sums") && oldFunctionsList.size() > 1));
2016-09-02 20:32:37 +02:00
}
setVariables(oldFunctionsList);
2016-09-02 20:32:37 +02:00
dsl = debugSpaces.length();
debugSpaces = "";
for (int i = 0; i < dsl - 2; i++) {
debugSpaces += " ";
}
Utils.debug.println(debugSpaces + "•Finished correcting classes.");
String result = toString();
2016-09-02 20:32:37 +02:00
Utils.debug.println(debugSpaces + "•Result:" + result);
}
}
@Override
public String getSymbol() {
2016-09-02 20:32:37 +02:00
return "Parentesi";
}
2016-10-02 16:01:41 +02:00
@Override
protected boolean isSolvable() {
if (variables.length >= 1) {
return true;
}
return false;
}
2016-09-02 20:32:37 +02:00
@Override
public List<Function> solveOneStep() throws Error {
List<Function> ret = new ArrayList<>();
2016-10-02 16:01:41 +02:00
if (variables.length == 1) {
if (variables[0].isSolved()) {
ret.add(variables[0]);
return ret;
} else {
List<Function> l = variables[0].solveOneStep();
for (Function f : l) {
if (f instanceof Number) {
ret.add(f);
} else {
ret.add(new Expression(new Function[]{(Function) f}));
}
}
return ret;
}
2016-09-02 20:32:37 +02:00
} else {
for (Function f : variables) {
2016-10-02 16:01:41 +02:00
if (f.isSolved() == false) {
List<Function> partial = f.solveOneStep();
for (Function fnc : partial) {
ret.add(new Expression(new Function[]{(Function) fnc}));
}
}
2016-09-02 20:32:37 +02:00
}
return ret;
2016-09-02 20:32:37 +02:00
}
}
@Override
public void generateGraphics() {
for (Function var : variables) {
2016-09-02 20:32:37 +02:00
var.setSmall(small);
var.generateGraphics();
2016-09-02 20:32:37 +02:00
}
width = calcWidth();
height = calcHeight();
line = calcLine();
}
public boolean parenthesesNeeded() {
boolean parenthesesneeded = true;
if (initialParenthesis) {
2016-09-02 20:32:37 +02:00
parenthesesneeded = false;
} else {
if (variables.length == 1) {
if (variables[0] instanceof Division) {
2016-09-02 20:32:37 +02:00
parenthesesneeded = false;
} else {
parenthesesneeded = true;
}
}
}
return parenthesesneeded;
}
@Override
public void draw(int x, int y) {
if (parenthesesNeeded() == false) {
this.variables[0].draw(x, y);
} else {
float miny = y;
float maxy = y + getHeight();
int h = getHeight();
x += 1;
glColor3f(0, 0, 0);
glDrawLine(x, y + 2, x + 2, y);
glDrawLine(x, y + 2, x, y + h - 3);
glDrawLine(x, y + h - 3, x + 2, y + h - 1);
x += 4;
for (Function f : variables) {
2016-09-02 20:32:37 +02:00
float fheight = f.getHeight();
float y2 = miny + ((maxy - miny) / 2 - fheight / 2);
f.draw(x, (int) y2);
x += f.getWidth();
}
x += 2;
glDrawLine(x, y, x + 2, y + 2);
glDrawLine(x + 2, y + 2, x + 2, y + h - 3);
glDrawLine(x, y + h - 1, x + 2, y + h - 3);
x += 4;
}
}
@Override
public int getWidth() {
return width;
}
private int calcWidth() {
if (parenthesesNeeded() == false) {
return this.variables[0].getWidth();
} else {
int w = 0;
for (Function f : variables) {
2016-09-02 20:32:37 +02:00
w += f.getWidth();
}
return 1 + 4 + w + 2 + 4;
}
}
@Override
public int getHeight() {
return height;
}
private int calcHeight() {
if (initialParenthesis || variables.length == 1) {
2016-09-02 20:32:37 +02:00
return this.variables[0].getHeight();
} else {
Function tmin = null;
Function tmax = null;
for (Function t : variables) {
2016-09-02 20:32:37 +02:00
if (tmin == null || t.getLine() >= tmin.getLine()) {
tmin = t;
}
if (tmax == null || t.getHeight() - t.getLine() >= tmax.getHeight() - tmax.getLine()) {
tmax = t;
}
}
if (tmin == null)
return Utils.getFontHeight(small);
return tmin.getLine() + tmax.getHeight() - tmax.getLine();
}
}
@Override
public int getLine() {
return line;
}
private int calcLine() {
if (initialParenthesis || variables.length == 1) {
2016-09-02 20:32:37 +02:00
return this.variables[0].getLine();
} else {
Function tl = null;
for (Function t : variables) {
2016-09-02 20:32:37 +02:00
if (tl == null || t.getLine() >= tl.getLine()) {
tl = t;
}
}
if (tl == null)
return Utils.getFontHeight(small) / 2;
return tl.getLine();
}
}
}