Merge remote-tracking branch 'origin/new-internal-structure'

This commit is contained in:
XDrake99 2017-04-23 15:10:31 +02:00
commit 0bf349ce9f
146 changed files with 4931 additions and 3610 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="org/warp/picalculator/deprecatedmath/" kind="src" path="src"/>
<classpathentry excluding="org/warp/picalculator/deprecatedmath/|org/warp/picalculator/device/PIDisplay.java|org/warp/picalculator/device/graphicengine/Display.java|com/rits/cloning/|com/rits/perspectives/|com/rits/|com/|org/warp/picalculator/TestCalcBenchmark.java" kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="src" path="res"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.USER_LIBRARY/JOGL"/>
@ -29,5 +29,10 @@
<attribute name="javadoc_location" value="jar:platform:/resource/PICalculator/libs/objenesis-2.4/objenesis-2.4-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/fastutil/fastutil-7.1.0.jar" sourcepath="libs/fastutil/fastutil-7.1.0-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/PICalculator/libs/fastutil/fastutil-7.1.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin"/>
</classpath>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
res/algebra_input.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
res/draft.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
res/draft2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

View File

@ -116,8 +116,7 @@ public class BMPFile extends Component {
final byte rgb[] = new byte[3];
size = (biWidth * biHeight) - 1;
pad = 4 - ((biWidth * 3) % 4);
if (pad == 4)
{
if (pad == 4) {
pad = 0; // <==== Bug correction
}
rowCount = 1;

View File

@ -7,8 +7,14 @@ public class Error extends java.lang.Throwable {
*/
private static final long serialVersionUID = -1014947815755694651L;
public Error(Errors ErrorID) {
id = ErrorID;
public Error(Errors errorID) {
super(errorID.toString());
id = errorID;
}
public Error(Errors errorID, String errorMessage) {
super(errorID.toString() + ": " + errorMessage);
id = errorID;
}
public Errors id = Errors.ERROR;

View File

@ -1,5 +1,5 @@
package org.warp.picalculator;
public enum Errors {
ERROR, DIVISION_BY_ZERO, UNBALANCED_BRACKETS, NOT_IMPLEMENTED, NEGATIVE_PARAMETER, NUMBER_TOO_LARGE, NUMBER_TOO_SMALL, CONVERSION_ERROR, SYNTAX_ERROR, NOT_AN_EQUATION, TIMEOUT
ERROR, DIVISION_BY_ZERO, UNBALANCED_STACK, NOT_IMPLEMENTED, NEGATIVE_PARAMETER, NUMBER_TOO_LARGE, NUMBER_TOO_SMALL, CONVERSION_ERROR, SYNTAX_ERROR, NOT_AN_EQUATION, TIMEOUT, MISSING_ARGUMENTS
}

View File

@ -14,6 +14,9 @@ public class Main {
public static Main instance;
public static boolean haxMode = true;
public static String[] args;
public static final String calculatorName = "WarpPI";
public static final String calculatorNameLOWER = "warppi";
public static final String calculatorNameUPPER = "WARPPI";
public Main(String[] args) throws InterruptedException {
this(new LoadingScreen(), args);
@ -23,7 +26,7 @@ public class Main {
instance = this;
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
Thread.currentThread().setName("Main thread");
this.args = args;
Main.args = args;
beforeStart();
new DisplayManager(screen);
Utils.debug.println("Shutdown...");

View File

@ -0,0 +1,28 @@
package org.warp.picalculator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.functions.Multiplication;
public class TestCalcBenchmark {
public static void main(String[] args) throws Error {
Utils.debugOn = true;
final int times = 1;
final MathContext mc = new MathContext();
final long time1 = System.nanoTime();
mc.parseInputString("5WABCDEFGHIWABCDEFGHIWABCDEFGHIWABCDEFGHIWABCDEFGHIWABCDEFGHI");
final long time2 = System.nanoTime();
for (int i = 0; i < times; i++) {
if (i == 1) {
Utils.debugOn = false;
}
mc.f2 = mc.solveExpression(mc.f);
}
final long time3 = System.nanoTime();
// System.out.println(mc.f2.get(0).toString());
System.out.println("PARSING\t" + ((time2 - time1) / 1000000d / (times)) + " milliseconds");
System.out.println("WORK\t" + ((time3 - time2) / 1000000d / (times)) + " milliseconds");
System.out.println("TOTAL\t" + ((time3 - time1) / 1000000d / (times)) + " milliseconds");
}
}

View File

@ -23,7 +23,7 @@ public class TestDrivers {
try {
Class.forName(className);
return true;
} catch( ClassNotFoundException e ) {
} catch (final ClassNotFoundException e) {
return false;
}
}

View File

@ -3,48 +3,162 @@ package org.warp.picalculator;
import java.io.IOException;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.gui.graphicengine.RenderingLoop;
import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.device.Keyboard.Key;
import org.warp.picalculator.device.KeyboardEventListener;
import org.warp.picalculator.gui.expression.blocks.BlockContainer;
import org.warp.picalculator.gui.expression.containers.NormalInputContainer;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.Skin;
import org.warp.picalculator.gui.graphicengine.gpu.GPUEngine;
import org.warp.picalculator.gui.graphicengine.gpu.GPURenderer;
import org.warp.picalculator.gui.screens.KeyboardDebugScreen;
import org.warp.picalculator.gui.screens.MarioScreen;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.parser.MathParser;
public class TestGPU {
public static final GPUEngine d = new GPUEngine();
public static final GraphicEngine d = new GPUEngine();
public static void main(String[] args) throws IOException {
public static void main(String[] args) throws IOException, Error {
Utils.debugOn = true;
Utils.debugThirdScreen = false;
d.create();
Keyboard.startKeyboard();
Keyboard.setAdditionalKeyboardListener(new KeyboardEventListener() {
@Override
public boolean keyPressed(Key k) {
switch (k) {
case LEFT:
c.moveLeft();
return true;
case RIGHT:
c.moveRight();
return true;
case NUM0:
c.typeChar('0');
return true;
case NUM1:
c.typeChar('1');
return true;
case NUM2:
c.typeChar('2');
return true;
case NUM3:
c.typeChar('3');
return true;
case NUM4:
c.typeChar('4');
return true;
case NUM5:
c.typeChar('5');
return true;
case NUM6:
c.typeChar('6');
return true;
case NUM7:
c.typeChar('7');
return true;
case NUM8:
c.typeChar('8');
return true;
case NUM9:
c.typeChar('9');
return true;
case PLUS:
c.typeChar(MathematicalSymbols.SUM);
return true;
case MINUS:
c.typeChar(MathematicalSymbols.SUBTRACTION);
return true;
case MULTIPLY:
c.typeChar(MathematicalSymbols.MULTIPLICATION);
return true;
case DIVIDE:
c.typeChar(MathematicalSymbols.DIVISION);
return true;
case SQRT:
c.typeChar(MathematicalSymbols.SQUARE_ROOT);
return true;
case PARENTHESIS_OPEN:
case SINE:
c.typeChar(MathematicalSymbols.PARENTHESIS_OPEN);
return true;
case PARENTHESIS_CLOSE:
case debug_DEG:
c.moveRight();
return true;
case DELETE:
c.del();
return true;
case RESET:
c.clear();
return true;
case POWER:
d.destroy();
System.exit(0);
return true;
case EQUAL:
Expression expr;
try {
expr = MathParser.parseInput(new MathContext(), c);
System.out.println("Parsed input:" + expr.toString());
} catch (final Error e) {
e.printStackTrace();
}
}
return false;
}
@Override
public boolean keyReleased(Key k) {
return false;
}
});
final Scene s = new Scene(d);
}
private static NormalInputContainer c = null;
private static class Scene implements RenderingLoop {
private BinaryFont exampleFont;
private final BinaryFont exampleFont;
private final Skin exampleSkin;
private final GPURenderer r;
private final Renderer r;
private final GraphicEngine d;
private long lastTime = 0L;
public Scene(GraphicEngine d) throws IOException {
public Scene(GraphicEngine d) throws IOException, Error {
this.d = d;
r = (GPURenderer) d.getRenderer();
r = d.getRenderer();
exampleFont = d.loadFont("ex");
exampleSkin = d.loadSkin("skin.png");
BlockContainer.initializeFonts(d.loadFont("ex"), d.loadFont("big"));
//New expression framework test
c = new NormalInputContainer(false, 0, 200);
c.typeChar(MathematicalSymbols.DIVISION);
c.typeChar('5');
c.typeChar(MathematicalSymbols.MULTIPLICATION);
c.typeChar('2');
c.moveRight();
c.typeChar('2');
c.moveRight();
c.typeChar(MathematicalSymbols.MULTIPLICATION);
c.typeChar('2');
c.typeChar('2');
c.recomputeDimensions();
d.start(this);
// fonts = new RAWFont[1];
@ -61,7 +175,10 @@ public class TestGPU {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!Utils.debugOn) {
d.destroy();
System.exit(0);
}
}).start();
d.waitUntilExit();
@ -76,13 +193,22 @@ public class TestGPU {
r.glFillRect(2, 2, 160, 160, 0, 0, 16, 16);
exampleFont.use(d);
r.glColor3f(1, 0, 0);
r.glDrawStringLeft(10, 170, "Prova! 123456789");
r.glDrawStringLeft(10, 170, "Prova! 123456789 222");
//MSAA TEST
r.glDrawStringLeft(10f, 190.5f, "Test MSAA");
exampleSkin.use(d);
r.glColor3f(1.0f, 1.0f, 1.0f);
r.glFillRect(162, 2.5f, 160, 160, 0, 0, 16, 16);
//New expression framework test
if (lastTime == 0) {
lastTime = System.currentTimeMillis();
}
final double delta = System.currentTimeMillis() - lastTime;
lastTime = System.currentTimeMillis();
c.beforeRender((float) (delta / 1000d));
c.draw(d, r, 10, 220);
}
}

View File

@ -15,18 +15,18 @@ import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import org.nevec.rjm.BigDecimalMath;
import org.nevec.rjm.Rational;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.functions.Division;
import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.functions.FunctionTwoValues;
import org.warp.picalculator.math.functions.Multiplication;
import org.warp.picalculator.math.functions.Negative;
import org.warp.picalculator.math.functions.Number;
@ -37,8 +37,6 @@ import org.warp.picalculator.math.functions.Variable;
import org.warp.picalculator.math.functions.equations.Equation;
import org.warp.picalculator.math.functions.equations.EquationsSystemPart;
import com.rits.cloning.Cloner;
public class Utils {
public static final int scale = 24;
@ -51,8 +49,7 @@ public class Utils {
public static boolean debugOn;
public static boolean debugThirdScreen;
public static Cloner cloner = new Cloner();
public static boolean debugWindow2x;
public static final class DebugStream extends StringWriter {
@ -78,6 +75,17 @@ public class Utils {
return contains;
}
public static boolean isInArray(char ch, char[] a) {
boolean contains = false;
for (final char c : a) {
if (c == ch) {
contains = true;
break;
}
}
return contains;
}
private static final String[] regexNormalSymbols = new String[] { "\\", ".", "[", "]", "{", "}", "(", ")", "*", "+", "-", "?", "^", "$", "|" };
public static String ArrayToRegex(String[] array) {
@ -107,6 +115,33 @@ public class Utils {
return regex;
}
public static String ArrayToRegex(char[] array) {
String regex = null;
for (final char symbol : array) {
boolean contained = false;
for (final String smb : regexNormalSymbols) {
if ((smb).equals(symbol + "")) {
contained = true;
break;
}
}
if (contained) {
if (regex != null) {
regex += "|\\" + symbol;
} else {
regex = "\\" + symbol;
}
} else {
if (regex != null) {
regex += "|" + symbol;
} else {
regex = symbol + "";
}
}
}
return regex;
}
public static String[] concat(String[] a, String[] b) {
final int aLen = a.length;
final int bLen = b.length;
@ -116,6 +151,15 @@ public class Utils {
return c;
}
public static char[] concat(char[] a, char[] b) {
final int aLen = a.length;
final int bLen = b.length;
final char[] c = new char[aLen + bLen];
System.arraycopy(a, 0, c, 0, aLen);
System.arraycopy(b, 0, c, aLen, bLen);
return c;
}
public static String[] add(String[] a, String b) {
final int aLen = a.length;
final String[] c = new String[aLen + 1];
@ -124,15 +168,23 @@ public class Utils {
return c;
}
public static boolean areThereOnlySettedUpFunctionsSumsEquationsAndSystems(ArrayList<Function> fl) {
public static char[] add(char[] a, char b) {
final int aLen = a.length;
final char[] c = new char[aLen + 1];
System.arraycopy(a, 0, c, 0, aLen);
c[aLen] = b;
return c;
}
public static boolean areThereOnlySettedUpFunctionsSumsEquationsAndSystems(ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Subtraction || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) {
if (fl.get(i) instanceof AnteriorFunction) {
if (((AnteriorFunction) fl.get(i)).getVariable() == null) {
if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return false;
}
} else if (fl.get(i) instanceof FunctionTwoValues) {
if (((FunctionTwoValues) fl.get(i)).getVariable1() == null || ((FunctionTwoValues) fl.get(i)).getVariable2() == null) {
} else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return false;
}
} else {
@ -143,15 +195,16 @@ public class Utils {
return true;
}
public static boolean areThereOnlySettedUpFunctionsSumsMultiplicationsEquationsAndSystems(ArrayList<Function> fl) {
public static boolean areThereOnlySettedUpFunctionsSumsMultiplicationsEquationsAndSystems(
ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Multiplication || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Subtraction || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) {
if (fl.get(i) instanceof AnteriorFunction) {
if (((AnteriorFunction) fl.get(i)).getVariable() == null) {
if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return false;
}
} else if (fl.get(i) instanceof FunctionTwoValues) {
if (((FunctionTwoValues) fl.get(i)).getVariable1() == null || ((FunctionTwoValues) fl.get(i)).getVariable2() == null) {
} else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return false;
}
} else {
@ -162,15 +215,15 @@ public class Utils {
return true;
}
public static boolean areThereOnlySettedUpFunctionsEquationsAndSystems(ArrayList<Function> fl) {
public static boolean areThereOnlySettedUpFunctionsEquationsAndSystems(ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) {
if (fl.get(i) instanceof AnteriorFunction) {
if (((AnteriorFunction) fl.get(i)).getVariable() == null) {
if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return false;
}
} else if (fl.get(i) instanceof FunctionTwoValues) {
if (((FunctionTwoValues) fl.get(i)).getVariable1() == null || ((FunctionTwoValues) fl.get(i)).getVariable2() == null) {
} else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return false;
}
} else {
@ -181,15 +234,15 @@ public class Utils {
return true;
}
public static boolean areThereOnlySettedUpFunctionsAndSystems(ArrayList<Function> fl) {
public static boolean areThereOnlySettedUpFunctionsAndSystems(ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) {
if (fl.get(i) instanceof AnteriorFunction) {
if (((AnteriorFunction) fl.get(i)).getVariable() == null) {
if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return false;
}
} else if (fl.get(i) instanceof FunctionTwoValues) {
if (((FunctionTwoValues) fl.get(i)).getVariable1() == null || ((FunctionTwoValues) fl.get(i)).getVariable2() == null) {
} else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return false;
}
} else {
@ -200,10 +253,10 @@ public class Utils {
return true;
}
public static boolean areThereOnlyEmptySNFunctions(ArrayList<Function> fl) {
public static boolean areThereOnlyEmptySNFunctions(ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof AnteriorFunction) {
if (((AnteriorFunction) fl.get(i)).getVariable() == null) {
if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return true;
}
}
@ -211,10 +264,10 @@ public class Utils {
return false;
}
public static boolean areThereOnlyEmptyNSNFunctions(ArrayList<Function> fl) {
public static boolean areThereOnlyEmptyNSNFunctions(ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof FunctionTwoValues && !(fl.get(i) instanceof Sum) && !(fl.get(i) instanceof SumSubtraction) && !(fl.get(i) instanceof Subtraction) && !(fl.get(i) instanceof Multiplication) && !(fl.get(i) instanceof Division)) {
if (((FunctionTwoValues) fl.get(i)).getVariable1() == null && ((FunctionTwoValues) fl.get(i)).getVariable2() == null) {
if (fl.get(i) instanceof FunctionOperator && !(fl.get(i) instanceof Sum) && !(fl.get(i) instanceof SumSubtraction) && !(fl.get(i) instanceof Subtraction) && !(fl.get(i) instanceof Multiplication) && !(fl.get(i) instanceof Division)) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null && ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return true;
}
}
@ -222,10 +275,10 @@ public class Utils {
return false;
}
public static boolean areThereEmptyMultiplications(ArrayList<Function> fl) {
public static boolean areThereEmptyMultiplications(ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division) {
if (((FunctionTwoValues) fl.get(i)).getVariable1() == null && ((FunctionTwoValues) fl.get(i)).getVariable2() == null) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null && ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return true;
}
}
@ -233,10 +286,10 @@ public class Utils {
return false;
}
public static boolean areThereEmptySums(ArrayList<Function> fl) {
public static boolean areThereEmptySums(ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Subtraction) {
if (((FunctionTwoValues) fl.get(i)).getVariable1() == null && ((FunctionTwoValues) fl.get(i)).getVariable2() == null) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null && ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return true;
}
}
@ -244,10 +297,10 @@ public class Utils {
return false;
}
public static boolean areThereEmptySystems(ArrayList<Function> fl) {
public static boolean areThereEmptySystems(ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof EquationsSystemPart) {
if (((EquationsSystemPart) fl.get(i)).getVariable() == null) {
if (((EquationsSystemPart) fl.get(i)).getParameter() == null) {
return true;
}
}
@ -255,15 +308,15 @@ public class Utils {
return false;
}
public static boolean areThereOtherSettedUpFunctions(ArrayList<Function> fl) {
public static boolean areThereOtherSettedUpFunctions(ObjectArrayList<Function> fl) {
for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Expression || fl.get(i) instanceof AnteriorFunction || fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division)) {
if (fl.get(i) instanceof AnteriorFunction) {
if (((AnteriorFunction) fl.get(i)).getVariable() == null) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Expression || fl.get(i) instanceof FunctionSingle || fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division)) {
if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return true;
}
} else if (fl.get(i) instanceof FunctionTwoValues) {
if (((FunctionTwoValues) fl.get(i)).getVariable1() == null || ((FunctionTwoValues) fl.get(i)).getVariable2() == null) {
} else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return true;
}
} else {
@ -338,7 +391,7 @@ public class Utils {
return BigDecimalMath.divideRound(new BigDecimal(r.numer()).setScale(Utils.scale, Utils.scaleMode), new BigDecimal(r.denom()).setScale(Utils.scale, Utils.scaleMode));
}
public static boolean equalsVariables(ArrayList<Variable> variables, ArrayList<Variable> variables2) {
public static boolean equalsVariables(ObjectArrayList<Variable> variables, ObjectArrayList<Variable> variables2) {
if (variables.size() != variables2.size()) {
return false;
} else {
@ -351,21 +404,22 @@ public class Utils {
}
}
@Deprecated
public static void writeSquareRoot(Function var, int x, int y, boolean small) {
var.setSmall(small);
final int w1 = var.getWidth();
final int h1 = var.getHeight();
final int wsegno = 5;
final int hsegno = h1 + 2;
var.draw(x + wsegno, y + (hsegno - h1));
DisplayManager.renderer.glDrawLine(x + 1, y + hsegno - 3, x + 1, y + hsegno - 3);
DisplayManager.renderer.glDrawLine(x + 2, y + hsegno - 2, x + 2, y + hsegno - 2);
DisplayManager.renderer.glDrawLine(x + 3, y + hsegno - 1, x + 3, y + hsegno - 1);
DisplayManager.renderer.glDrawLine(x + 3, y + (hsegno - 1) / 2 + 1, x + 3, y + hsegno - 1);
DisplayManager.renderer.glDrawLine(x + 4, y, x + 4, y + (hsegno - 1) / 2);
DisplayManager.renderer.glDrawLine(x + 4, y, x + 4 + 1 + w1 + 1, y);
// var.setSmall(small);
// final int w1 = var.getWidth();
// final int h1 = var.getHeight();
// final int wsegno = 5;
// final int hsegno = h1 + 2;
//
// var.draw(x + wsegno, y + (hsegno - h1), null, null);
//
// DisplayManager.renderer.glDrawLine(x + 1, y + hsegno - 3, x + 1, y + hsegno - 3);
// DisplayManager.renderer.glDrawLine(x + 2, y + hsegno - 2, x + 2, y + hsegno - 2);
// DisplayManager.renderer.glDrawLine(x + 3, y + hsegno - 1, x + 3, y + hsegno - 1);
// DisplayManager.renderer.glDrawLine(x + 3, y + (hsegno - 1) / 2 + 1, x + 3, y + hsegno - 1);
// DisplayManager.renderer.glDrawLine(x + 4, y, x + 4, y + (hsegno - 1) / 2);
// DisplayManager.renderer.glDrawLine(x + 4, y, x + 4 + 1 + w1 + 1, y);
}
public static final int getFontHeight() {
@ -449,7 +503,7 @@ public class Utils {
public static boolean allSolved(List<Function> expressions) throws Error {
for (final Function itm : expressions) {
if (itm.isSolved() == false) {
if (itm.isSimplified() == false) {
return false;
}
}
@ -461,7 +515,7 @@ public class Utils {
final int size2 = l2.size();
int cur1 = 0;
int cur2 = 0;
final int total = l1.size() * l2.size();
final int total = size1 * size2;
final Function[][] results = new Function[total][2];
for (int i = 0; i < total; i++) {
results[i] = new Function[] { l1.get(cur1), l2.get(cur2) };
@ -481,6 +535,44 @@ public class Utils {
return results;
}
public static Function[][] joinFunctionsResults(ObjectArrayList<ObjectArrayList<Function>> ln) {
final int[] sizes = new int[ln.size()];
for (int i = 0; i < ln.size(); i++) {
sizes[i] = ln.get(i).size();
}
final int[] curs = new int[sizes.length];
int total = 0;
for (int i = 0; i < ln.size(); i++) {
if (i == 0) {
total = sizes[i];
} else {
total *= sizes[i];
}
}
final Function[][] results = new Function[total][sizes.length];
for (int i = 0; i < total; i++) {
results[i] = new Function[sizes.length];
for (int j = 0; j < sizes.length; j++) {
results[i][j] = ln.get(j).get(curs[j]);
}
for (int k = 0; k < sizes.length; k++) {
if (i % sizes[k] == 0) {
for (int l = 0; l < sizes.length; l++) {
if (l != k) {
curs[l] += 1;
}
}
}
}
for (int k = 0; k < sizes.length; k++) {
if (curs[k] >= sizes[k]) {
curs[k] = 0;
}
}
}
return results;
}
public static boolean isNegative(Function b) {
if (b instanceof Negative) {
return true;
@ -520,27 +612,27 @@ public class Utils {
public static void printSystemResourcesUsage() {
System.out.println("============");
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) {
final OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
for (final Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) {
method.setAccessible(true);
if (method.getName().startsWith("get") && Modifier.isPublic(method.getModifiers())) {
Object value;
try {
value = method.invoke(operatingSystemMXBean);
} catch (Exception e) {
} catch (final Exception e) {
value = e;
} // try
boolean percent = false;
boolean mb = false;
String displayName = method.getName();
String displayValue = value.toString();
final String displayName = method.getName();
final String displayValue = value.toString();
if (displayName.endsWith("CpuLoad")) {
percent = true;
}
if (displayName.endsWith("MemorySize")) {
mb = true;
}
ArrayList<String> arr = new ArrayList<>();
final ObjectArrayList<String> arr = new ObjectArrayList<>();
arr.add("getFreePhysicalMemorySize");
arr.add("getProcessCpuLoad");
arr.add("getSystemCpuLoad");
@ -549,13 +641,13 @@ public class Utils {
if (percent) {
try {
System.out.println(displayName + " = " + (((int) (Float.parseFloat(displayValue) * 10000f)) / 100f) + "%");
}catch(Exception ex) {
} catch (final Exception ex) {
System.out.println(displayName + " = " + displayValue);
}
} else if (mb) {
try {
System.out.println(displayName + " = " + (Long.parseLong(displayValue) / 1024L / 1024L) + " MB");
}catch(Exception ex) {
} catch (final Exception ex) {
System.out.println(displayName + " = " + displayValue);
}
} else {
@ -570,8 +662,7 @@ public class Utils {
public static boolean isRunningOnRaspberry() {
if (System.getProperty("os.name").equals("Linux")) {
final File file = new File("/etc", "os-release");
try (FileInputStream fis = new FileInputStream(file);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis))) {
try (FileInputStream fis = new FileInputStream(file); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis))) {
String string;
while ((string = bufferedReader.readLine()) != null) {
if (string.toLowerCase().contains("raspbian")) {

View File

@ -0,0 +1,88 @@
package org.warp.picalculator.device;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;
import org.warp.picalculator.Main;
public class CacheFile {
private String path;
private ObjectOutputStream lastOOS;
private FileOutputStream lastFOS;
private ObjectInputStream lastOIS;
private FileInputStream lastFIS;
public CacheFile() {
do {
path = UUID.randomUUID().toString()+".ser";
} while (Files.exists(Paths.get(path)));
try {
Files.createTempFile(Main.calculatorNameLOWER, "");
} catch (IOException e) {
e.printStackTrace();
}
}
public ObjectOutputStream getObjectOutputStram() {
if (lastOOS == null) {
try {
return new ObjectOutputStream(new FileOutputStream(path));
} catch (IOException e) {
e.printStackTrace();
return lastOOS;
}
} else {
return lastOOS;
}
}
public ObjectInputStream getObjectInputStram() {
if (lastOIS == null) {
try {
return new ObjectInputStream(new FileInputStream(path));
} catch (IOException e) {
return lastOIS;
}
} else {
return lastOIS;
}
}
public void closeStreams() {
try {
if (lastOOS != null) {
lastOOS.close();
lastOOS = null;
}
if (lastFOS != null) {
lastFOS.close();
lastFOS = null;
}
if (lastOIS != null) {
lastOIS.close();
lastOIS = null;
}
if (lastFIS != null) {
lastFIS.close();
lastFIS = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void dispose() {
closeStreams();
try {
Files.deleteIfExists(Paths.get(path));
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -6,6 +6,7 @@ import org.warp.picalculator.Utils;
import org.warp.picalculator.device.chip.ParallelToSerial;
import org.warp.picalculator.device.chip.SerialToParallel;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.GUIErrorMessage;
import org.warp.picalculator.gui.screens.KeyboardDebugScreen;
import org.warp.picalculator.gui.screens.MarioScreen;
import org.warp.picalculator.gui.screens.Screen;
@ -32,7 +33,9 @@ public class Keyboard {
private static volatile boolean refreshRequest = false;
public static void startKeyboard() {
private static KeyboardEventListener additionalListener;
public synchronized static void startKeyboard() {
final Thread kt = new Thread(() -> {
if (Utils.debugOn) {
try {
@ -94,7 +97,7 @@ public class Keyboard {
kt.start();
}
private static void debugKeyPressed(int keyCode) {
private synchronized static void debugKeyPressed(int keyCode) {
switch (keyCode) {
case KeyEvent.VK_ESCAPE:
Keyboard.keyPressed(Key.POWER);
@ -398,7 +401,7 @@ public class Keyboard {
}
}
private static void keyReleasedRaw(int row, int col) {
private synchronized static void keyReleasedRaw(int row, int col) {
KeyboardDebugScreen.keyX = row;
KeyboardDebugScreen.keyY = col;
if (row == 1 && col == 1) {
@ -406,7 +409,7 @@ public class Keyboard {
}
}
static void keyPressedRaw(int row, int col) {
static synchronized void keyPressedRaw(int row, int col) {
KeyboardDebugScreen.keyX = row;
KeyboardDebugScreen.keyY = col;
if (row == 1 && col == 1) {
@ -695,11 +698,25 @@ public class Keyboard {
}
}
public static void keyPressed(Key k) {
public synchronized static void keyPressed(Key k) {
boolean done = false;
if (additionalListener != null) {
try {
done = additionalListener.keyPressed(k);
} catch (final Exception ex) {
new GUIErrorMessage(ex);
}
}
if (DisplayManager.INSTANCE != null) {
final Screen scr = DisplayManager.INSTANCE.getScreen();
boolean refresh = false;
if (scr != null && scr.initialized && scr.keyPressed(k)) {
boolean scrdone = false;
try {
scrdone = scr.keyPressed(k);
} catch (final Exception ex) {
new GUIErrorMessage(ex);
}
if (scr != null && scr.initialized && scrdone) {
refresh = true;
} else {
switch (k) {
@ -716,7 +733,7 @@ public class Keyboard {
refresh = true;
break;
case BRIGHTNESS_CYCLE_REVERSE:
DisplayManager.INSTANCE.setScreen(new MarioScreen()); //TODO: rimuovere: prova
// DisplayManager.INSTANCE.setScreen(new MarioScreen()); //TODO: rimuovere: prova
DisplayManager.cycleBrightness(true);
refresh = true;
break;
@ -756,6 +773,8 @@ public class Keyboard {
if (refresh) {
refreshRequest = true;
}
} else if (!done) {
Utils.debug.println("Key " + k.toString() + " ignored.");
}
}
@ -763,7 +782,11 @@ public class Keyboard {
}
public static void keyReleased(Key k) {
public synchronized static void keyReleased(Key k) {
boolean done = false;
if (additionalListener != null) {
done = additionalListener.keyReleased(k);
}
boolean refresh = false;
if (DisplayManager.INSTANCE != null) {
final Screen scr = DisplayManager.INSTANCE.getScreen();
@ -778,9 +801,15 @@ public class Keyboard {
}
}
if (refresh) {
// PIDisplay.display.repaint();
refreshRequest = true;
}
} else if (!done) {
Utils.debug.println("Key " + k.toString() + " ignored.");
}
}
public static void setAdditionalKeyboardListener(KeyboardEventListener l) {
additionalListener = l;
}
public static enum Key {

View File

@ -0,0 +1,13 @@
package org.warp.picalculator.device;
import org.warp.picalculator.device.Keyboard.Key;
public interface KeyboardEventListener {
public default boolean keyPressed(Key k) {
return false;
}
public default boolean keyReleased(Key k) {
return false;
}
}

View File

@ -25,16 +25,6 @@ import org.warp.picalculator.device.graphicengine.RAWFont;
import org.warp.picalculator.device.graphicengine.Screen;
import com.pi4j.wiringpi.Gpio;
/**
* STB Truetype oversampling demo.
*
* <p>
* This is a Java port of <a href=
* "https://github.com/nothings/stb/blob/master/tests/oversample/main.c">https:/
* /github
* .com/nothings/stb/blob/master/tests/oversample/main.c</a>.
* </p>
*/
public final class PIDisplay {
public static PIDisplay INSTANCE;
private static float brightness;

View File

@ -33,13 +33,13 @@ public class RAWFont {
public void create(String name) {
try {
loadFont("/font_" + name + ".rft");
} catch (IOException e) {
} catch (final IOException e) {
e.printStackTrace();
System.exit(1);
}
chars32 = new int[(maxBound - minBound) * charIntCount];
for (int charIndex = 0; charIndex < maxBound - minBound; charIndex++) {
boolean[] currentChar = rawchars[charIndex];
final boolean[] currentChar = rawchars[charIndex];
if (currentChar == null) {
int currentInt = 0;
int currentBit = 0;
@ -66,7 +66,7 @@ public class RAWFont {
}
Object obj = new Object();
WeakReference<Object> ref = new WeakReference<>(obj);
final WeakReference<Object> ref = new WeakReference<>(obj);
obj = null;
while (ref.get() != null) {
System.gc();
@ -74,9 +74,9 @@ public class RAWFont {
}
private void loadFont(String string) throws IOException {
URL res = Main.instance.getClass().getResource(string);
int[] file = Utils.realBytes(Utils.convertStreamToByteArray(res.openStream(), res.getFile().length()));
int filelength = file.length;
final URL res = Main.instance.getClass().getResource(string);
final int[] file = Utils.realBytes(Utils.convertStreamToByteArray(res.openStream(), res.getFile().length()));
final int filelength = file.length;
if (filelength >= 16) {
if (file[0x0] == 114 && file[0x1] == 97 && file[0x2] == 119 && file[0x3] == 0xFF && file[0x8] == 0xFF && file[0xD] == 0xFF) {
charW = file[0x4] << 8 | file[0x5];
@ -92,8 +92,8 @@ public class RAWFont {
int index = 0x12;
while (index < filelength) {
try {
int charIndex = file[index] << 8 | file[index+1];
boolean[] rawchar = new boolean[charS];
final int charIndex = file[index] << 8 | file[index + 1];
final boolean[] rawchar = new boolean[charS];
int charbytescount = 0;
while (charbytescount * 8 < charS) {
charbytescount += 1;
@ -110,8 +110,7 @@ public class RAWFont {
}
rawchars[charIndex - minBound] = rawchar;
index += 2 + charbytescount;
}
catch (Exception ex) {
} catch (final Exception ex) {
ex.printStackTrace();
System.out.println(string);
System.exit(-1);
@ -127,8 +126,8 @@ public class RAWFont {
public int[] getCharIndexes(String txt) {
final int l = txt.length();
int[] indexes = new int[l];
char[] chars = txt.toCharArray();
final int[] indexes = new int[l];
final char[] chars = txt.toCharArray();
for (int i = 0; i < l; i++) {
indexes[i] = (chars[i] & 0xFFFF) - minBound;
}
@ -137,12 +136,12 @@ public class RAWFont {
@SuppressWarnings("unused")
private void saveArray(int[] screen, String coutputpng) {
BufferedImage bi = new BufferedImage(300, 200, BufferedImage.TYPE_INT_RGB);
final BufferedImage bi = new BufferedImage(300, 200, BufferedImage.TYPE_INT_RGB);
final int[] a = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
System.arraycopy(screen, 0, a, 0, screen.length);
try {
ImageIO.write(bi, "PNG", new File(coutputpng));
} catch (IOException ex) {
} catch (final IOException ex) {
Logger.getLogger(RAWFont.class.getName()).log(Level.SEVERE, null, ex);
}
}
@ -151,7 +150,6 @@ public class RAWFont {
final int screenLength = screen.length;
int screenPos = 0;
int currentInt;
int currentIntBitPosition;
int bitData;
@ -165,7 +163,7 @@ public class RAWFont {
for (int dx = 0; dx < charW; dx++) {
j = x + cpos + dx;
if (j > 0 & j < screenSize[0]) {
int bit = dx + dy * charW;
final int bit = dx + dy * charW;
currentInt = (int) (Math.floor(bit) / (intBits));
currentIntBitPosition = bit - (currentInt * intBits);
bitData = (chars32[charIndex * charIntCount + currentInt] >> currentIntBitPosition) & 1;

View File

@ -1,11 +1,7 @@
package org.warp.picalculator.gui;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Main;
import org.warp.picalculator.Utils;
@ -38,6 +34,7 @@ public final class DisplayManager implements RenderingLoop {
public static Screen screen;
public static String displayDebugString = "";
public static ObjectArrayList<GUIErrorMessage> errorMessages = new ObjectArrayList<>();
public DisplayManager(Screen screen) {
setScreen(screen);
@ -372,7 +369,7 @@ public final class DisplayManager implements RenderingLoop {
}
//Working thread
Thread workThread = new Thread(() -> {
final Thread workThread = new Thread(() -> {
try {
while (true) {
float dt = 0;
@ -413,7 +410,7 @@ public final class DisplayManager implements RenderingLoop {
// if (displayName.endsWith("MemorySize")) {
// mb = true;
// }
// ArrayList<String> arr = new ArrayList<>();
// ObjectArrayList<String> arr = new ObjectArrayList<>();
// arr.add("getFreePhysicalMemorySize");
// arr.add("getProcessCpuLoad");
// arr.add("getSystemCpuLoad");
@ -449,7 +446,7 @@ public final class DisplayManager implements RenderingLoop {
workThread.setName("Work thread");
workThread.start();
engine.start(this);
engine.start(getDrawable());
engine.waitUntilExit();
} catch (final Exception ex) {

View File

@ -0,0 +1,36 @@
package org.warp.picalculator.gui;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.Error;
public class GUIErrorMessage {
private final String err;
private final long creationTime;
public GUIErrorMessage(Error e) {
err = e.getLocalizedMessage();
creationTime = System.currentTimeMillis();
}
public GUIErrorMessage(Exception ex) {
err = ex.getLocalizedMessage();
creationTime = System.currentTimeMillis();
}
public void draw(GraphicEngine g, Renderer r, String msg) {
final int scrW = g.getWidth();
final int scrH = g.getHeight();
final int width = 200;
final int height = 20;
final int margin = 4;
r.glClearSkin();
r.glColor(0x00000000);
r.glFillRect(scrW - width - margin, scrH - height - margin, width, height, 0, 0, 0, 0);
}
public long getCreationTime() {
return creationTime;
}
}

View File

@ -1,23 +1,19 @@
package org.warp.picalculator.gui;
public class GraphicUtils {
public static final float sin(float rad)
{
public static final float sin(float rad) {
return sin[(int) (rad * radToIndex) & SIN_MASK];
}
public static final float cos(float rad)
{
public static final float cos(float rad) {
return cos[(int) (rad * radToIndex) & SIN_MASK];
}
public static final float sinDeg(float deg)
{
public static final float sinDeg(float deg) {
return sin[(int) (deg * degToIndex) & SIN_MASK];
}
public static final float cosDeg(float deg)
{
public static final float cosDeg(float deg) {
return cos[(int) (deg * degToIndex) & SIN_MASK];
}
@ -27,8 +23,7 @@ public class GraphicUtils {
private static final float degFull, degToIndex;
private static final float[] sin, cos;
static
{
static {
RAD = (float) Math.PI / 180.0f;
DEG = 180.0f / (float) Math.PI;
@ -44,15 +39,13 @@ public class GraphicUtils {
sin = new float[SIN_COUNT];
cos = new float[SIN_COUNT];
for (int i = 0; i < SIN_COUNT; i++)
{
for (int i = 0; i < SIN_COUNT; i++) {
sin[i] = (float) Math.sin((i + 0.5f) / SIN_COUNT * radFull);
cos[i] = (float) Math.cos((i + 0.5f) / SIN_COUNT * radFull);
}
// Four cardinal directions (credits: Nate)
for (int i = 0; i < 360; i += 90)
{
for (int i = 0; i < 360; i += 90) {
sin[(int) (i * degToIndex) & SIN_MASK] = (float) Math.sin(i * Math.PI / 180.0);
cos[(int) (i * degToIndex) & SIN_MASK] = (float) Math.cos(i * Math.PI / 180.0);
}

View File

@ -0,0 +1,30 @@
package org.warp.picalculator.gui;
public interface GraphicalElement {
/**
* Recompute element's dimension parameters, like <strong>width</strong>,
* <strong>height</strong>, <strong>line</strong> or
* <strong>length</strong>.
*/
public void recomputeDimensions();
/**
*
* @return Width of the element.
*/
public int getWidth();
/**
*
* @return Height of the element.
*/
public int getHeight();
/**
*
* @return Position of the vertical alignment line of the element, relative
* to itself.
*/
public int getLine();
}

View File

@ -0,0 +1,52 @@
package org.warp.picalculator.gui.expression;
public class Caret {
private int pos;
private int remaining;
private CaretState state;
public Caret(CaretState state, int pos) {
this.state = state;
this.pos = pos;
remaining = pos;
}
public void skip(int i) {
remaining -= i;
}
public int getPosition() {
return pos;
}
public int getRemaining() {
return remaining;
}
public CaretState getState() {
return state;
}
public void flipState() {
if (state == CaretState.VISIBLE_ON) {
state = CaretState.VISIBLE_OFF;
} else if (state == CaretState.VISIBLE_OFF) {
state = CaretState.VISIBLE_ON;
}
}
public void turnOn() {
if (state == CaretState.VISIBLE_OFF) {
state = CaretState.VISIBLE_ON;
}
}
public void setPosition(int i) {
pos = i;
}
public void resetRemaining() {
remaining = pos;
}
}

View File

@ -0,0 +1,5 @@
package org.warp.picalculator.gui.expression;
public enum CaretState {
VISIBLE_ON, VISIBLE_OFF, HIDDEN
}

View File

@ -0,0 +1,58 @@
package org.warp.picalculator.gui.expression.blocks;
import org.warp.picalculator.gui.GraphicalElement;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public abstract class Block implements GraphicalElement {
protected boolean small;
protected int width;
protected int height;
protected int line;
/**
*
* @param r
* Graphic Renderer class.
* @param x
* Position relative to the window.
* @param y
* Position relative to the window.
* @param small
*/
public abstract void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret);
public abstract boolean putBlock(Caret caret, Block newBlock);
public abstract boolean delBlock(Caret caret);
@Override
public abstract void recomputeDimensions();
public abstract int computeCaretMaxBound();
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
public boolean isSmall() {
return small;
}
public abstract void setSmall(boolean small);
public abstract int getClassID();
}

View File

@ -0,0 +1,62 @@
package org.warp.picalculator.gui.expression.blocks;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public class BlockChar extends Block {
public static final int CLASS_ID = 0x00000001;
private final char ch;
public BlockChar(char ch) {
this.ch = ch;
recomputeDimensions();
}
@Override
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
r.glDrawCharLeft(x, y, ch);
}
@Override
public boolean putBlock(Caret caret, Block newBlock) {
return false;
}
@Override
public boolean delBlock(Caret caret) {
return false;
}
@Override
public void recomputeDimensions() {
width = BlockContainer.getDefaultCharWidth(small);
height = BlockContainer.getDefaultCharHeight(small);
line = height / 2;
}
@Override
public void setSmall(boolean small) {
this.small = small;
recomputeDimensions();
}
public char getChar() {
return ch;
}
@Override
public int getClassID() {
return CLASS_ID;
}
@Override
public int computeCaretMaxBound() {
return 0;
}
}

View File

@ -0,0 +1,318 @@
package org.warp.picalculator.gui.expression.blocks;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.gui.GraphicalElement;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.expression.CaretState;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public class BlockContainer implements GraphicalElement {
private static boolean initialized = false;
private int minWidth;
private int minHeight;
private final ObjectArrayList<Block> content;
private boolean small;
private int width;
private int height;
private int line;
public final boolean withBorder;
private boolean autoMinimums;
public BlockContainer() {
this(false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true);
autoMinimums = true;
}
public BlockContainer(boolean small) {
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true);
autoMinimums = true;
}
public BlockContainer(boolean small, boolean withBorder) {
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder);
autoMinimums = true;
}
public BlockContainer(boolean small, int minWidth, int minHeight, boolean withBorder) {
this(small, minWidth, minHeight, new ObjectArrayList<>(), withBorder);
autoMinimums = false;
}
public BlockContainer(boolean small, int minWidth, int minHeight, ObjectArrayList<Block> content, boolean withBorder) {
this.small = small;
this.minWidth = minWidth;
this.minHeight = minHeight;
this.withBorder = withBorder;
for (final Block b : content) {
if (b.isSmall() != small) {
b.setSmall(small);
}
}
this.content = content;
recomputeDimensions();
}
public void addBlock(int position, Block b) {
if (b.isSmall() != small) {
b.setSmall(small);
}
if (position >= content.size()) {
content.add(b);
} else {
content.add(position, b);
}
recomputeDimensions();
}
public void appendBlock(Block b) {
appendBlockUnsafe(b);
recomputeDimensions();
}
public void appendBlockUnsafe(Block b) {
if (b.isSmall() != small) {
b.setSmall(small);
}
content.add(b);
}
public void removeBlock(Block b) {
content.remove(b);
recomputeDimensions();
}
public void removeAt(int i) {
content.remove(i);
recomputeDimensions();
}
public Block getBlockAt(int i) {
return content.get(i);
}
public void clear() {
content.clear();
recomputeDimensions();
}
/**
*
* @param ge
* Graphic Engine class.
* @param r
* Graphic Renderer class of <b>ge</b>.
* @param x
* Position relative to the window.
* @param y
* Position relative to the window.
* @param caret
* Position of the caret.
*/
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
int paddingX = 1;
if (caret.getRemaining() == 0) {
if (content.size() > 0) {
BlockContainer.drawCaret(ge, r, caret, small, x, y + line - content.get(0).line, content.get(0).height);
} else {
BlockContainer.drawCaret(ge, r, caret, small, x, y, height);
}
}
if (withBorder && content.size() == 0) {
r.glDrawLine(x + paddingX, y, x + paddingX + width - 1, y);
r.glDrawLine(x + paddingX, y, x + paddingX, y + height - 1);
r.glDrawLine(x + paddingX + width - 1, y, x + paddingX + width - 1, y + height - 1);
r.glDrawLine(x + paddingX, y + height - 1, x + paddingX + width - 1, y + height - 1);
} else {
for (final Block b : content) {
caret.skip(1);
b.draw(ge, r, x + paddingX, y + line - b.line, caret);
paddingX += b.getWidth();
if (caret.getRemaining() == 0) {
BlockContainer.drawCaret(ge, r, caret, small, x + paddingX, y + line - b.line, b.height);
}
paddingX += 1;
}
}
caret.skip(1);
}
public boolean putBlock(Caret caret, Block newBlock) {
boolean added = false;
if (caret.getRemaining() == 0) {
addBlock(0, newBlock);
added = true;
}
int pos = 0;
for (final Block b : content) {
caret.skip(1);
pos++;
added = added | b.putBlock(caret, newBlock);
if (caret.getRemaining() == 0) {
addBlock(pos, newBlock);
added = true;
}
}
caret.skip(1);
if (added) {
recomputeDimensions();
}
return added;
}
public boolean delBlock(Caret caret) {
boolean removed = false;
int pos = 0;
for (final Block b : content) {
caret.skip(1);
pos++;
final int deltaCaret = caret.getRemaining();
removed = removed | b.delBlock(caret);
if (caret.getRemaining() == 0 || (removed == false && deltaCaret >= 0 && caret.getRemaining() < 0)) {
removeAt(pos - 1);
caret.setPosition(caret.getPosition() - deltaCaret);
removed = true;
}
}
caret.skip(1);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public void recomputeDimensions() {
int l = 0; //Line
int w = 0; //Width
int h2 = 0; //Height under the line. h = h2 + l
int h = 0; //Height
for (final Block b : content) {
w += b.getWidth() + 1;
final int bl = b.getLine();
final int bh = b.getHeight();
final int bh2 = bh - bl;
if (bl > l) {
l = bl;
}
if (bh2 > h2) {
h2 = bh2;
}
}
if (content.size() > 0) {
w -= 1;
}
h = h2 + l;
line = l;
if (w > minWidth) {
width = w;
} else {
width = minWidth;
}
if (h > minHeight) {
height = h;
} else {
height = minHeight;
line = height / 2;
}
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
private static final BinaryFont[] defFonts = new BinaryFont[2];
private static final int[] defFontSizes = new int[4];
private static final int defColor = 0xFF000000;
public static void initializeFonts(BinaryFont big, BinaryFont small) {
defFonts[0] = big;
defFonts[1] = small;
defFontSizes[0] = big.getCharacterWidth();
defFontSizes[1] = big.getCharacterHeight();
defFontSizes[2] = small.getCharacterWidth();
defFontSizes[3] = small.getCharacterHeight();
initialized = true;
}
public static BinaryFont getDefaultFont(boolean small) {
checkInitialized();
return defFonts[small ? 1 : 0];
}
public static int getDefaultColor() {
return defColor;
}
public static int getDefaultCharWidth(boolean b) {
checkInitialized();
return defFontSizes[b ? 2 : 0];
}
public static int getDefaultCharHeight(boolean b) {
checkInitialized();
return defFontSizes[b ? 3 : 1];
}
public static void drawCaret(GraphicEngine ge, Renderer r, Caret caret, boolean small, int x, int y, int height) {
if (caret.getState() == CaretState.VISIBLE_ON) {
r.glColor(getDefaultColor());
r.glFillColor(x, y, small?2:3, height);
}
}
public void setSmall(boolean small) {
this.small = small;
if (this.autoMinimums) {
this.minWidth = BlockContainer.getDefaultCharWidth(small);
this.minHeight = BlockContainer.getDefaultCharHeight(small);
}
for (Block b : this.content) {
b.setSmall(small);
}
recomputeDimensions();
}
public ObjectArrayList<Block> getContent() {
return content.clone();
}
private static void checkInitialized() {
if (!initialized) {
throw new ExceptionInInitializerError("Please initialize BlockContainer by running the method BlockContainer.initialize(...) first!");
}
}
public int computeCaretMaxBound() {
int maxpos = 0;
for (final Block b : content) {
maxpos += 1 + b.computeCaretMaxBound();
}
return maxpos + 1;
}
}

View File

@ -0,0 +1,104 @@
package org.warp.picalculator.gui.expression.blocks;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public class BlockDivision extends Block {
public static final int CLASS_ID = 0x00000002;
private final BlockContainer containerUp;
private final BlockContainer containerDown;
private int paddingLeftUpper;
private int paddingLeftLower;
private int h1;
public BlockDivision() {
containerUp = new BlockContainer(false);
containerDown = new BlockContainer(false);
recomputeDimensions();
}
@Override
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
containerUp.draw(ge, r, x + 1 + paddingLeftUpper, y, caret);
r.glDrawLine(x, y + h1 + 1, x + width - 1, y + h1 + 1);
containerDown.draw(ge, r, x + 1 + paddingLeftLower, y + h1 + 3, caret);
}
@Override
public boolean putBlock(Caret caret, Block newBlock) {
boolean added = false;
added = added | containerUp.putBlock(caret, newBlock);
added = added | containerDown.putBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(Caret caret) {
boolean removed = false;
removed = removed | containerUp.delBlock(caret);
removed = removed | containerDown.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public void recomputeDimensions() {
final int w1 = containerUp.getWidth();
final int w2 = containerDown.getWidth();
final int h1 = containerUp.getHeight();
final int h2 = containerDown.getHeight();
width = (w1 > w2 ? w1 : w2) + 4;
height = h1 + 3 + h2;
line = h1 + 1;
this.h1 = h1;
if (w1 != w2) {
if (w1 > w2) {
paddingLeftUpper = 0;
paddingLeftLower = (w1 - w2) / 2;
} else {
paddingLeftUpper = (w2 - w1) / 2;
paddingLeftLower = 0;
}
} else {
paddingLeftUpper = 0;
paddingLeftLower = 0;
}
}
@Override
public void setSmall(boolean small) {
this.small = small;
containerUp.setSmall(small);
containerDown.setSmall(small);
recomputeDimensions();
}
public BlockContainer getUpperContainer() {
return containerUp;
}
public BlockContainer getLowerContainer() {
return containerDown;
}
@Override
public int getClassID() {
return CLASS_ID;
}
@Override
public int computeCaretMaxBound() {
return containerUp.computeCaretMaxBound() + containerDown.computeCaretMaxBound();
}
}

View File

@ -0,0 +1,26 @@
package org.warp.picalculator.gui.expression.blocks;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public class BlockExponentialNotation extends BlockPower {
private int bw;
private int bh;
@Override
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
r.glDrawStringLeft(x, y+height-bh, "");
super.draw(ge, r, x+bw, y, caret);
}
@Override
public void recomputeDimensions() {
super.recomputeDimensions();
bw = (int) (BlockContainer.getDefaultCharWidth(small)*1.5);
bh = BlockContainer.getDefaultCharHeight(small);
this.width+=bw;
}
}

View File

@ -0,0 +1,85 @@
package org.warp.picalculator.gui.expression.blocks;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public class BlockParenthesis extends Block {
public static final int CLASS_ID = 0x00000004;
private final BlockContainer containerNumber;
private int chw;
private int chh;
public BlockParenthesis() {
containerNumber = new BlockContainer(false);
recomputeDimensions();
}
@Override
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
r.glDrawCharLeft(x, y, '╭');
r.glDrawCharLeft(x, y+height-chh, '╰');
r.glFillColor(x+3, y+6, 2, height-6*2);
r.glFillColor(x+width-5, y+6, 2, height-6*2);
r.glDrawCharLeft(x+width-chw, y, '╮');
r.glDrawCharLeft(x+width-chw, y+height-chh, '╯');
containerNumber.draw(ge, r, x+chw, y, caret);
}
@Override
public boolean putBlock(Caret caret, Block newBlock) {
boolean added = false;
added = added | containerNumber.putBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(Caret caret) {
boolean removed = false;
removed = removed | containerNumber.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public void recomputeDimensions() {
chw = BlockContainer.getDefaultCharWidth(small);
chh = BlockContainer.getDefaultCharHeight(small);
width = containerNumber.getWidth() + chw * 2 + 3;
height = containerNumber.getHeight();
line = containerNumber.getLine();
}
@Override
public void setSmall(boolean small) {
this.small = small;
containerNumber.setSmall(small);
recomputeDimensions();
}
public BlockContainer getNumberContainer() {
return containerNumber;
}
@Override
public int getClassID() {
return CLASS_ID;
}
@Override
public int computeCaretMaxBound() {
return containerNumber.computeCaretMaxBound();
}
}

View File

@ -0,0 +1,77 @@
package org.warp.picalculator.gui.expression.blocks;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.expression.blocks.Block;
import org.warp.picalculator.gui.expression.blocks.BlockContainer;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public class BlockPower extends Block {
public static final int CLASS_ID = 0x00000005;
private final BlockContainer containerExponent;
public BlockPower() {
containerExponent = new BlockContainer(true);
recomputeDimensions();
}
@Override
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(true).use(ge);
r.glColor(BlockContainer.getDefaultColor());
containerExponent.draw(ge, r, x, y, caret);
}
@Override
public boolean putBlock(Caret caret, Block newBlock) {
boolean added = false;
added = added | containerExponent.putBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(Caret caret) {
boolean removed = false;
removed = removed | containerExponent.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public void recomputeDimensions() {
final int w2 = containerExponent.getWidth();
final int h2 = containerExponent.getHeight();
final int l2 = containerExponent.getLine();
width = w2+1;
height = h2+BlockContainer.getDefaultCharHeight(small)-3;
line = h2+BlockContainer.getDefaultCharHeight(small)/2-3;
}
@Override
public void setSmall(boolean small) {
this.small = small;
containerExponent.setSmall(true);
recomputeDimensions();
}
public BlockContainer getExponentContainer() {
return containerExponent;
}
@Override
public int getClassID() {
return CLASS_ID;
}
@Override
public int computeCaretMaxBound() {
return containerExponent.computeCaretMaxBound();
}
}

View File

@ -0,0 +1,89 @@
package org.warp.picalculator.gui.expression.blocks;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public class BlockSquareRoot extends Block {
public static final int CLASS_ID = 0x00000003;
private final BlockContainer containerNumber;
private int h1;
public BlockSquareRoot() {
containerNumber = new BlockContainer(false);
recomputeDimensions();
}
@Override
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
r.glDrawLine(x, y + height - 10 + 1, x, y + height - 10 + 2); // /
r.glDrawLine(x + 1, y + height - 10, x + 1, y + height - 10 + 1); // /
r.glDrawLine(x + 2, y + height - 10 + 2, x + 2, y + height - 10 + 6); // \
r.glDrawLine(x + 3, y + height - 10 + 7, x + 3, y + height - 10 + 9); // \
r.glDrawLine(x + 5, y + height - h1 - 1 - 2, x + width - 1, y + height - h1 - 1 - 2); // ----
r.glDrawLine(x + 5, y + height - h1 - 1 - 2, x + 5, y + height - (h1 - 2) / 3f * 2f - 1); // |
r.glDrawLine(x + 4, y + height - (h1 - 2) / 3f * 2f - 1, x + 4, y + height - (h1 - 2) / 3f - 1); // |
r.glDrawLine(x + 3, y + height - (h1 - 2) / 3f - 1, x + 3, y + height - 1); // |
containerNumber.draw(ge, r, x + 7, y + 3, caret);
}
@Override
public boolean putBlock(Caret caret, Block newBlock) {
boolean added = false;
added = added | containerNumber.putBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(Caret caret) {
boolean removed = false;
removed = removed | containerNumber.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public void recomputeDimensions() {
final int w1 = containerNumber.getWidth();
h1 = containerNumber.getHeight();
final int l1 = containerNumber.getLine();
width = 8 + w1 + 2;
height = 3 + h1;
line = 3 + l1;
if (height < 9) {
height = 9;
line += (9 - (3 + h1));
}
}
@Override
public void setSmall(boolean small) {
this.small = small;
containerNumber.setSmall(small);
recomputeDimensions();
}
public BlockContainer getNumberContainer() {
return containerNumber;
}
@Override
public int getClassID() {
return CLASS_ID;
}
@Override
public int computeCaretMaxBound() {
return containerNumber.computeCaretMaxBound();
}
}

View File

@ -0,0 +1,25 @@
package org.warp.picalculator.gui.expression.containers;
import org.warp.picalculator.gui.expression.blocks.Block;
import org.warp.picalculator.gui.expression.blocks.BlockChar;
import org.warp.picalculator.math.MathematicalSymbols;
public class InlineInputContainer extends InputContainer {
public InlineInputContainer() {
super();
}
public InlineInputContainer(boolean small) {
super(small);
}
public InlineInputContainer(boolean small, int minWidth, int minHeight) {
super(small, minWidth, minHeight);
}
@Override
public Block parseChar(char c) {
return new BlockChar(MathematicalSymbols.DIVISION);
}
}

View File

@ -0,0 +1,190 @@
package org.warp.picalculator.gui.expression.containers;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.warp.picalculator.gui.GraphicalElement;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.expression.CaretState;
import org.warp.picalculator.gui.expression.blocks.Block;
import org.warp.picalculator.gui.expression.blocks.BlockContainer;
import org.warp.picalculator.gui.expression.layouts.InputLayout;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
import it.unimi.dsi.fastutil.Arrays;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public abstract class InputContainer implements GraphicalElement, InputLayout, Serializable {
private static final long serialVersionUID = 923589369317765667L;
private final BlockContainer root;
private Caret caret;
private static final float CARET_DURATION = 0.5f;
private float caretTime;
private int maxPosition = 0;
private boolean parsed = false;
public InputContainer() {
caret = new Caret(CaretState.VISIBLE_ON, 0);
root = new BlockContainer(false, false);
}
public InputContainer(boolean small) {
caret = new Caret(CaretState.VISIBLE_ON, 0);
root = new BlockContainer(small, false);
}
public InputContainer(boolean small, int minWidth, int minHeight) {
caret = new Caret(CaretState.VISIBLE_ON, 0);
root = new BlockContainer(small, false);
}
public void typeChar(char c) {
final Block b = parseChar(c);
if (b != null) {
caret.resetRemaining();
if (root.putBlock(caret, b)) {
caret.setPosition(caret.getPosition() + 1);
maxPosition = root.computeCaretMaxBound();
root.recomputeDimensions();
}
}
caretTime = 0;
caret.turnOn();
}
public void typeChar(String c) {
typeChar(c.charAt(0));
}
public void del() {
caret.resetRemaining();
if (root.delBlock(caret)) {
root.recomputeDimensions();
}
if (caret.getPosition() > 0) {
caret.setPosition(caret.getPosition() - 1);
maxPosition = root.computeCaretMaxBound();
}
caret.turnOn();
caretTime = 0;
}
public void moveLeft() {
final int curPos = caret.getPosition();
if (curPos > 0) {
caret.setPosition(curPos - 1);
} else {
caret.setPosition(maxPosition-1);
}
caret.turnOn();
caretTime = 0;
}
public void moveRight() {
final int curPos = caret.getPosition();
if (curPos + 1 < maxPosition) {
caret.setPosition(curPos + 1);
} else {
caret.setPosition(0);
}
caret.turnOn();
caretTime = 0;
}
@Override
public void recomputeDimensions() {
root.recomputeDimensions();
}
@Override
public int getWidth() {
return root.getWidth();
}
@Override
public int getHeight() {
return root.getHeight();
}
@Override
public int getLine() {
return root.getLine();
}
/**
*
* @param delta
* Time, in seconds
* @return true if something changed
*/
public boolean beforeRender(float delta) {
boolean somethingChanged = false;
caretTime += delta;
if (caretTime >= CARET_DURATION) {
while (caretTime >= CARET_DURATION) {
caretTime -= CARET_DURATION;
caret.flipState();
somethingChanged = true;
}
}
return somethingChanged;
}
/**
*
* @param ge
* Graphic Engine class.
* @param r
* Graphic Renderer class of <b>ge</b>.
* @param x
* Position relative to the window.
* @param y
* Position relative to the window.
*/
public void draw(GraphicEngine ge, Renderer r, int x, int y) {
caret.resetRemaining();
root.draw(ge, r, x, y, caret);
}
public void clear() {
caret = new Caret(CaretState.VISIBLE_ON, 0);
root.clear();
maxPosition = root.computeCaretMaxBound();
recomputeDimensions();
}
public boolean isEmpty() {
return maxPosition <= 1;
}
public int getCaretMaxPosition() {
return maxPosition;
}
public void setCaretPosition(int pos) {
if (pos > 0 && pos < maxPosition) {
caret.setPosition(pos);
}
caret.turnOn();
caretTime = 0;
}
public void setParsed(boolean parsed) {
this.parsed = parsed;
}
public boolean isAlreadyParsed() {
return parsed;
}
/**
* <strong>WARNING! DO NOT MODIFY THIS ARRAY!!!</strong>
*
* @return an arraylist representing the content
*/
public ObjectArrayList<Block> getContent() {
return root.getContent();
}
}

View File

@ -0,0 +1,66 @@
package org.warp.picalculator.gui.expression.containers;
import org.warp.picalculator.gui.expression.blocks.Block;
import org.warp.picalculator.gui.expression.blocks.BlockChar;
import org.warp.picalculator.gui.expression.blocks.BlockDivision;
import org.warp.picalculator.gui.expression.blocks.BlockParenthesis;
import org.warp.picalculator.gui.expression.blocks.BlockPower;
import org.warp.picalculator.gui.expression.blocks.BlockSquareRoot;
import org.warp.picalculator.math.MathematicalSymbols;
public class NormalInputContainer extends InputContainer {
public NormalInputContainer() {
super();
}
public NormalInputContainer(boolean small) {
super(small);
}
public NormalInputContainer(boolean small, int minWidth, int minHeight) {
super(small, minWidth, minHeight);
}
@Override
public Block parseChar(char c) {
switch (c) {
case MathematicalSymbols.DIVISION:
return new BlockDivision();
case MathematicalSymbols.SQUARE_ROOT:
return new BlockSquareRoot();
case MathematicalSymbols.PARENTHESIS_OPEN:
return new BlockParenthesis();
case MathematicalSymbols.PARENTHESIS_CLOSE:
return null;
case MathematicalSymbols.POWER:
case MathematicalSymbols.POWER_OF_TWO:
return new BlockPower();
case MathematicalSymbols.MULTIPLICATION:
case MathematicalSymbols.SUM:
case MathematicalSymbols.SUM_SUBTRACTION:
case MathematicalSymbols.SUBTRACTION:
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return new BlockChar(c);
default:
return new BlockChar(c);
}
}
@Override
public void typeChar(char c) {
super.typeChar(c);
if (c == MathematicalSymbols.PARENTHESIS_CLOSE) {
this.moveRight();
}
}
}

View File

@ -0,0 +1,15 @@
package org.warp.picalculator.gui.expression.containers;
public class NormalOutputContainer extends OutputContainer {
public NormalOutputContainer() {
super();
}
public NormalOutputContainer(boolean small) {
super(small);
}
public NormalOutputContainer(boolean small, int minWidth, int minHeight) {
super(small, minWidth, minHeight);
}
}

View File

@ -0,0 +1,88 @@
package org.warp.picalculator.gui.expression.containers;
import java.io.Serializable;
import org.warp.picalculator.gui.GraphicalElement;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.expression.CaretState;
import org.warp.picalculator.gui.expression.blocks.Block;
import org.warp.picalculator.gui.expression.blocks.BlockContainer;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public abstract class OutputContainer implements GraphicalElement, OutputLayout, Serializable {
private static final long serialVersionUID = -5714825964892683571L;
public final BlockContainer root;
private final Caret caret = new Caret(CaretState.HIDDEN, 0);
public OutputContainer() {
root = new BlockContainer();
}
public OutputContainer(boolean small) {
root = new BlockContainer(small);
}
public OutputContainer(boolean small, int minWidth, int minHeight) {
root = new BlockContainer(small);
}
public void setContent(ObjectArrayList<Block> blocks) {
root.clear();
for (Block b : blocks) {
root.appendBlockUnsafe(b);
}
recomputeDimensions();
}
@Override
public void recomputeDimensions() {
root.recomputeDimensions();
}
@Override
public int getWidth() {
return root.getWidth();
}
@Override
public int getHeight() {
return root.getHeight();
}
@Override
public int getLine() {
return root.getLine();
}
/**
*
* @param delta
* Time, in seconds
*/
public void beforeRender(double delta) {
}
/**
*
* @param ge
* Graphic Engine class.
* @param r
* Graphic Renderer class of <b>ge</b>.
* @param x
* Position relative to the window.
* @param y
* Position relative to the window.
*/
public void draw(GraphicEngine ge, Renderer r, int x, int y) {
root.draw(ge, r, x, y, caret);
}
public void clear() {
root.clear();
recomputeDimensions();
}
}

View File

@ -0,0 +1,5 @@
package org.warp.picalculator.gui.expression.containers;
public interface OutputLayout {
}

View File

@ -0,0 +1,7 @@
package org.warp.picalculator.gui.expression.layouts;
import org.warp.picalculator.gui.expression.blocks.Block;
public interface InputLayout {
public Block parseChar(char c);
}

View File

@ -1,7 +1,5 @@
package org.warp.picalculator.gui.graphicengine;
import java.awt.FontMetrics;
public interface Renderer {
public void glColor3i(int r, int gg, int b);
@ -25,10 +23,17 @@ public interface Renderer {
public void glDrawLine(float x0, float y0, float x1, float y1);
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth, float uvHeight);
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth,
float uvHeight);
public void glFillColor(float x, float y, float width, float height);
public void glDrawCharLeft(int x, int y, char ch);
public void glDrawCharCenter(int x, int y, char ch);
public void glDrawCharRight(int x, int y, char ch);
public void glDrawStringLeft(float x, float y, String text);
public void glDrawStringCenter(float x, float y, String text);

View File

@ -48,7 +48,7 @@ public class CPUEngine implements GraphicEngine {
@Override
public void create() {
INSTANCE = new SwingWindow(this, DisplayManager.getDrawable());
INSTANCE = new SwingWindow(this);
setResizable(Utils.debugOn & !Utils.debugThirdScreen);
setDisplayMode(Main.screenSize[0], Main.screenSize[1]);
INSTANCE.setVisible(true);
@ -86,7 +86,8 @@ public class CPUEngine implements GraphicEngine {
@Override
public void start(RenderingLoop d) {
Thread th = new Thread(() -> {
INSTANCE.setRenderingLoop(d);
final Thread th = new Thread(() -> {
try {
double extratime = 0;
while (initialized) {
@ -268,21 +269,27 @@ public class CPUEngine implements GraphicEngine {
}
if (iy0 == iy1) {
for (int x = 0; x <= ix1 - ix0; x++) {
if ((ix0 + x < size[0]) & (iy0 < size[1])) {
canvas2d[ix0 + x + iy0 * size[0]] = color;
}
}
} else if (ix0 == ix1) {
for (int y = 0; y <= iy1 - iy0; y++) {
if ((ix0 < size[0]) & (iy0 + y < size[1])) {
canvas2d[ix0 + (iy0 + y) * size[0]] = color;
}
}
} else {
final int m = (iy1 - iy0) / (ix1 - ix0);
for (int texx = 0; texx <= ix1 - ix0; texx++) {
if (ix0 + texx < size[0] && iy0 + (m * texx) < size[1]) {
if ((ix0 + texx < size[0]) & ((iy0 + (m * texx)) < size[1])) {
canvas2d[(ix0 + texx) + (iy0 + (m * texx)) * size[0]] = color;
}
}
}
}
}
@Override
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth,
@ -409,6 +416,21 @@ public class CPUEngine implements GraphicEngine {
currentSkin = null;
}
@Override
public void glDrawCharLeft(int x, int y, char ch) {
glDrawStringLeft(x, y, ch + "");
}
@Override
public void glDrawCharCenter(int x, int y, char ch) {
glDrawStringCenter(x, y, ch + "");
}
@Override
public void glDrawCharRight(int x, int y, char ch) {
glDrawStringRight(x, y, ch + "");
}
}
@Override
@ -442,7 +464,7 @@ public class CPUEngine implements GraphicEngine {
do {
Thread.sleep(500);
} while (initialized);
} catch (InterruptedException e) {
} catch (final InterruptedException e) {
}
}

View File

@ -161,9 +161,9 @@ public class CPUFont implements BinaryFont {
@Override
public int getStringWidth(String text) {
final int w = (charW + 1) * text.length();
final int w = (charW) * text.length();
if (text.length() > 0) {
return w - 1;
return w;
} else {
return 0;
}

View File

@ -5,7 +5,6 @@ import java.io.IOException;
import javax.imageio.ImageIO;
import org.warp.picalculator.Main;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Skin;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine.CPURenderer;
@ -21,7 +20,7 @@ public class CPUSkin implements Skin {
@Override
public void load(String file) throws IOException {
final BufferedImage img = ImageIO.read(Main.instance.getClass().getResource("/"+file));
final BufferedImage img = ImageIO.read(this.getClass().getResource("/" + file));
skinData = getMatrixOfImage(img);
skinSize = new int[] { img.getWidth(), img.getHeight() };
}

View File

@ -24,12 +24,11 @@ import org.warp.picalculator.gui.graphicengine.RenderingLoop;
public class SwingWindow extends JFrame {
private static final long serialVersionUID = 2945898937634075491L;
public CustomCanvas c;
private static RenderingLoop d;
private RenderingLoop renderingLoop;
public boolean wasResized = false;
private final CPUEngine display;
public SwingWindow(CPUEngine disp, RenderingLoop d) {
SwingWindow.d = d;
public SwingWindow(CPUEngine disp) {
display = disp;
c = new CustomCanvas();
c.setDoubleBuffered(false);
@ -223,7 +222,11 @@ public class SwingWindow extends JFrame {
return c.getHeight();
}
// private static ArrayList<Double> mediaValori = new ArrayList<Double>();
public void setRenderingLoop(RenderingLoop renderingLoop) {
this.renderingLoop = renderingLoop;
}
// private static ObjectArrayList<Double> mediaValori = new ObjectArrayList<Double>();
public class CustomCanvas extends JPanel {
@ -235,7 +238,8 @@ public class SwingWindow extends JFrame {
@Override
public void paintComponent(Graphics g) {
// long time1 = System.nanoTime();
d.refresh();
if (renderingLoop != null) {
renderingLoop.refresh();
final int[] a = ((DataBufferInt) display.g.getRaster().getDataBuffer()).getData();
// System.arraycopy(canvas2d, 0, a, 0, canvas2d.length);
@ -254,3 +258,4 @@ public class SwingWindow extends JFrame {
}
}
}
}

View File

@ -24,7 +24,7 @@ import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -267,7 +267,7 @@ public class DeallocationHelper {
*/
public DeallocationHelper(final boolean ignoreClassesAndFieldsHints) {
super();
final List<Buffer> buffersToDelete = new ArrayList<>();
final List<Buffer> buffersToDelete = new ObjectArrayList<>();
/**
* builds the map used to determine the names of the fields containing
* the direct byte buffers. The direct read only buffers and the sliced
@ -342,7 +342,7 @@ public class DeallocationHelper {
}
// checks if these classes are in the class library
if (!attachmentOrByteBufferFieldNameMap.isEmpty()) {
final List<String> classnamesToRemove = new ArrayList<>();
final List<String> classnamesToRemove = new ObjectArrayList<>();
for (final String classname : attachmentOrByteBufferFieldNameMap.keySet()) {
try {
Class.forName(classname);
@ -365,7 +365,7 @@ public class DeallocationHelper {
final Class<?> bufferClass = Class.forName(classname);
Field bufferField = null;
Class<?> bufferIntermediaryClass = bufferClass;
final List<Class<?>> intermediaryClassWithoutBufferList = new ArrayList<>();
final List<Class<?>> intermediaryClassWithoutBufferList = new ObjectArrayList<>();
while (bufferIntermediaryClass != null) {
try {
bufferField = bufferIntermediaryClass.getDeclaredField(fieldname);
@ -454,7 +454,7 @@ public class DeallocationHelper {
final LongBuffer littleEndianReadWriteDirectLongBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
final ShortBuffer littleEndianReadOnlyDirectShortBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asShortBuffer();
final ShortBuffer littleEndianReadWriteDirectShortBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
final List<Buffer> buffers = new ArrayList<>();
final List<Buffer> buffers = new ObjectArrayList<>();
buffers.add(slicedBigEndianReadOnlyDirectByteBuffer);
buffers.add(slicedBigEndianReadWriteDirectByteBuffer);
buffers.add(bigEndianReadOnlyDirectCharBuffer);

View File

@ -9,7 +9,6 @@ import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.Skin;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.egl.EGL;
public class GPUEngine implements org.warp.picalculator.gui.graphicengine.GraphicEngine {
@ -47,9 +46,9 @@ public class GPUEngine implements org.warp.picalculator.gui.graphicengine.Graphi
@Override
public void setDisplayMode(int ww, int wh) {
this.size[0] = ww;
this.size[1] = wh;
wnd.window.setSize(ww, wh);
size[0] = ww;
size[1] = wh;
wnd.window.setSize((Utils.debugOn & Utils.debugWindow2x) ? ww * 2 : ww, (Utils.debugOn & Utils.debugWindow2x) ? wh * 2 : wh);
}
@Override
@ -93,7 +92,7 @@ public class GPUEngine implements org.warp.picalculator.gui.graphicengine.Graphi
@Override
public void repaint() {
if (d != null & r != null && r.gl != null) {
if (d != null & r != null && GPURenderer.gl != null) {
d.refresh();
}
}
@ -119,14 +118,14 @@ public class GPUEngine implements org.warp.picalculator.gui.graphicengine.Graphi
do {
Thread.sleep(500);
} while (initialized | created);
} catch (InterruptedException e) {
} catch (final InterruptedException e) {
}
}
@Override
public boolean isSupported() {
boolean available = GLProfile.isAvailable(GLProfile.GL2ES1);
final boolean available = GLProfile.isAvailable(GLProfile.GL2ES1);
if (!available) {
System.err.println(GLProfile.glAvailabilityToString());
}

View File

@ -1,11 +1,8 @@
package org.warp.picalculator.gui.graphicengine.gpu;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.cpu.CPUFont;
@ -50,11 +47,15 @@ public class GPUFont implements BinaryFont {
final int[] indexes = new int[l];
final char[] chars = txt.toCharArray();
for (int i = 0; i < l; i++) {
indexes[i] = (chars[i] & 0xFFFF) - minCharIndex;
indexes[i] = getCharIndex(chars[i]);
}
return indexes;
}
public int getCharIndex(char ch) {
return (ch & 0xFFFF) - minCharIndex;
}
private void genTexture(boolean[][] chars) {
final double totalChars = maxCharIndex - minCharIndex;
final int w = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charW)));
@ -120,9 +121,9 @@ public class GPUFont implements BinaryFont {
@Override
public int getStringWidth(String text) {
final int w = (charW + 1) * text.length();
final int w = (charW) * text.length();
if (text.length() > 0) {
return w - 1;
return w;
} else {
return 0;
}

View File

@ -1,6 +1,5 @@
package org.warp.picalculator.gui.graphicengine.gpu;
import java.awt.FontMetrics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -24,7 +23,7 @@ import com.jogamp.opengl.util.texture.TextureIO;
public class GPURenderer implements Renderer {
public GL2ES1 gl;
public static GL2ES1 gl;
private final DeallocationHelper deallocationHelper = new DeallocationHelper();
FloatBuffer fbVertices;
@ -43,9 +42,9 @@ public class GPURenderer implements Renderer {
@Override
public void glColor3i(int r, int gg, int b) {
final float red = ((float)r) / 255f;
final float gre = ((float)gg) / 255f;
final float blu = ((float)b) / 255f;
final float red = (r) / 255f;
final float gre = (gg) / 255f;
final float blu = (b) / 255f;
currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
}
@ -75,10 +74,10 @@ public class GPURenderer implements Renderer {
@Override
public void glClearColor(int rgb) {
final float alpha = (float)((rgb >> 24) & 0xFF) / 255f;
final float red = (float)((rgb >> 16) & 0xFF) / 255f;
final float green = (float)((rgb >> 8) & 0xFF) / 255f;
final float blue = (float)(rgb & 0xFF) / 255f;
final float alpha = ((rgb >> 24) & 0xFF) / 255f;
final float red = ((rgb >> 16) & 0xFF) / 255f;
final float green = ((rgb >> 8) & 0xFF) / 255f;
final float blue = (rgb & 0xFF) / 255f;
glClearColor4f(red, green, blue, alpha);
}
@ -117,7 +116,8 @@ public class GPURenderer implements Renderer {
}
@Override
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth, float uvHeight) {
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth,
float uvHeight) {
enableTexture();
uvWidth /= currentTexWidth;
uvX /= currentTexWidth;
@ -145,13 +145,13 @@ public class GPURenderer implements Renderer {
@Override
public void glDrawStringLeft(float x, float y, String text) {
final int txtLen = text.length();
int[] txtArray = currentFont.getCharIndexes(text);
final int[] txtArray = currentFont.getCharIndexes(text);
int tableIndexX;
int tableIndexY;
for (int currentCharIndex = 0; currentCharIndex < txtLen; currentCharIndex++) {
tableIndexX = txtArray[currentCharIndex] % currentFont.memoryWidthOfEachColumn;
tableIndexY = (txtArray[currentCharIndex] - tableIndexX) / currentFont.memoryWidthOfEachColumn;
glFillRect(x + ((float)currentCharIndex) * ((float)(currentFont.charW + 1)), y, currentFont.charW, currentFont.charH, tableIndexX*currentFont.charW, tableIndexY*currentFont.charH, currentFont.charW, currentFont.charH);
glFillRect(x + ((float) currentCharIndex) * ((float) (currentFont.charW)), y, currentFont.charW, currentFont.charH, tableIndexX * currentFont.charW, tableIndexY * currentFont.charH, currentFont.charW, currentFont.charH);
}
}
@ -165,6 +165,24 @@ public class GPURenderer implements Renderer {
glDrawStringLeft(x - currentFont.getStringWidth(text), y, text);
}
@Override
public void glDrawCharLeft(int x, int y, char ch) {
final int index = currentFont.getCharIndex(ch);
final int tableIndexX = index % currentFont.memoryWidthOfEachColumn;
final int tableIndexY = (index - tableIndexX) / currentFont.memoryWidthOfEachColumn;
glFillRect(x, y, currentFont.charW, currentFont.charH, tableIndexX * currentFont.charW, tableIndexY * currentFont.charH, currentFont.charW, currentFont.charH);
}
@Override
public void glDrawCharCenter(int x, int y, char ch) {
glDrawCharLeft(x - (currentFont.charW / 2), y, ch);
}
@Override
public void glDrawCharRight(int x, int y, char ch) {
glDrawCharLeft(x - currentFont.charW, y, ch);
}
@Override
public BinaryFont getCurrentFont() {
return currentFont;
@ -174,10 +192,10 @@ public class GPURenderer implements Renderer {
final FileInputStream f = new FileInputStream("test.png");
final TextureData tx_dat = TextureIO.newTextureData(gl.getGLProfile(), f, false, TextureIO.PNG);
final Texture tex = new Texture(gl, tx_dat);
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
// tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
// tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
return tex;
}
@ -190,7 +208,10 @@ public class GPURenderer implements Renderer {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(img, "png", os);
final InputStream fis = new ByteArrayInputStream(os.toByteArray());
return TextureIO.newTexture(fis, false, TextureIO.PNG);
final Texture tex = TextureIO.newTexture(fis, false, TextureIO.PNG);
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
return tex;
}
@Override
@ -203,12 +224,17 @@ public class GPURenderer implements Renderer {
}
public void startDrawCycle() {
if (fbVertices == null) {
fbVertices = Buffers.newDirectFloatBuffer(3 * 4);
txVertices = Buffers.newDirectFloatBuffer(2 * 4);
colVertices = Buffers.newDirectFloatBuffer(4 * 4);
}
fbElements = 0;
}
private boolean precTexEnabled;
private Texture precTex;
public void endDrawCycle() {
fbVertices.rewind();
txVertices.rewind();
@ -218,21 +244,25 @@ public class GPURenderer implements Renderer {
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, txVertices);
gl.glVertexPointer(3, GL.GL_FLOAT, 0, fbVertices);
if (precTexEnabled != currentTexEnabled | precTex != currentTex) {
precTexEnabled = currentTexEnabled;
precTex = currentTex;
if (currentTexEnabled) {
gl.glEnable(GL2ES1.GL_TEXTURE_2D);
gl.glEnable(GL.GL_TEXTURE_2D);
currentTex.bind(gl);
} else {
gl.glDisable(GL2ES1.GL_TEXTURE_2D);
gl.glDisable(GL.GL_TEXTURE_2D);
}
}
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, fbElements * 4);
deleteBuffer(fbVertices);
deleteBuffer(txVertices);
deleteBuffer(colVertices);
fbVertices = null;
txVertices = null;
colVertices = null;
// deleteBuffer(fbVertices);
// deleteBuffer(txVertices);
// deleteBuffer(colVertices);
// fbVertices = null;
// txVertices = null;
// colVertices = null;
}
public void deleteBuffer(final Buffer realNioBuffer) {

View File

@ -5,6 +5,7 @@ import java.io.IOException;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Skin;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES1;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.util.texture.Texture;
@ -33,12 +34,12 @@ public class GPUSkin implements Skin {
@Override
public void initialize(GraphicEngine d) {
try {
BufferedImage i = GPURenderer.openTexture(texturePath);
GL2ES1 gl = ((GPURenderer)d.getRenderer()).gl;
final BufferedImage i = GPURenderer.openTexture(texturePath);
final GL2ES1 gl = GPURenderer.gl;
t = GPURenderer.importTexture(i);
w = i.getWidth();
h = i.getHeight();
t.setTexParameteri(gl, GL2ES1.GL_TEXTURE_MAG_FILTER, GL2ES1.GL_NEAREST);
t.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
initialized = true;
} catch (GLException | IOException e) {
e.printStackTrace();

View File

@ -33,13 +33,10 @@ import com.jogamp.opengl.GL2ES1;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.fixedfunc.GLLightingFunc;
import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
import com.jogamp.opengl.fixedfunc.GLPointerFunc;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.nativewindow.util.DimensionImmutable;
import com.jogamp.nativewindow.util.PixelFormat;
import com.jogamp.nativewindow.util.PixelRectangle;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.WindowEvent;
@ -49,15 +46,10 @@ import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.nio.ByteBuffer;
import java.util.Collection;
import org.warp.picalculator.Utils;
import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.device.Keyboard.Key;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
/**
*
@ -276,9 +268,9 @@ class NEWTWindow implements GLEventListener {
gl.glEnable(GL.GL_TEXTURE_2D);
//Transparency
gl.glEnable(GL2ES1.GL_BLEND);
gl.glBlendFunc(GL2ES1.GL_SRC_ALPHA, GL2ES1.GL_ONE_MINUS_SRC_ALPHA);
gl.glShadeModel(GL2ES1.GL_SMOOTH);
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
gl.glShadeModel(GLLightingFunc.GL_FLAT);
try {
renderer.currentTex = ((GPUSkin) disp.loadSkin("test.png")).t;
@ -295,8 +287,8 @@ class NEWTWindow implements GLEventListener {
@Override
public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
disp.size[0] = width;
disp.size[1] = height;
disp.size[0] = (Utils.debugOn & Utils.debugWindow2x) ? width / 2 : width;
disp.size[1] = (Utils.debugOn & Utils.debugWindow2x) ? height / 2 : height;
final GL2ES1 gl = glad.getGL().getGL2ES1();
float max_wh, min_wh;
if (width == 0) {
@ -318,7 +310,7 @@ class NEWTWindow implements GLEventListener {
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrtho(0.0, width, height, 0.0, -1, 1);
gl.glOrtho(0.0, (Utils.debugOn & Utils.debugWindow2x) ? width / 2 : width, (Utils.debugOn & Utils.debugWindow2x) ? height / 2 : height, 0.0, -1, 1);
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glLoadIdentity();
@ -328,7 +320,7 @@ class NEWTWindow implements GLEventListener {
public void display(GLAutoDrawable glad) {
final GL2ES1 gl = glad.getGL().getGL2ES1();
renderer.gl = gl;
GPURenderer.gl = gl;
gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);
gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
@ -340,7 +332,7 @@ class NEWTWindow implements GLEventListener {
renderer.endDrawCycle();
renderer.gl = null;
GPURenderer.gl = null;
gl.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
gl.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);

View File

@ -4,7 +4,7 @@ import org.warp.picalculator.Main;
import org.warp.picalculator.Utils;
import org.warp.picalculator.device.Keyboard.Key;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.functions.Variable.VariableValue;
public class ChooseVariableValueScreen extends Screen {

View File

@ -29,7 +29,7 @@ public class KeyboardDebugScreen extends Screen {
@Override
public void render() {
Renderer renderer = DisplayManager.renderer;
final Renderer renderer = DisplayManager.renderer;
fonts[2].use(DisplayManager.engine);
renderer.glColor4f(0.75f, 0.0f, 0.0f, 1.0f);
renderer.glDrawStringRight(Main.screenSize[0] - 10, 30, "-" + keyevent.toUpperCase() + "-");

View File

@ -1,8 +1,5 @@
package org.warp.picalculator.gui.screens;
import static org.warp.picalculator.gui.DisplayManager.colore;
import static org.warp.picalculator.gui.DisplayManager.fonts;
import org.warp.picalculator.Main;
import org.warp.picalculator.device.Keyboard.Key;
import org.warp.picalculator.gui.DisplayManager;

View File

@ -1,10 +1,7 @@
package org.warp.picalculator.gui.screens;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.warp.picalculator.Main;
import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.device.Keyboard.Key;
@ -37,7 +34,7 @@ public class MarioScreen extends Screen {
try {
skin = DisplayManager.engine.loadSkin("marioskin.png");
groundskin = DisplayManager.engine.loadSkin("marioground.png");
} catch (IOException e) {
} catch (final IOException e) {
e.printStackTrace();
}
}

View File

@ -1,152 +1,97 @@
package org.warp.picalculator.gui.screens;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.Main;
import org.warp.picalculator.Utils;
import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.device.Keyboard.Key;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.expression.blocks.Block;
import org.warp.picalculator.gui.expression.blocks.BlockContainer;
import org.warp.picalculator.gui.expression.containers.InputContainer;
import org.warp.picalculator.gui.expression.containers.NormalInputContainer;
import org.warp.picalculator.gui.expression.containers.NormalOutputContainer;
import org.warp.picalculator.gui.expression.containers.OutputContainer;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.math.AngleMode;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionDynamic;
import org.warp.picalculator.math.FunctionSingle;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.functions.FunctionMultipleValues;
import org.warp.picalculator.math.functions.FunctionTwoValues;
import org.warp.picalculator.math.functions.Variable;
import org.warp.picalculator.math.functions.Variable.VariableValue;
import org.warp.picalculator.math.functions.equations.Equation;
import org.warp.picalculator.math.parser.MathParser;
import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.functions.Number;
public class MathInputScreen extends Screen {
public volatile String currentExpression = "";
public volatile String newExpression = "";
public volatile int caretPos = 0;
public volatile boolean showCaret = true;
public volatile float showCaretDelta = 0f;
public Calculator calc;
public boolean autoscroll;
public int scrollX = 0;
public MathContext calc;
public InputContainer userInput;
public OutputContainer result;
public int errorLevel = 0; // 0 = nessuno, 1 = risultato, 2 = tutto
boolean mustRefresh = true;
boolean firstStep = true;
public MathInputScreen() {
super();
canBeInHistory = true;
calc = new Calculator();
}
@Override
public void created() throws InterruptedException {
calc = new MathContext();
try {
BlockContainer.initializeFonts(DisplayManager.engine.loadFont("ex"), DisplayManager.engine.loadFont("big"));
} catch (final IOException e) {
e.printStackTrace();
System.exit(1);
}
userInput = new NormalInputContainer();
result = new NormalOutputContainer();
calc.init();
}
@Override
public void init() throws InterruptedException {
/* Fine caricamento */
// Parentesi f = new
// Parentesi("(Ⓐ(2X)*3Y)/(5Z^2)+(Ⓐ(11A)*13B)/(7CZ)=19XZ");
// PARENTESI CON CALCOLI
// Funzione f = new Sottrazione(new Somma(new Parentesi("Ⓐ9/2+Ⓐ7/2",
// "").calcola(), new Termine("3.5")), new
// Parentesi("3*2√14","").calcola());
// PARENTESI CON DUE NUMERI FRAZIONALI COMPLETI CON INCOGNITE:
// Funzione f = new
// Parentesi("(Ⓐ(2X)*3Y)/(5Z^2)+(Ⓐ(11A)*13B)/(7CZ)", "");
// PARENTESI CON DUE NUMERI FRAZIONALI DISALLINEATI GRAFICAMENTE:
// Funzione f = new Parentesi("((5^2-1)/2)/5-5/(5/2)=2", "");
// TERMINE DI PROVA COMPLETO:
// Funzione f = new Termine(new NumeroAvanzato(new Rational(3, 2),
// new Rational(7, 1), new Incognite(new Incognita('X',
// Rational.ONE)), new Incognite(new Incognita('Y', Rational.ONE)),
// new Incognite(new Incognita('z', Rational.ONE))));
// PARENTESI REALISTICA CON INCOGNITE:
// Funzione f = new Equazione(new
// Parentesi("X^2+(MX-M+4)^2-4X-4(MX-M+4)^2+7", ""), new
// Termine("0"));
// POTENZA:
// Funzione f = new Parentesi("(MX-M+4)^2", "");
// NUMERO SEMPLICE LUNGO:
// Funzione f = new Parentesi("-1219999799999996934.42229", "");
// :
// Funzione f = new Parentesi("5Y+XY=2", "")
// calcola("((5^2+3√(100/0.1))+Ⓐ(7)+9/15*2√(26/2))/21");
calc.init();
// interpreta("{(5X*(15X/3X))+(25X/(5X*(15X/3X)))=15{X=5"); //TODO RIMUOVERE
// long start = System.nanoTime();
// Termine result =
// Calculator.calcolarisultato("((5Ⓑ2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21");
// long end = System.nanoTime();
// long timeElapsed = end-start;
// System.out.println("RESULT: " + result);
// System.out.println("DECIMAl RESULT: " +
// result.getTerm().toBigDecimal());
// System.out.println("Time elapsed: " + (double) timeElapsed /
// 1000000 + " milliseconds\n");
//
//
// start = System.nanoTime();
// RisultatoEquazione eresult =
// Calculator.calcolaequazione("((5Ⓑ2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21=(175*(2√7)+3*(2√13))/105");
// end = System.nanoTime();
// timeElapsed = end-start;
// System.out.println("Is an equation: " + eresult.isAnEquation);
// System.out.println("L-R: " + eresult.LR);
// System.out.println("Time elapsed: " + (double) timeElapsed /
// 1000000 + " milliseconds\n");
}
public void interpreta(boolean temporary) throws Error {
final String eqn = newExpression;
if (!temporary) {
currentExpression = eqn;
}
calc.parseInputString(eqn);
}
@Override
public void beforeRender(float dt) {
showCaretDelta += dt;
if (showCaretDelta >= 0.5f) {
mustRefresh = true;
showCaret = !showCaret;
showCaretDelta = 0f;
}
if (caretPos > newExpression.length()) {
caretPos = newExpression.length();
}
if (DisplayManager.error == null) {
DisplayManager.renderer.glClearColor(0xFFc5c2af);
} else {
DisplayManager.renderer.glClearColor(0xFFDC3C32);
}
if (userInput.beforeRender(dt)) {
mustRefresh = true;
}
}
private static final BinaryFont fontBig = Utils.getFont(false);
@Override
public void renderStatusbar() {
Renderer renderer = DisplayManager.renderer;
final Renderer renderer = DisplayManager.renderer;
renderer.glColor3f(1, 1, 1);
final int pos = 2;
final int spacersNumb = 1;
@ -165,71 +110,11 @@ public class MathInputScreen extends Screen {
final int textColor = 0xFF000000;
final int padding = 4;
DisplayManager.renderer.glColor(textColor);
final int caretRealPos = MathematicalSymbols.getGraphicRepresentation(newExpression.substring(0, caretPos)).length() * (fontBig.getCharacterWidth() + 1);
final String inputTextWithoutCaret = MathematicalSymbols.getGraphicRepresentation(newExpression);
final boolean tooLongI = padding + fontBig.getStringWidth(newExpression) + padding >= Main.screenSize[0];
int scrollI = 0;
if (tooLongI) {
scrollI = -scrollX;
if (-scrollI >= Main.screenSize[0]) {
scrollI += Main.screenSize[0];
} else {
scrollI = 0;
}
}
DisplayManager.renderer.glDrawStringLeft(padding + scrollI, padding + 20, inputTextWithoutCaret);
if (showCaret) {
DisplayManager.renderer.glDrawStringLeft(padding + scrollI + caretRealPos, padding + 20, "|");
}
if (tooLongI) {
DisplayManager.renderer.glColor(DisplayManager.renderer.glGetClearColor());
DisplayManager.renderer.glFillColor(Main.screenSize[0] - 16 - 2, padding + 20, fontBig.getCharacterHeight(), Main.screenSize[0]);
DisplayManager.renderer.glColor(textColor);
DisplayManager.drawSkinPart(Main.screenSize[0] - 16, padding + 20 + fontBig.getCharacterHeight() / 2 - 16 / 2, 304, 0, 304 + 16, 16);
}
if (calc.f != null) {
int topSpacing = 0;
final Iterator<Function> iter = calc.f.iterator();
while (iter.hasNext()) {
final Function fnc = iter.next();
try {
final boolean tooLong = padding + fnc.getWidth() + padding >= Main.screenSize[0];
int scrollA = 0;
if (tooLong) {
scrollA = -scrollX;
if (-scrollA >= Main.screenSize[0]) {
scrollA += Main.screenSize[0];
} else {
scrollA = 0;
}
}
final int y = padding + 20 + padding + fontBig.getCharacterHeight() + 1 + topSpacing;
fnc.draw(padding + scrollA, y);
if (tooLong) {
DisplayManager.renderer.glColor(DisplayManager.renderer.glGetClearColor());
DisplayManager.renderer.glFillColor(Main.screenSize[0] - 16 - 2, y, fnc.getHeight(), Main.screenSize[0]);
DisplayManager.renderer.glColor(textColor);
DisplayManager.drawSkinPart(Main.screenSize[0] - 16, y + fnc.getHeight() / 2 - 16 / 2, 304, 0, 304 + 16, 16);
}
} catch (final NullPointerException e) {
iter.remove();
}
topSpacing += fnc.getHeight() + 2;
}
}
if (calc.f2 != null) {
int bottomSpacing = 0;
for (final Function f : calc.f2) {
bottomSpacing += f.getHeight() + 2;
f.draw(DisplayManager.engine.getWidth() - 2 - f.getWidth(), DisplayManager.engine.getHeight() - bottomSpacing);
}
if (calc.resultsCount > 1 && calc.resultsCount != calc.f2.size()) {
final String resultsCountText = calc.resultsCount + " total results".toUpperCase();
DisplayManager.renderer.glColor(0xFF9AAEA0);
Utils.getFont(true).use(DisplayManager.engine);
bottomSpacing += fontBig.getCharacterHeight() + 2;
DisplayManager.renderer.glDrawStringRight(DisplayManager.engine.getWidth() - 2, DisplayManager.engine.getHeight() - bottomSpacing, resultsCountText);
}
userInput.draw(DisplayManager.engine, DisplayManager.renderer, padding, padding + 20);
if (!result.root.getContent().isEmpty()) {
result.draw(DisplayManager.engine, DisplayManager.renderer, DisplayManager.engine.getWidth() - result.getWidth() - 2, DisplayManager.engine.getHeight() - result.getHeight() - 2);
}
}
@ -245,43 +130,44 @@ public class MathInputScreen extends Screen {
@Override
public boolean keyPressed(Key k) {
Utils.debug.println(k.toString());
switch (k) {
case STEP:
if (newExpression.length() > 0) {
if (firstStep) {
try {
try {
interpreta(true);
showVariablesDialog(() -> {
currentExpression = newExpression;
calc.f2 = calc.f;
firstStep = false;
step();
});
} catch (final Exception ex) {
if (Utils.debugOn) {
ex.printStackTrace();
}
throw new Error(Errors.SYNTAX_ERROR);
}
} catch (final Error e) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
DisplayManager.error = e.id.toString();
System.err.println(e.id);
}
} else {
step();
}
}
return true;
// if (newExpression.length() > 0) {
// if (firstStep) {
// try {
// try {
// interpreta(true);
// showVariablesDialog(() -> {
// currentExpression = newExpression;
// calc.f2 = calc.f;
// firstStep = false;
// step();
// });
// } catch (final Exception ex) {
// if (Utils.debugOn) {
// ex.printStackTrace();
// }
// throw new Error(Errors.SYNTAX_ERROR);
// }
// } catch (final Error e) {
// final StringWriter sw = new StringWriter();
// final PrintWriter pw = new PrintWriter(sw);
// e.printStackTrace(pw);
// d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
// DisplayManager.error = e.id.toString();
// System.err.println(e.id);
// }
// } else {
// step();
// }
// }
// return true;
case SIMPLIFY:
if (DisplayManager.error != null) {
//TODO: make the error management a global API rather than being relegated to this screen.
Utils.debug.println("Resetting after error...");
DisplayManager.error = null;
currentExpression = null;
calc.f = null;
calc.f2 = null;
calc.resultsCount = 0;
@ -289,17 +175,23 @@ public class MathInputScreen extends Screen {
} else {
try {
try {
if (!firstStep) {
step();
if (!userInput.isAlreadyParsed() && !userInput.isEmpty()) {
Expression expr = MathParser.parseInput(calc, userInput);
if (calc.f == null | calc.f2 == null) {
calc.f = new ObjectArrayList<>();
calc.f2 = new ObjectArrayList<>();
} else {
if (newExpression != currentExpression && newExpression.length() > 0) {
changeEquationScreen();
interpreta(true);
showVariablesDialog(() -> {
currentExpression = newExpression;
simplify();
});
calc.f.clear();
calc.f2.clear();
}
calc.f.add(expr);
ObjectArrayList<Function> resultExpression = expr.solve();
ObjectArrayList<Block> resultBlocks = MathParser.parseOutput(calc, resultExpression);
result.setContent(resultBlocks);
// showVariablesDialog(() -> {
// currentExpression = newExpression;
// simplify();
// });
}
} catch (final Exception ex) {
if (Utils.debugOn) {
@ -318,70 +210,70 @@ public class MathInputScreen extends Screen {
return true;
}
case NUM0:
typeChar("0");
typeChar('0');
return true;
case NUM1:
typeChar("1");
typeChar('1');
return true;
case NUM2:
typeChar("2");
typeChar('2');
return true;
case NUM3:
typeChar("3");
typeChar('3');
return true;
case NUM4:
typeChar("4");
typeChar('4');
return true;
case NUM5:
typeChar("5");
typeChar('5');
return true;
case NUM6:
typeChar("6");
typeChar('6');
return true;
case NUM7:
typeChar("7");
typeChar('7');
return true;
case NUM8:
typeChar("8");
typeChar('8');
return true;
case NUM9:
typeChar("9");
typeChar('9');
return true;
case PLUS:
typeChar("+");
typeChar('+');
return true;
case MINUS:
typeChar("-");
typeChar('-');
return true;
case PLUS_MINUS:
typeChar("±");
typeChar('±');
return true;
case MULTIPLY:
typeChar("*");
typeChar('*');
return true;
case DIVIDE:
typeChar("/");
typeChar('/');
return true;
case PARENTHESIS_OPEN:
typeChar("(");
typeChar('(');
return true;
case PARENTHESIS_CLOSE:
typeChar(")");
typeChar(')');
return true;
case DOT:
typeChar(".");
typeChar('.');
return true;
case EQUAL:
typeChar("=");
typeChar('=');
return true;
case SQRT:
typeChar("");
typeChar('Ⓐ');
return true;
case ROOT:
typeChar("");
typeChar('√');
return true;
case POWER_OF_2:
typeChar(MathematicalSymbols.POWER + "2");
typeChar(MathematicalSymbols.POWER_OF_TWO);
return true;
case POWER_OF_x:
typeChar(MathematicalSymbols.POWER);
@ -390,10 +282,10 @@ public class MathInputScreen extends Screen {
typeChar(MathematicalSymbols.PI);
return true;
case LETTER_X:
typeChar(MathematicalSymbols.variables()[23]);
typeChar(MathematicalSymbols.variables[23]);
return true;
case LETTER_Y:
typeChar(MathematicalSymbols.variables()[24]);
typeChar(MathematicalSymbols.variables[24]);
return true;
case SINE:
typeChar(MathematicalSymbols.SINE);
@ -414,59 +306,31 @@ public class MathInputScreen extends Screen {
typeChar(MathematicalSymbols.ARC_TANGENT);
return true;
case DELETE:
if (newExpression.length() > 0) {
if (caretPos > 0) {
caretPos -= 1;
newExpression = newExpression.substring(0, caretPos) + newExpression.substring(caretPos + 1, newExpression.length());
} else {
newExpression = newExpression.substring(1);
}
try {
interpreta(true);
} catch (final Error e) {}
}
firstStep = true;
userInput.del();
mustRefresh = true;
return true;
case LEFT:
if (caretPos > 0) {
caretPos -= 1;
} else {
caretPos = newExpression.length();
}
scrollX = fontBig.getStringWidth(newExpression.substring(0, caretPos) + "|||");
showCaret = true;
showCaretDelta = 0L;
userInput.moveLeft();
mustRefresh = true;
return true;
case RIGHT:
if (caretPos < newExpression.length()) {
caretPos += 1;
} else {
caretPos = 0;
}
scrollX = fontBig.getStringWidth(newExpression.substring(0, caretPos) + "|||");
showCaret = true;
showCaretDelta = 0L;
userInput.moveRight();
mustRefresh = true;
return true;
case RESET:
userInput.clear();
result.clear();
if (DisplayManager.error != null) {
Utils.debug.println("Resetting after error...");
DisplayManager.error = null;
return true;
} else {
caretPos = 0;
newExpression = "";
firstStep = false;
if (calc.f != null) {
calc.f = new ArrayList<>();
}
return true;
}
case SURD_MODE:
calc.exactMode = !calc.exactMode;
if (calc.exactMode == false) {
calc.f2 = solveExpression(calc.f2);
} else {
currentExpression = "";
result.clear();
Keyboard.keyPressed(Key.SIMPLIFY);
}
return true;
@ -474,24 +338,24 @@ public class MathInputScreen extends Screen {
DisplayManager.INSTANCE.setScreen(new EmptyScreen());
return true;
case HISTORY_BACK:
if (DisplayManager.INSTANCE.canGoBack()) {
if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession + 1] instanceof MathInputScreen) {
newExpression = currentExpression;
try {
interpreta(true);
} catch (final Error e) {}
}
}
// if (DisplayManager.INSTANCE.canGoBack()) {
// if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession + 1] instanceof MathInputScreen) {
// newExpression = currentExpression;
// try {
// interpreta(true);
// } catch (final Error e) {}
// }
// }
return false;
case HISTORY_FORWARD:
if (DisplayManager.INSTANCE.canGoForward()) {
if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession - 1] instanceof MathInputScreen) {
newExpression = currentExpression;
try {
interpreta(true);
} catch (final Error e) {}
}
}
// if (DisplayManager.INSTANCE.canGoForward()) {
// if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession - 1] instanceof MathInputScreen) {
// newExpression = currentExpression;
// try {
// interpreta(true);
// } catch (final Error e) {}
// }
// }
return false;
case debug_DEG:
if (calc.angleMode.equals(AngleMode.DEG) == false) {
@ -525,7 +389,7 @@ public class MathInputScreen extends Screen {
}
}
private ArrayList<Function> solveExpression(ArrayList<Function> f22) {
private ObjectArrayList<Function> solveExpression(ObjectArrayList<Function> f22) {
try {
try {
return calc.solveExpression(f22);
@ -550,22 +414,22 @@ public class MathInputScreen extends Screen {
try {
try {
showVariablesDialog();
ArrayList<Function> results = new ArrayList<>();
final ArrayList<Function> partialResults = new ArrayList<>();
ObjectArrayList<Function> results = new ObjectArrayList<>();
final ObjectArrayList<Function> partialResults = new ObjectArrayList<>();
for (final Function f : calc.f2) {
if (f instanceof Equation) {
DisplayManager.INSTANCE.setScreen(new SolveEquationScreen(this));
} else {
results.add(f);
for (final Function itm : results) {
if (itm.isSolved() == false) {
final List<Function> dt = itm.solveOneStep();
if (itm.isSimplified() == false) {
final List<Function> dt = itm.simplify();
partialResults.addAll(dt);
} else {
partialResults.add(itm);
}
}
results = new ArrayList<>(partialResults);
results = new ObjectArrayList<>(partialResults);
partialResults.clear();
}
}
@ -581,9 +445,6 @@ public class MathInputScreen extends Screen {
results.clear();
results.addAll(hs);
calc.f2 = results;
for (final Function rf : calc.f2) {
rf.generateGraphics();
}
}
Utils.debug.println(calc.f2.toString());
} catch (final Exception ex) {
@ -612,7 +473,7 @@ public class MathInputScreen extends Screen {
}
}
final ArrayList<Function> results = solveExpression(calc.f);
final ObjectArrayList<Function> results = solveExpression(calc.f);
if (results.size() == 0) {
calc.resultsCount = 0;
} else {
@ -624,9 +485,6 @@ public class MathInputScreen extends Screen {
results.clear();
results.addAll(hs);
calc.f2 = results;
for (final Function rf : calc.f2) {
rf.generateGraphics();
}
}
} catch (final Exception ex) {
if (Utils.debugOn) {
@ -644,34 +502,24 @@ public class MathInputScreen extends Screen {
}
}
@SuppressWarnings("unused")
@Deprecated
private void changeEquationScreen() {
if (currentExpression != null && currentExpression.length() > 0) {
final MathInputScreen cloned = clone();
cloned.caretPos = cloned.currentExpression.length();
cloned.newExpression = cloned.currentExpression;
cloned.scrollX = fontBig.getStringWidth(cloned.currentExpression);
try {
cloned.interpreta(true);
} catch (final Error e) {}
DisplayManager.INSTANCE.replaceScreen(cloned);
initialized = false;
DisplayManager.INSTANCE.setScreen(this);
}
throw new NotImplementedException();
//
// if (!userInput.isEmpty()) {
// final MathInputScreen cloned = clone();
// cloned.userInput.setCaretPosition(cloned.userInput.getCaretMaxPosition()-1);
// DisplayManager.INSTANCE.replaceScreen(cloned);
// initialized = false;
// DisplayManager.INSTANCE.setScreen(this);
//
// }
}
public void typeChar(String chr) {
final int len = chr.length();
newExpression = newExpression.substring(0, caretPos) + chr + newExpression.substring(caretPos, newExpression.length());
caretPos += len;
scrollX = fontBig.getStringWidth(newExpression.substring(0, caretPos) + "|||");
showCaret = true;
showCaretDelta = 0L;
firstStep = true;
try {
interpreta(true);
} catch (final Error e) {}
// f.clear(); //TODO: I removed this line to prevent input blanking when pressing EQUALS button and cloning this screen, but I must see why I created this part of code.
public void typeChar(char chr) {
userInput.typeChar(chr);
mustRefresh = true;
}
@Override
@ -685,7 +533,7 @@ public class MathInputScreen extends Screen {
public void showVariablesDialog(final Runnable runnable) {
final Thread ct = new Thread(() -> {
final ArrayList<Function> knownVarsInFunctions = getKnownVariables(calc.f.toArray(new Function[calc.f.size()]));
final ObjectArrayList<Function> knownVarsInFunctions = getKnownVariables(calc.f.toArray(new Function[calc.f.size()]));
for (final VariableValue f : calc.variablesValues) {
if (knownVarsInFunctions.contains(f.v)) {
knownVarsInFunctions.remove(f.v);
@ -727,15 +575,15 @@ public class MathInputScreen extends Screen {
ct.start();
}
private ArrayList<Function> getKnownVariables(Function[] fncs) {
final ArrayList<Function> res = new ArrayList<>();
private ObjectArrayList<Function> getKnownVariables(Function[] fncs) {
final ObjectArrayList<Function> res = new ObjectArrayList<>();
for (final Function f : fncs) {
if (f instanceof FunctionTwoValues) {
res.addAll(getKnownVariables(new Function[] { ((FunctionTwoValues) f).getVariable1(), ((FunctionTwoValues) f).getVariable2() }));
} else if (f instanceof FunctionMultipleValues) {
res.addAll(getKnownVariables(((FunctionMultipleValues) f).getVariables()));
} else if (f instanceof AnteriorFunction) {
res.addAll(getKnownVariables(new Function[] { ((AnteriorFunction) f).getVariable() }));
if (f instanceof FunctionOperator) {
res.addAll(getKnownVariables(new Function[] { ((FunctionOperator) f).getParameter1(), ((FunctionOperator) f).getParameter2() }));
} else if (f instanceof FunctionDynamic) {
res.addAll(getKnownVariables(((FunctionDynamic) f).getParameters()));
} else if (f instanceof FunctionSingle) {
res.addAll(getKnownVariables(new Function[] { ((FunctionSingle) f).getParameter() }));
} else if (f instanceof Variable) {
if (((Variable) f).getType() == Variable.V_TYPE.KNOWN) {
if (!res.contains(f)) {
@ -748,25 +596,17 @@ public class MathInputScreen extends Screen {
}
@Override
@Deprecated
public MathInputScreen clone() {
final MathInputScreen es = this;
final MathInputScreen es2 = new MathInputScreen();
es2.scrollX = es.scrollX;
es2.newExpression = es.newExpression;
es2.currentExpression = es.currentExpression;
es2.showCaret = es.showCaret;
es2.showCaretDelta = es.showCaretDelta;
es2.caretPos = es.caretPos;
// es2.calc.f = Utils.cloner.deepClone(es.calc.f);
// es2.calc.f2 = Utils.cloner.deepClone(es.calc.f2);
// es2.calc.resultsCount = es.calc.resultsCount;
es2.autoscroll = es.autoscroll;
es2.errorLevel = es.errorLevel;
es2.mustRefresh = es.mustRefresh;
es2.firstStep = es.firstStep;
// es2.calc.variablesValues = Utils.cloner.deepClone(es.calc.variablesValues);
es2.calc = Utils.cloner.deepClone(es.calc);
return es2;
throw new NotImplementedException();
// final MathInputScreen es = this;
// final MathInputScreen es2 = new MathInputScreen();
// es2.errorLevel = es.errorLevel;
// es2.mustRefresh = es.mustRefresh;
// es2.calc = Utils.cloner.deepClone(es.calc);
// es2.userInput = Utils.cloner.deepClone(es.userInput);
// es2.result = Utils.cloner.deepClone(es.result);
// return es2;
}
}

View File

@ -1,10 +1,8 @@
package org.warp.picalculator.gui.screens;
import org.warp.picalculator.Error;
import org.warp.picalculator.Main;
import org.warp.picalculator.device.Keyboard.Key;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.math.Calculator;
public class SolveEquationScreen extends Screen {

View File

@ -0,0 +1,65 @@
package org.warp.picalculator.math;
import java.util.List;
import org.warp.picalculator.Error;
public interface Function {
/**
* Returns this function and its children in a string form.
*
* @return This function and its children in a string form.
*/
@Override
public String toString();
@Override
public boolean equals(Object o);
/**
* Deep clone this function.
*
* @return A clone of this function.
*/
public Function clone();
/**
* Generic method to change a parameter in a known position.
*
* @param index
* parameter index.
* @param var
* parameter.
* @return A new instance of this function.
*/
public Function setParameter(int index, Function var) throws IndexOutOfBoundsException;
/**
* Generic method to retrieve a parameter in a known position.
*
* @param index
* parameter index.
* @return The requested parameter.
*/
public Function getParameter(int index) throws IndexOutOfBoundsException;
/**
* Retrieve the current Math Context used by this function
*
* @return Calculator mathContext
*/
public MathContext getMathContext();
/**
* Simplify the current function or it's children
*/
public List<Function> simplify() throws Error;
/**
* The current simplification status of this function and it's childrens
*
* @return boolean
*/
public boolean isSimplified();
}

View File

@ -0,0 +1,170 @@
package org.warp.picalculator.math;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.Arrays;
import java.util.List;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
public abstract class FunctionDynamic implements Function {
public FunctionDynamic(MathContext root) {
this.root = root;
functions = new Function[] {};
}
public FunctionDynamic(Function[] values) {
if (values.length > 0) {
root = values[0].getMathContext();
} else {
throw new NullPointerException("Nessun elemento nell'array. Impossibile ricavare il nodo root");
}
functions = values;
}
public FunctionDynamic(MathContext root, Function[] values) {
this.root = root;
functions = values;
}
protected final MathContext root;
protected Function[] functions;
public Function[] getParameters() {
return Arrays.copyOf(functions, functions.length);
}
public FunctionDynamic setParameters(final List<Function> value) {
final FunctionDynamic f = clone();
final int vsize = value.size();
final Function[] tmp = new Function[vsize];
for (int i = 0; i < vsize; i++) {
tmp[i] = value.get(i);
}
f.functions = tmp;
return f;
}
public FunctionDynamic setParameters(final Function[] value) {
final FunctionDynamic f = clone();
f.functions = value;
return f;
}
@Override
public Function getParameter(int index) {
return functions[index];
}
@Override
public FunctionDynamic setParameter(int index, Function value) {
final FunctionDynamic f = clone();
f.functions[index] = value;
return f;
}
public FunctionDynamic appendParameter(Function value) {
final FunctionDynamic f = clone();
f.functions = Arrays.copyOf(f.functions, f.functions.length + 1);
f.functions[f.functions.length - 1] = value;
return f;
}
/**
* Retrieve the current number of parameters.
*
* @return The number of parameters.
*/
public int getParametersLength() {
return functions.length;
}
public FunctionDynamic setParametersLength(int length) {
final FunctionDynamic f = clone();
f.functions = Arrays.copyOf(functions, length);
return f;
}
@Override
public boolean isSimplified() {
for (final Function variable : functions) {
if (variable.isSimplified() == false) {
return false;
}
}
return !isSolvable();
}
/**
* The current simplification status of this function, assuming that its
* children are already simplified.
*
* @return <strong>true</strong> if this function can be solved, otherwise
* <strong>false</strong>.
*/
protected abstract boolean isSolvable();
@Override
public final ObjectArrayList<Function> simplify() throws Error {
boolean solved = true;
final Function[] fncs = getParameters();
for (final Function f : fncs) {
if (f.isSimplified() == false) {
solved = false;
break;
}
}
ObjectArrayList<Function> result = solved ? solve() : null;
if (result == null || result.isEmpty()) {
result = new ObjectArrayList<>();
final ObjectArrayList<ObjectArrayList<Function>> ln = new ObjectArrayList<>();
for (final Function fnc : fncs) {
final ObjectArrayList<Function> l = new ObjectArrayList<>();
if (fnc.isSimplified()) {
l.add(fnc);
} else {
l.addAll(fnc.simplify());
}
ln.add(l);
}
final Function[][] results = Utils.joinFunctionsResults(ln);
for (final Function[] f : results) {
result.add(this.setParameters(f));
}
}
return result;
}
/**
* Solves only this function, assuming that its children are already
* simplified and it can be solved.
*
* @return The solved function.
* @throws Error
* Errors during computation, like a/0 or similar.
*/
protected abstract ObjectArrayList<Function> solve() throws Error;
@Override
public MathContext getMathContext() {
return root;
}
@Override
public abstract FunctionDynamic clone();
@Override
public int hashCode() {
return functions.hashCode() + 883 * super.hashCode();
}
@Override
public boolean equals(Object o) {
return false;
}
}

View File

@ -0,0 +1,180 @@
package org.warp.picalculator.math;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
public abstract class FunctionOperator implements Function {
/**
* Create a new instance of FunctionOperator. The Math Context will be the
* same of <strong>value1</strong>'s.
*
* @throws NullPointerException
* when value1 is null.
* @param value1
* The parameter of this function.
* @param value2
* The parameter of this function.
*/
public FunctionOperator(Function value1, Function value2) throws NullPointerException {
mathContext = value1.getMathContext();
parameter1 = value1;
parameter2 = value2;
}
/**
* Create a new instance of FunctionOperator.
*
* @param value1
* The parameter of this function.
* @param value2
* The parameter of this function.
*/
public FunctionOperator(MathContext mc, Function value1, Function value2) {
mathContext = mc;
parameter1 = value1;
parameter2 = value2;
}
protected final MathContext mathContext;
protected Function parameter1 = null;
protected Function parameter2 = null;
/**
*
* @return First parameter.
*/
public Function getParameter1() {
return parameter1;
}
/**
*
* @return Second parameter.
*/
public Function getParameter2() {
return parameter2;
}
/**
*
* @param var
* First parameter.
* @return A new instance of this function.
*/
public FunctionOperator setParameter1(Function var) {
final FunctionOperator s = clone();
s.parameter1 = var;
return s;
}
/**
*
* @param var
* Second parameter.
* @return A new instance of this function.
*/
public FunctionOperator setParameter2(Function var) {
final FunctionOperator s = clone();
s.parameter2 = var;
return s;
}
@Override
public FunctionOperator setParameter(int index, Function var) throws IndexOutOfBoundsException {
switch (index) {
case 0:
return setParameter1(var);
case 1:
return setParameter2(var);
default:
throw new IndexOutOfBoundsException();
}
}
@Override
public Function getParameter(int index) throws IndexOutOfBoundsException {
switch (index) {
case 0:
return getParameter1();
case 1:
return getParameter2();
default:
throw new IndexOutOfBoundsException();
}
}
@Override
public MathContext getMathContext() {
return mathContext;
}
@Override
public boolean isSimplified() {
return (parameter1.isSimplified() & parameter2.isSimplified()) ? !isSolvable() : false;
}
/**
* The current simplification status of this function, assuming that its
* children are already simplified.
*
* @return <strong>true</strong> if this function can be solved, otherwise
* <strong>false</strong>.
*/
protected abstract boolean isSolvable();
@Override
public final ObjectArrayList<Function> simplify() throws Error {
final boolean solved = parameter1.isSimplified() & parameter2.isSimplified();
ObjectArrayList<Function> result = solved ? solve() : null;;
if (result == null || result.isEmpty()) {
result = new ObjectArrayList<>();
final ObjectArrayList<Function> l1 = new ObjectArrayList<>();
final ObjectArrayList<Function> l2 = new ObjectArrayList<>();
if (parameter1.isSimplified()) {
l1.add(parameter1);
} else {
l1.addAll(parameter1.simplify());
}
if (parameter2.isSimplified()) {
l2.add(parameter2);
} else {
l2.addAll(parameter2.simplify());
}
final Function[][] results = Utils.joinFunctionsResults(l1, l2);
for (final Function[] f : results) {
result.add(setParameter1(f[0]).setParameter2(f[1]));
}
}
return result;
}
/**
* Solves only this function, assuming that its children are already
* simplified and it can be solved.
*
* @return The solved function.
* @throws Error
* Errors during computation, like a/0 or similar.
*/
protected abstract ObjectArrayList<Function> solve() throws Error;
@Override
public abstract FunctionOperator clone();
@Override
public int hashCode() {
return parameter1.hashCode() + 7 * parameter2.hashCode() + 883 * super.hashCode();
}
@Override
public abstract boolean equals(Object o);
}

View File

@ -0,0 +1,144 @@
package org.warp.picalculator.math;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
public abstract class FunctionSingle implements Function {
/**
* Create a new instance of FunctionSingle. The Math Context will be the
* same of <strong>value</strong>'s.
*
* @throws NullPointerException
* when value is null.
* @param value
* The parameter of this function.
*/
public FunctionSingle(Function value) throws NullPointerException {
mathContext = value.getMathContext();
parameter = value;
}
/**
* Create a new instance of FunctionSingle.
*
* @param mathContext
* Math Context
* @param value
* The parameter of this function.
*/
public FunctionSingle(MathContext mathContext, Function value) {
this.mathContext = mathContext;
parameter = value;
}
protected final MathContext mathContext;
/**
* Function parameter.<br>
* <u>MUST NOT BE MODIFIED IF ALREADY SET UP.</u>
*/
protected Function parameter;
/**
*
* @return Parameter.
*/
public Function getParameter() {
return parameter;
}
/**
*
* @param var
* Parameter.
* @return A new instance of this function.
*/
public FunctionSingle setParameter(Function value) {
final FunctionSingle s = clone();
s.parameter = value;
return s;
}
@Override
public FunctionSingle setParameter(int index, Function var) throws IndexOutOfBoundsException {
if (index == 0) {
return this.setParameter(var);
} else {
throw new IndexOutOfBoundsException();
}
}
@Override
public Function getParameter(int index) throws IndexOutOfBoundsException {
if (index == 0) {
return this.getParameter();
} else {
throw new IndexOutOfBoundsException();
}
}
@Override
public MathContext getMathContext() {
return mathContext;
}
@Override
public final ObjectArrayList<Function> simplify() throws Error {
final boolean simplified = parameter.isSimplified();
ObjectArrayList<Function> result = simplified ? solve() : null;
if (result == null || result.isEmpty()) {
result = new ObjectArrayList<>();
final ObjectArrayList<Function> l1 = new ObjectArrayList<>();
if (parameter.isSimplified()) {
l1.add(parameter);
} else {
l1.addAll(parameter.simplify());
}
for (final Function f : l1) {
result.add(this.setParameter(f));
}
}
return result;
}
/**
* Solves only this function, assuming that its children are already
* simplified and it can be solved.
*
* @return The solved function.
* @throws Error
* Errors during computation, like a/0 or similar.
*/
protected abstract ObjectArrayList<Function> solve() throws Error;
@Override
public boolean isSimplified() {
return parameter.isSimplified() ? !isSolvable() : false;
}
/**
* The current simplification status of this function, assuming that its
* children are already simplified.
*
* @return <strong>true</strong> if this function can be solved, otherwise
* <strong>false</strong>.
*/
protected abstract boolean isSolvable();
@Override
public abstract FunctionSingle clone();
@Override
public int hashCode() {
return parameter.hashCode() + 883 * super.hashCode();
}
@Override
public abstract boolean equals(Object o);
}

View File

@ -1,31 +1,32 @@
package org.warp.picalculator.math;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.Utils;
import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.functions.Number;
import org.warp.picalculator.math.functions.Variable.VariableValue;
import org.warp.picalculator.math.functions.equations.Equation;
import org.warp.picalculator.math.functions.equations.EquationsSystem;
public class Calculator {
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
public class MathContext {
public AngleMode angleMode = AngleMode.DEG;
public boolean exactMode = false;
public ArrayList<Function> f;
public ArrayList<Function> f2;
public ArrayList<VariableValue> variablesValues;
public ObjectArrayList<Function> f;
public ObjectArrayList<Function> f2;
public ObjectArrayList<VariableValue> variablesValues;
public int resultsCount;
public Calculator() {
f = new ArrayList<>();
f2 = new ArrayList<>();
variablesValues = new ArrayList<>();
public MathContext() {
f = new ObjectArrayList<>();
f2 = new ObjectArrayList<>();
variablesValues = new ObjectArrayList<>();
resultsCount = 0;
}
@ -37,7 +38,7 @@ public class Calculator {
final String[] parts = string.substring(1).split("\\{");
final EquationsSystem s = new EquationsSystem(this);
for (final String part : parts) {
s.addFunctionToEnd(parseEquationString(part));
s.appendParameter(parseEquationString(part));
}
return s;
} else if (string.contains("=")) {
@ -50,23 +51,17 @@ public class Calculator {
public Function parseEquationString(String string) throws Error {
final String[] parts = string.split("=");
if (parts.length == 1) {
final Equation e = new Equation(this, null, null);
e.setVariable1(new Expression(this, parts[0]));
e.setVariable2(new Number(this, BigInteger.ZERO));
return e;
return new Equation(this, new Expression(this, parts[0]), new Number(this, BigInteger.ZERO));
} else if (parts.length == 2) {
final Equation e = new Equation(this, null, null);
e.setVariable1(new Expression(this, parts[0]));
e.setVariable2(new Expression(this, parts[1]));
return e;
return new Equation(this, new Expression(this, parts[0]), new Expression(this, parts[1]));
} else {
throw new Error(Errors.SYNTAX_ERROR);
}
}
public ArrayList<Function> solveExpression(ArrayList<Function> input) throws Error {
ArrayList<Function> results = new ArrayList<>();
final ArrayList<Function> partialResults = new ArrayList<>();
public ObjectArrayList<Function> solveExpression(ObjectArrayList<Function> input) throws Error {
ObjectArrayList<Function> results = new ObjectArrayList<>();
final ObjectArrayList<Function> partialResults = new ObjectArrayList<>();
for (final Function f : input) {
if (f instanceof Equation) {
throw new IllegalArgumentException("Not an expression!");
@ -74,11 +69,11 @@ public class Calculator {
results.add(f);
while (Utils.allSolved(results) == false) {
for (final Function itm : results) {
if (itm.isSolved() == false) {
if (itm.isSimplified() == false) {
final long t1 = System.currentTimeMillis();
final List<Function> dt = itm.solveOneStep();
final List<Function> dt = itm.simplify();
final long t2 = System.currentTimeMillis();
if (t2 - t1 >= 3000) {
if (!Utils.debugOn & (t2 - t1 >= 3000)) {
throw new Error(Errors.TIMEOUT);
}
partialResults.addAll(dt);
@ -86,7 +81,7 @@ public class Calculator {
partialResults.add(itm);
}
}
results = new ArrayList<>(partialResults);
results = new ObjectArrayList<>(partialResults);
partialResults.clear();
}
}
@ -100,36 +95,17 @@ public class Calculator {
public void init() {
if (f == null & f2 == null) {
f = new ArrayList<>();
f2 = new ArrayList<>();
variablesValues = new ArrayList<>();
f = new ObjectArrayList<>();
f2 = new ObjectArrayList<>();
variablesValues = new ObjectArrayList<>();
resultsCount = 0;
}
}
public void parseInputString(String eqn) throws Error {
final ArrayList<Function> fncs = new ArrayList<>();
if (eqn.length() > 0) {
try {
fncs.add(parseString(eqn.replace("sqrt", MathematicalSymbols.SQUARE_ROOT).replace("^", MathematicalSymbols.POWER)));
} catch (final Exception ex) {
}
}
f = fncs;
for (final Function f : f) {
try {
f.generateGraphics();
} catch (final NullPointerException ex) {
throw new Error(Errors.SYNTAX_ERROR);
}
}
}
/*public void solve(EquationScreen equationScreen, char letter) throws Error {
if (Calculator.currentSession == 0 && Calculator.sessions[0] instanceof EquationScreen) {
EquationScreen es = (EquationScreen) Calculator.sessions[0];
ArrayList<Function> f = es.f;
ObjectArrayList<Function> f = es.f;
if (f instanceof Equation) {
List<Function> results = ((Equation)f).solve(letter);
Collections.reverse(results);
@ -146,4 +122,17 @@ public class Calculator {
}
}*/
@Override
@Deprecated
public MathContext clone() {
// MathContext mc = new MathContext();
// mc.angleMode = this.angleMode;
// mc.exactMode = this.exactMode;
// mc.f = this.f;
// mc.f2 = this.f2;
// mc.variablesValues = this.variablesValues;
// mc.resultsCount = this.resultsCount;
// return mc;
throw new NotImplementedException();
}
}

View File

@ -5,60 +5,53 @@ import static org.warp.picalculator.Utils.concat;
import org.warp.picalculator.Utils;
public class MathematicalSymbols {
public static final String SUM = "+";
public static final String SUM_SUBTRACTION = "±";
public static final String SUBTRACTION = "";
public static final String MINUS = "-";
public static final String MULTIPLICATION = "*";
public static final String DIVISION = "/";
public static final String NTH_ROOT = "";
public static final String SQUARE_ROOT = "";
public static final String PARENTHESIS_OPEN = "(";
public static final String PARENTHESIS_CLOSE = ")";
public static final String POWER = "";
public static final String EQUATION = "=";
public static final String SYSTEM = "{";
public static final String SINE = "";
public static final String COSINE = "";
public static final String TANGENT = "";
public static final String ARC_SINE = "";
public static final String ARC_COSINE = "";
public static final String ARC_TANGENT = "";
public static final String PI = "π";
public static final char SUM = '+';
public static final char SUM_SUBTRACTION = '±';
public static final char SUBTRACTION = '';
public static final char MINUS = '-';
public static final char MULTIPLICATION = '*';
public static final char DIVISION = '/';
public static final char NTH_ROOT = '√';
public static final char SQUARE_ROOT = 'Ⓐ';
public static final char PARENTHESIS_OPEN = '(';
public static final char PARENTHESIS_CLOSE = ')';
public static final char POWER = 'Ⓑ';
public static final char POWER_OF_TWO = 'Ⓘ';
public static final char EQUATION = '=';
public static final char SYSTEM = '{';
public static final char SINE = 'Ⓒ';
public static final char COSINE = 'Ⓓ';
public static final char TANGENT = 'Ⓔ';
public static final char ARC_SINE = 'Ⓕ';
public static final char ARC_COSINE = 'Ⓖ';
public static final char ARC_TANGENT = 'Ⓗ';
public static final char PI = 'π';
public static final String[] functions() {
return concat(functionsNSN(), functionsSN());
}
public static final char[] functionsNSN = new char[] { NTH_ROOT, POWER };
public static final String[] functionsNSN() {
return new String[] { NTH_ROOT, POWER };
}
public static final char[] functionsSN = new char[] { SQUARE_ROOT, POWER_OF_TWO, MINUS, SINE, COSINE, TANGENT, ARC_SINE, ARC_COSINE, ARC_TANGENT };
public static final String[] functionsSN() {
return new String[] { SQUARE_ROOT, MINUS, SINE, COSINE, TANGENT, ARC_SINE, ARC_COSINE, ARC_TANGENT };
}
public static final char[] functions = concat(functionsNSN, functionsSN);
public static final String[] signums(boolean withMultiplication) {
String[] ret = new String[] { SUM, SUM_SUBTRACTION, SUBTRACTION, DIVISION };
private static final char[] signumsWithoutMultiplication = new char[] { SUM, SUM_SUBTRACTION, SUBTRACTION, DIVISION };
private static final char[] signumsWithMultiplication = Utils.add(signumsWithoutMultiplication, MULTIPLICATION);
public static final char[] signums(boolean withMultiplication) {
if (withMultiplication) {
ret = Utils.add(ret, MULTIPLICATION);
return signumsWithMultiplication;
}
return ret;
return signumsWithoutMultiplication;
}
public static final String[] parentheses() {
return new String[] { PARENTHESIS_OPEN, PARENTHESIS_CLOSE };
}
public static final char[] parentheses = new char[] { PARENTHESIS_OPEN, PARENTHESIS_CLOSE };
public static String[] variables() {
return new String[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "", "", "Z", PI };
}
public static final char[] variables = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'ⓧ', 'Ⓨ', 'Z', PI };
public static String[] genericSyntax() {
return new String[] { SYSTEM, EQUATION };
}
public static final char[] genericSyntax = new char[] { SYSTEM, EQUATION };
public static String getGraphicRepresentation(String string) {
return string.replace("", "^").replace("", "SIN").replace("", "COS").replace("", "TAN").replace("", "ASIN").replace("", "ACOS").replace("", "ATAN");
}
public static final char[] numbers = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
}

View File

@ -1,11 +1,11 @@
package org.warp.picalculator.math;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.math.functions.equations.Equation;
public interface SolveMethod {
public static final SolveMethod[] techniques = new SolveMethod[] {};
public abstract ArrayList<Equation> solve(Equation equation);
public abstract ObjectArrayList<Equation> solve(Equation equation);
}

View File

@ -1,150 +0,0 @@
package org.warp.picalculator.math.functions;
import java.util.ArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
import org.warp.picalculator.math.Calculator;
import com.rits.cloning.Cloner;
public abstract class AnteriorFunction implements Function {
public AnteriorFunction(Function value) {
root = value.getRoot();
variable = value;
}
public AnteriorFunction(Calculator root, Function value) {
this.root = root;
variable = value;
}
protected abstract Function NewInstance(Calculator root, Function value);
protected final Calculator root;
protected Function variable;
protected int width;
protected int height;
protected int line;
protected boolean small;
public Function getVariable() {
return variable;
}
public void setVariable(Function value) {
variable = value;
}
@Override
public Calculator getRoot() {
return root;
}
@Override
public abstract String getSymbol();
@Override
public final ArrayList<Function> solveOneStep() throws Error {
final boolean solved = variable.isSolved();
ArrayList<Function> result = solved ? solve() : null;
if (result == null || result.isEmpty()) {
result = new ArrayList<>();
final ArrayList<Function> l1 = new ArrayList<>();
if (variable.isSolved()) {
l1.add(variable);
} else {
l1.addAll(variable.solveOneStep());
}
for (final Function f : l1) {
result.add(NewInstance(root, f));
}
}
return result;
}
protected abstract ArrayList<Function> solve() throws Error;
@Override
public boolean isSolved() {
return variable.isSolved() ? !isSolvable() : false;
}
protected abstract boolean isSolvable();
@Override
public void generateGraphics() {
variable.setSmall(small);
variable.generateGraphics();
width = Utils.getFont(small).getStringWidth(getSymbol()) + 1 + getVariable().getWidth();
height = variable.getHeight();
line = variable.getLine();
}
@Override
public void draw(int x, int y) {
final float h1 = getVariable().getHeight();
final int wsegno = Utils.getFont(small).getStringWidth(getSymbol());
final float hsegno = Utils.getFontHeight(small);
final float maxh = getHeight();
Utils.getFont(small).use(DisplayManager.engine);
DisplayManager.renderer.glDrawStringLeft(x, (int) Math.floor(y + (maxh - hsegno) / 2), getSymbol());
getVariable().draw(x + wsegno + 1, (int) Math.floor(y + (maxh - h1) / 2));
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
@Override
public String toString() {
// try {
// return solve().toString();
String val1 = "null";
if (variable != null) {
val1 = variable.toString();
}
return getSymbol() + val1;
// } catch (Error e) {
// return e.id.toString();
// }
}
@Override
public AnteriorFunction clone() {
final Cloner cloner = new Cloner();
return cloner.deepClone(this);
}
@Override
public void setSmall(boolean small) {
this.small = small;
}
@Override
public int hashCode() {
return variable.hashCode() + 883 * getSymbol().hashCode();
}
@Override
public abstract boolean equals(Object o);
}

View File

@ -1,13 +1,11 @@
package org.warp.picalculator.math.functions;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.rules.FractionsRule1;
import org.warp.picalculator.math.rules.FractionsRule11;
import org.warp.picalculator.math.rules.FractionsRule12;
@ -15,24 +13,16 @@ import org.warp.picalculator.math.rules.FractionsRule2;
import org.warp.picalculator.math.rules.FractionsRule3;
import org.warp.picalculator.math.rules.UndefinedRule2;
public class Division extends FunctionTwoValues {
public class Division extends FunctionOperator {
public Division(Calculator root, Function value1, Function value2) {
public Division(MathContext root, Function value1, Function value2) {
super(root, value1, value2);
}
@Override
protected Function NewInstance(Calculator root, Function value1, Function value2) {
return new Division(root, value1, value2);
}
@Override
public String getSymbol() {
return MathematicalSymbols.DIVISION;
}
@Override
protected boolean isSolvable() {
final Function variable1 = getParameter1();
final Function variable2 = getParameter2();
if (FractionsRule1.compare(this)) {
return true;
}
@ -52,10 +42,10 @@ public class Division extends FunctionTwoValues {
return true;
}
if (variable1 instanceof Number && variable2 instanceof Number) {
if (root.exactMode) {
if (getMathContext().exactMode) {
try {
return ((Number) variable1).divide((Number) variable2).isInteger();
} catch (Error e) {
} catch (final Error e) {
return false;
}
} else {
@ -66,8 +56,10 @@ public class Division extends FunctionTwoValues {
}
@Override
public ArrayList<Function> solve() throws Error {
ArrayList<Function> result = new ArrayList<>();
public ObjectArrayList<Function> solve() throws Error {
final Function variable1 = getParameter1();
final Function variable2 = getParameter2();
ObjectArrayList<Function> result = new ObjectArrayList<>();
if (FractionsRule1.compare(this)) {
result = FractionsRule1.execute(this);
} else if (FractionsRule2.compare(this)) {
@ -86,147 +78,22 @@ public class Division extends FunctionTwoValues {
return result;
}
public boolean hasMinus() {
final String numerator = variable1.toString();
if (numerator.startsWith("-")) {
return true;
}
return false;
}
public void draw(int x, int y, boolean small, boolean drawMinus) {
final boolean beforedrawminus = this.drawMinus;
this.drawMinus = drawMinus;
draw(x, y);
this.drawMinus = beforedrawminus;
}
private boolean drawMinus = true;
@Override
public void generateGraphics() {
variable1.generateGraphics();
variable2.generateGraphics();
width = calcWidth();
height = calcHeight();
line = variable1.getHeight() + 1;
}
@Override
public void draw(int x, int y) {
// glColor3f(255, 127-50+new Random().nextInt(50), 0);
// glFillRect(x,y,width,height);
// glColor3f(0, 0, 0);
final Object var1 = variable1;
final Object var2 = variable2;
boolean minus = false;
int minusw = 0;
int minush = 0;
String numerator = ((Function) var1).toString();
if (numerator.startsWith("-") && ((Function) var1) instanceof Number) {
minus = true;
numerator = numerator.substring(1);
}
int w1 = 0;
int h1 = 0;
Utils.getFont(small).use(DisplayManager.engine);
if (minus) {
w1 = Utils.getFont(small).getStringWidth(numerator);
h1 = Utils.getFont(small).getCharacterHeight();
} else {
w1 = ((Function) var1).getWidth();
h1 = ((Function) var1).getHeight();
}
final int w2 = ((Function) var2).getWidth();
int maxw;
if (w1 > w2) {
maxw = 1 + w1;
} else {
maxw = 1 + w2;
}
if (minus && drawMinus) {
minusw = Utils.getFont(small).getCharacterWidth() /* Width of minus */ + 1;
minush = Utils.getFont(small).getCharacterHeight();
DisplayManager.renderer.glDrawStringLeft(x + 1, y + h1 + 1 + 1 - (minush / 2), "-");
DisplayManager.renderer.glDrawStringLeft((int) (x + 1 + minusw + 1 + (maxw - w1) / 2d), y, numerator);
} else {
((Function) var1).draw((int) (x + 1 + minusw + (maxw - w1) / 2d), y);
}
((Function) var2).draw((int) (x + 1 + minusw + (maxw - w2) / 2d), y + h1 + 1 + 1 + 1);
DisplayManager.renderer.glFillColor(x + 1 + minusw, y + h1 + 1, maxw, 1);
}
@Override
public int getHeight() {
return height;
}
@Override
protected int calcHeight() {
boolean minus = false;
String numerator = variable1.toString();
if (numerator.startsWith("-") && variable1 instanceof Number) {
minus = true;
numerator = numerator.substring(1);
}
int h1 = 0;
if (minus) {
h1 = Utils.getFontHeight(small);
} else {
h1 = variable1.getHeight();
}
final int h2 = variable2.getHeight();
return h1 + 3 + h2;
}
@Override
public int getLine() {
return line;
}
@Override
public int getWidth() {
return width;
}
@Override
protected int calcWidth() {
boolean minus = false;
String numerator = variable1.toString();
if (numerator.startsWith("-") && variable1 instanceof Number) {
minus = true;
numerator = numerator.substring(1);
}
int w1 = 0;
if (minus) {
w1 = Utils.getFont(small).getStringWidth(numerator);
} else {
w1 = variable1.getWidth();
}
final int w2 = variable2.getWidth();
int maxw = 0;
if (w1 > w2) {
maxw = w1 + 1;
} else {
maxw = w2 + 1;
}
if (minus && drawMinus) {
return 1 + Utils.getFont(small).getCharacterWidth() /* Width of minus */ + 1 + maxw;
} else {
return 1 + maxw;
}
}
@Override
public boolean equals(Object o) {
if (o instanceof Division) {
final FunctionTwoValues f = (FunctionTwoValues) o;
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
final FunctionOperator f = (FunctionOperator) o;
return getParameter1().equals(f.getParameter1()) && getParameter2().equals(f.getParameter2());
}
return false;
}
@Override
public FunctionOperator clone() {
return new Division(getMathContext(), getParameter1(), getParameter2());
}
@Override
public String toString() {
return "(" + getParameter1() + ")/(" + getParameter2() + ")";
}
}

View File

@ -1,76 +1,52 @@
package org.warp.picalculator.math.functions;
import java.util.List;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
public class EmptyNumber implements Function {
public EmptyNumber(Calculator root) {
public EmptyNumber(MathContext root) {
this.root = root;
}
private final Calculator root;
private final MathContext root;
@Override
public String getSymbol() {
return " ";
}
@Override
public List<Function> solveOneStep() throws Error {
public ObjectArrayList<Function> simplify() throws Error {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isSolved() {
public boolean isSimplified() {
return false;
}
@Override
public void generateGraphics() {
}
@Override
public void draw(int x, int y) {
DisplayManager.renderer.glDrawStringLeft(x, y, "");
}
@Override
public int getWidth() {
return Utils.getFont(small).getStringWidth("");
}
@Override
public int getHeight() {
return Utils.getFont(small).getCharacterHeight();
}
@Override
public int getLine() {
return Utils.getFont(small).getCharacterHeight() / 2;
}
@Override
public Calculator getRoot() {
public MathContext getMathContext() {
return root;
}
private boolean small = false;
@Override
public void setSmall(boolean small) {
this.small = small;
}
@Override
public boolean equals(Object o) {
return o instanceof EmptyNumber;
}
@Override
public Function clone() {
return new EmptyNumber(root);
}
@Override
public Function setParameter(int index, Function var) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
@Override
public Function getParameter(int index) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
}

View File

@ -4,7 +4,7 @@ import static org.warp.picalculator.Utils.ArrayToRegex;
import static org.warp.picalculator.Utils.concat;
import java.math.BigDecimal;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -12,8 +12,11 @@ import java.util.regex.Pattern;
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionDynamic;
import org.warp.picalculator.math.FunctionSingle;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.trigonometry.ArcCosine;
import org.warp.picalculator.math.functions.trigonometry.ArcSine;
@ -22,27 +25,27 @@ import org.warp.picalculator.math.functions.trigonometry.Cosine;
import org.warp.picalculator.math.functions.trigonometry.Sine;
import org.warp.picalculator.math.functions.trigonometry.Tangent;
public class Expression extends FunctionMultipleValues {
public class Expression extends FunctionDynamic {
public Expression(Calculator root) {
public Expression(MathContext root) {
super(root);
}
public Expression(Calculator root, Function[] values) {
public Expression(MathContext root, Function[] values) {
super(root, values);
}
public Expression(Calculator root, Function value) {
public Expression(MathContext root, Function value) {
super(root, new Function[] { value });
}
private boolean initialParenthesis = false;
public Expression(Calculator root, String string) throws Error {
public Expression(MathContext root, String string) throws Error {
this(root, string, "", true);
}
public Expression(Calculator root, String string, String debugSpaces, boolean initialParenthesis) throws Error {
public Expression(MathContext root, String string, String debugSpaces, boolean initialParenthesis) throws Error {
super(root);
this.initialParenthesis = initialParenthesis;
boolean isNumber = false;
@ -65,7 +68,7 @@ public class Expression extends FunctionMultipleValues {
// If the expression is already a number:
// Se l'espressione è già un numero:
final Number t = new Number(root, string);
setVariables(new Function[] { t });
functions = new Function[] { t };
Utils.debug.println(debugSpaces + "•Result:" + t.toString());
} else {
// Else prepare the expression:
@ -137,7 +140,7 @@ public class Expression extends FunctionMultipleValues {
}
// Rimuovi i + in eccesso
pattern = Pattern.compile("[" + ArrayToRegex(Utils.add(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions()), "(")) + "]\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions()), new String[] { "(", ")" })) + "]+?[" + ArrayToRegex(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions())) + "]|[" + ArrayToRegex(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions())) + "]+?\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions()), new String[] { "(", ")" })) + "]");
pattern = Pattern.compile("[" + ArrayToRegex(Utils.add(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions), '(')) + "]\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions), new char[] { '(', ')' })) + "]+?[" + ArrayToRegex(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions)) + "]|[" + ArrayToRegex(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions)) + "]+?\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions), new char[] { '(', ')' })) + "]");
matcher = pattern.matcher(processExpression);
symbolsChanged = false;
while (matcher.find()) {
@ -148,14 +151,14 @@ public class Expression extends FunctionMultipleValues {
}
// Correggi i segni - in
processExpression = processExpression.replace("-", MathematicalSymbols.SUBTRACTION);
processExpression = processExpression.replace('-', MathematicalSymbols.SUBTRACTION);
// Correggi i segni dopo di espressioni o funzioni SN in -
pattern = Pattern.compile("[" + Utils.ArrayToRegex(concat(concat(MathematicalSymbols.functions(), new String[] { MathematicalSymbols.PARENTHESIS_OPEN }), MathematicalSymbols.signums(true))) + "]" + MathematicalSymbols.SUBTRACTION);
pattern = Pattern.compile("[" + Utils.ArrayToRegex(concat(concat(MathematicalSymbols.functions, new char[] { MathematicalSymbols.PARENTHESIS_OPEN }), MathematicalSymbols.signums(true))) + "]" + MathematicalSymbols.SUBTRACTION);
matcher = pattern.matcher(processExpression);
while (matcher.find()) {
symbolsChanged = true;
final String correzione = MathematicalSymbols.MINUS;
final char correzione = MathematicalSymbols.MINUS;
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + 2, processExpression.length());
matcher = pattern.matcher(processExpression);
}
@ -192,11 +195,11 @@ public class Expression extends FunctionMultipleValues {
String beforeexp = processExpression.substring(0, matcher.start(0));
final 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), MathematicalSymbols.genericSyntax())), "(")) + "]$").matcher(beforeexp).find()) {
if (Pattern.compile("[^\\-" + Utils.ArrayToRegex(Utils.add(concat(MathematicalSymbols.functions, concat(MathematicalSymbols.signums(true), MathematicalSymbols.genericSyntax)), '(')) + "]$").matcher(beforeexp).find()) {
// Se la stringa precedente finisce con un numero
beforeexp += MathematicalSymbols.MULTIPLICATION;
}
if (Pattern.compile("^[^\\-" + Utils.ArrayToRegex(Utils.add(concat(MathematicalSymbols.functions(), concat(MathematicalSymbols.signums(true), MathematicalSymbols.genericSyntax())), ")")) + "]").matcher(afterexp).find()) {
if (Pattern.compile("^[^\\-" + Utils.ArrayToRegex(Utils.add(concat(MathematicalSymbols.functions, concat(MathematicalSymbols.signums(true), MathematicalSymbols.genericSyntax)), ')')) + "]").matcher(afterexp).find()) {
// Se la stringa successiva inizia con un numero
afterexp = MathematicalSymbols.MULTIPLICATION + afterexp;
}
@ -215,13 +218,13 @@ public class Expression extends FunctionMultipleValues {
debugSpaces += " ";
// Convert the expression to a list of objects
final Expression imputRawParenthesis = new Expression(root);
imputRawParenthesis.setVariables(new Function[] {});
Expression imputRawParenthesis = new Expression(root);
imputRawParenthesis = (Expression) imputRawParenthesis.setParameters(new Function[] {});
String tmp = "";
final String[] functions = concat(concat(concat(concat(MathematicalSymbols.functions(), MathematicalSymbols.parentheses()), MathematicalSymbols.signums(true)), MathematicalSymbols.variables()), MathematicalSymbols.genericSyntax());
final char[] functions = concat(concat(concat(concat(MathematicalSymbols.functions, MathematicalSymbols.parentheses), MathematicalSymbols.signums(true)), MathematicalSymbols.variables), MathematicalSymbols.genericSyntax);
for (int i = 0; i < processExpression.length(); i++) {
// Per ogni carattere cerca se è un numero o una funzione:
final String charI = processExpression.charAt(i) + "";
final char charI = processExpression.charAt(i);
if (Utils.isInArray(charI, functions)) {
// Finds the type of function fron the following list
@ -287,14 +290,14 @@ public class Expression extends FunctionMultipleValues {
} else if (jumps > 0) {
jumps -= 1;
} else if (jumps < 0) {
throw new Error(Errors.UNBALANCED_BRACKETS);
throw new Error(Errors.UNBALANCED_STACK);
}
} else if ((processExpression.charAt(i2) + "").equals(MathematicalSymbols.PARENTHESIS_OPEN)) {
jumps += 1;
}
}
if (endIndex == -1 || endIndex < startIndex) {
throw new Error(Errors.UNBALANCED_BRACKETS);
throw new Error(Errors.UNBALANCED_STACK);
}
startIndex += 1;
i = startIndex;
@ -307,11 +310,11 @@ public class Expression extends FunctionMultipleValues {
f = new Expression(root, tmpExpr, debugSpaces, false);
break;
default:
if (Utils.isInArray(charI, MathematicalSymbols.variables())) {
if (Utils.isInArray(charI, MathematicalSymbols.variables)) {
f = new Variable(root, charI, Variable.V_TYPE.UNKNOWN);
} else {
if (charI == "(" || charI == ")") {
throw new Error(Errors.UNBALANCED_BRACKETS);
if (charI == '(' || charI == ')') {
throw new Error(Errors.UNBALANCED_STACK);
} else {
System.err.println("Unexpected character while parsing expression: " + charI);
throw new Error(Errors.SYNTAX_ERROR);
@ -322,30 +325,30 @@ public class Expression extends FunctionMultipleValues {
if (f instanceof Expression) {
tmp = "";
} else if (f instanceof Variable) {
if (imputRawParenthesis.getVariablesLength() == 0) {
if (imputRawParenthesis.getParametersLength() == 0) {
if (tmp.length() > 0) {
imputRawParenthesis.addFunctionToEnd(new Number(root, tmp));
imputRawParenthesis = (Expression) imputRawParenthesis.appendParameter(new Number(root, tmp));
Utils.debug.println(debugSpaces + "•Added number to expression:" + tmp);
imputRawParenthesis.addFunctionToEnd(new Multiplication(root, null, null));
Utils.debug.println(debugSpaces + "•Added multiplication to expression:" + new Multiplication(root, null, null).getSymbol());
imputRawParenthesis = (Expression) imputRawParenthesis.appendParameter(new Multiplication(root, null, null));
Utils.debug.println(debugSpaces + "•Added multiplication to expression:" + new Multiplication(root, null, null).getClass().getSimpleName());
}
} else {
final Function precedentFunction = imputRawParenthesis.getVariable(imputRawParenthesis.getVariablesLength() - 1);
final Function precedentFunction = imputRawParenthesis.getParameter(imputRawParenthesis.getParametersLength() - 1);
if (tmp.length() > 0) {
if (precedentFunction instanceof Number || precedentFunction instanceof Variable) {
imputRawParenthesis.addFunctionToEnd(new Multiplication(root, null, null));
Utils.debug.println(debugSpaces + "•Added multiplication to expression:" + new Multiplication(root, null, null).getSymbol());
imputRawParenthesis = (Expression) imputRawParenthesis.appendParameter(new Multiplication(root, null, null));
Utils.debug.println(debugSpaces + "•Added multiplication to expression:" + new Multiplication(root, null, null).getClass().getSimpleName());
}
if (tmp.equals("-")) {
imputRawParenthesis.addFunctionToEnd(new Subtraction(root, null, null));
imputRawParenthesis = (Expression) imputRawParenthesis.appendParameter(new Subtraction(root, null, null));
} else {
imputRawParenthesis.addFunctionToEnd(new Number(root, tmp));
imputRawParenthesis = (Expression) imputRawParenthesis.appendParameter(new Number(root, tmp));
Utils.debug.println(debugSpaces + "•Added number to expression:" + tmp);
}
}
if (tmp.length() > 0 || (precedentFunction instanceof Number || precedentFunction instanceof Variable)) {
imputRawParenthesis.addFunctionToEnd(new Multiplication(root, null, null));
Utils.debug.println(debugSpaces + "•Added multiplication to expression:" + new Multiplication(root, null, null).getSymbol());
imputRawParenthesis = (Expression) imputRawParenthesis.appendParameter(new Multiplication(root, null, null));
Utils.debug.println(debugSpaces + "•Added multiplication to expression:" + new Multiplication(root, null, null).getClass().getSimpleName());
}
}
} else {
@ -355,16 +358,16 @@ public class Expression extends FunctionMultipleValues {
tmp = "-1";
}
}
imputRawParenthesis.addFunctionToEnd(new Number(root, tmp));
imputRawParenthesis = (Expression) imputRawParenthesis.appendParameter(new Number(root, tmp));
Utils.debug.println(debugSpaces + "•Added number to expression:" + tmp);
}
}
imputRawParenthesis.addFunctionToEnd(f);
Utils.debug.println(debugSpaces + "•Added variable to expression:" + f.getSymbol() + (f instanceof Number ? " (number)" : " (variable)"));
imputRawParenthesis = (Expression) imputRawParenthesis.appendParameter(f);
Utils.debug.println(debugSpaces + "•Added variable to expression:" + f.getClass().getSimpleName() + (f instanceof Number ? " (number)" : " (variable)"));
tmp = "";
} else {
try {
if (charI.equals("-") == false && charI.equals(".") == false) {
if (charI != '-' && charI != '.') {
new BigDecimal(tmp + charI);
}
// Se il carattere è un numero intero, un segno
@ -378,7 +381,7 @@ public class Expression extends FunctionMultipleValues {
if (tmp.length() > 0) {
Utils.debug.println(debugSpaces + "•Added variable to expression:" + tmp);
try {
imputRawParenthesis.addFunctionToEnd(new Number(root, tmp));
imputRawParenthesis = (Expression) imputRawParenthesis.appendParameter(new Number(root, tmp));
} catch (final NumberFormatException ex) {
throw new Error(Errors.SYNTAX_ERROR);
}
@ -394,13 +397,13 @@ public class Expression extends FunctionMultipleValues {
// Fine suddivisione di insieme
Utils.debug.println(debugSpaces + "•Removing useless parentheses");
for (int i = 0; i < imputRawParenthesis.functions.length; i++) {
if (imputRawParenthesis.functions[i] instanceof Expression) {
final Expression par = (Expression) imputRawParenthesis.functions[i];
if (par.functions.length == 1) {
final Function subFunz = par.functions[0];
for (int i = 0; i < imputRawParenthesis.getParametersLength(); i++) {
if (imputRawParenthesis.getParameter(i) instanceof Expression) {
final Expression par = (Expression) imputRawParenthesis.getParameter(i);
if (par.getParametersLength() == 1) {
final Function subFunz = par.getParameter(0);
if (subFunz instanceof Expression || subFunz instanceof Number || subFunz instanceof Variable) {
imputRawParenthesis.functions[i] = subFunz;
imputRawParenthesis = (Expression) imputRawParenthesis.setParameter(i, subFunz);
Utils.debug.println(debugSpaces + " •Useless parentheses removed");
}
}
@ -410,8 +413,8 @@ public class Expression extends FunctionMultipleValues {
// Inizia l'affinazione dell'espressione
Utils.debug.println(debugSpaces + "•Pushing classes...");
final Function[] oldFunctionsArray = imputRawParenthesis.getVariables();
final ArrayList<Function> oldFunctionsList = new ArrayList<>();
final Function[] oldFunctionsArray = imputRawParenthesis.getParameters();
final ObjectArrayList<Function> oldFunctionsList = new ObjectArrayList<>();
for (int i = 0; i < oldFunctionsArray.length; i++) {
Function funzione = oldFunctionsArray[i];
if (funzione != null) {
@ -458,15 +461,15 @@ public class Expression extends FunctionMultipleValues {
}
Utils.debug.println(debugSpaces + " •Phase: " + step);
while (i < oldFunctionsList.size() && change == false && oldFunctionsList.size() > 1) {
final Function funzioneTMP = oldFunctionsList.get(i);
if (funzioneTMP instanceof FunctionTwoValues) {
Function funzioneTMP = oldFunctionsList.get(i);
if (funzioneTMP instanceof FunctionOperator) {
if (step != "SN Functions") {
if ((step == "sums" && (funzioneTMP instanceof Sum || funzioneTMP instanceof SumSubtraction || funzioneTMP instanceof Subtraction) == 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)))) || (step.equals("multiplications") && ((funzioneTMP instanceof Multiplication) || (funzioneTMP instanceof Division)) && ((FunctionTwoValues) funzioneTMP).variable1 == null && ((FunctionTwoValues) funzioneTMP).variable2 == null) || (step == "NSN Functions" && (funzioneTMP instanceof Sum) == false && (funzioneTMP instanceof SumSubtraction) == false && (funzioneTMP instanceof Subtraction) == false && (funzioneTMP instanceof Multiplication) == false && (funzioneTMP instanceof Division) == false && ((funzioneTMP instanceof AnteriorFunction && ((AnteriorFunction) funzioneTMP).variable == null) || (funzioneTMP instanceof FunctionTwoValues && ((FunctionTwoValues) funzioneTMP).variable1 == null && ((FunctionTwoValues) funzioneTMP).variable2 == null) || (!(funzioneTMP instanceof AnteriorFunction) && !(funzioneTMP instanceof FunctionTwoValues))))) {
if ((step == "sums" && (funzioneTMP instanceof Sum || funzioneTMP instanceof SumSubtraction || funzioneTMP instanceof Subtraction) == true && ((funzioneTMP instanceof FunctionSingle && ((FunctionSingle) funzioneTMP).getParameter() == null) || (funzioneTMP instanceof FunctionOperator && ((FunctionOperator) funzioneTMP).getParameter1() == null && ((FunctionOperator) funzioneTMP).getParameter2() == null) || (!(funzioneTMP instanceof FunctionSingle) && !(funzioneTMP instanceof FunctionOperator)))) || (step.equals("multiplications") && ((funzioneTMP instanceof Multiplication) || (funzioneTMP instanceof Division)) && ((FunctionOperator) funzioneTMP).getParameter1() == null && ((FunctionOperator) funzioneTMP).getParameter2() == null) || (step == "NSN Functions" && (funzioneTMP instanceof Sum) == false && (funzioneTMP instanceof SumSubtraction) == false && (funzioneTMP instanceof Subtraction) == false && (funzioneTMP instanceof Multiplication) == false && (funzioneTMP instanceof Division) == false && ((funzioneTMP instanceof FunctionSingle && ((FunctionSingle) funzioneTMP).getParameter() == null) || (funzioneTMP instanceof FunctionOperator && ((FunctionOperator) funzioneTMP).getParameter1() == null && ((FunctionOperator) funzioneTMP).getParameter2() == null) || (!(funzioneTMP instanceof FunctionSingle) && !(funzioneTMP instanceof FunctionOperator))))) {
change = true;
if (i + 1 < oldFunctionsList.size() && i - 1 >= 0) {
((FunctionTwoValues) funzioneTMP).setVariable1(oldFunctionsList.get(i - 1));
((FunctionTwoValues) funzioneTMP).setVariable2(oldFunctionsList.get(i + 1));
funzioneTMP = ((FunctionOperator) funzioneTMP).setParameter1(oldFunctionsList.get(i - 1));
funzioneTMP = ((FunctionOperator) funzioneTMP).setParameter2(oldFunctionsList.get(i + 1));
oldFunctionsList.set(i, funzioneTMP);
// è importante togliere prima gli elementi
@ -475,15 +478,15 @@ public class Expression extends FunctionMultipleValues {
oldFunctionsList.remove(i + 1);
oldFunctionsList.remove(i - 1);
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getSymbol());
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getClass().getSimpleName());
try {
Utils.debug.println(debugSpaces + " " + "var1=" + ((FunctionTwoValues) funzioneTMP).getVariable1().toString());
Utils.debug.println(debugSpaces + " " + "var1=" + ((FunctionOperator) funzioneTMP).getParameter1().toString());
} catch (final NullPointerException ex2) {}
try {
Utils.debug.println(debugSpaces + " " + "var2=" + ((FunctionTwoValues) funzioneTMP).getVariable2().toString());
Utils.debug.println(debugSpaces + " " + "var2=" + ((FunctionOperator) funzioneTMP).getParameter2().toString());
} catch (final NullPointerException ex2) {}
try {
Utils.debug.println(debugSpaces + " " + "(result)=" + ((FunctionTwoValues) funzioneTMP).toString());
Utils.debug.println(debugSpaces + " " + "(result)=" + ((FunctionOperator) funzioneTMP).toString());
} catch (final NullPointerException ex2) {}
} else {
@ -491,15 +494,15 @@ public class Expression extends FunctionMultipleValues {
}
}
}
} else if (funzioneTMP instanceof AnteriorFunction) {
if ((step == "SN Functions" && ((AnteriorFunction) funzioneTMP).variable == null)) {
} else if (funzioneTMP instanceof FunctionSingle) {
if ((step == "SN Functions" && ((FunctionSingle) funzioneTMP).getParameter() == null)) {
if (i + 1 < oldFunctionsList.size()) {
final Function nextFunc = oldFunctionsList.get(i + 1);
if (nextFunc instanceof AnteriorFunction && ((AnteriorFunction) nextFunc).variable == null) {
if (nextFunc instanceof FunctionSingle && ((FunctionSingle) nextFunc).getParameter() == null) {
} else {
change = true;
((AnteriorFunction) funzioneTMP).setVariable(nextFunc);
funzioneTMP = ((FunctionSingle) funzioneTMP).setParameter(nextFunc);
oldFunctionsList.set(i, funzioneTMP);
// è importante togliere prima gli elementi in
@ -507,8 +510,8 @@ public class Expression extends FunctionMultipleValues {
// scalano da destra a sinistra.
oldFunctionsList.remove(i + 1);
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getSymbol());
final Function var = ((AnteriorFunction) funzioneTMP).getVariable();
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getClass().getSimpleName());
final Function var = ((FunctionSingle) funzioneTMP).getParameter();
if (var == null) {
Utils.debug.println(debugSpaces + " " + "var=null");
} else {
@ -533,9 +536,9 @@ public class Expression extends FunctionMultipleValues {
} while (((oldFunctionsList.size() != before || step != "sums") && oldFunctionsList.size() > 1));
}
if (oldFunctionsList.isEmpty()) {
setVariables(new Function[] { new Number(root, 0) });
super.functions = new Function[] { new Number(root, 0) };
} else {
setVariables(oldFunctionsList);
super.functions = oldFunctionsList.toArray(new Function[oldFunctionsList.size()]);
}
dsl = debugSpaces.length();
@ -550,18 +553,13 @@ public class Expression extends FunctionMultipleValues {
}
}
@Override
public String getSymbol() {
return "Parentesi";
}
@Override
protected boolean isSolvable() {
if (functions.length > 1) {
if (getParametersLength() > 1) {
return true;
} else if (functions.length == 1) {
final Function f = functions[0];
if (f.isSolved() == false) {
} else if (getParametersLength() == 1) {
final Function f = getParameter(0);
if (f.isSimplified() == false) {
return true;
} else {
return !parenthesisNeeded();
@ -571,14 +569,14 @@ public class Expression extends FunctionMultipleValues {
}
@Override
public List<Function> solveOneStep() throws Error {
final List<Function> ret = new ArrayList<>();
if (functions.length == 1) {
if (functions[0].isSolved() || !parenthesisNeeded()) {
ret.add(functions[0]);
public ObjectArrayList<Function> solve() throws Error {
final ObjectArrayList<Function> ret = new ObjectArrayList<>();
if (getParametersLength() == 1) {
if (getParameter(0).isSimplified() || !parenthesisNeeded()) {
ret.add(getParameter(0));
return ret;
} else {
final List<Function> l = functions[0].solveOneStep();
final List<Function> l = getParameter(0).simplify();
for (final Function f : l) {
if (f instanceof Number || f instanceof Variable) {
ret.add(f);
@ -589,9 +587,9 @@ public class Expression extends FunctionMultipleValues {
return ret;
}
} else {
for (final Function f : functions) {
if (f.isSolved() == false) {
final List<Function> partial = f.solveOneStep();
for (final Function f : getParameters()) {
if (f.isSimplified() == false) {
final List<Function> partial = f.simplify();
for (final Function fnc : partial) {
ret.add(new Expression(root, new Function[] { fnc }));
}
@ -601,34 +599,22 @@ public class Expression extends FunctionMultipleValues {
}
}
@Override
public void generateGraphics() {
for (final Function var : functions) {
var.setSmall(small);
var.generateGraphics();
}
width = calcWidth();
height = calcHeight();
line = calcLine();
}
public boolean parenthesisNeeded() {
boolean parenthesisneeded = true;
if (initialParenthesis) {
parenthesisneeded = false;
} else {
if (functions.length == 1) {
final Function f = functions[0];
if (getParametersLength() == 1) {
final Function f = getParameter(0);
if (f instanceof Number || f instanceof Variable || f instanceof Expression || f instanceof Division || f instanceof Joke || f instanceof Undefined || f instanceof Power || f instanceof Sine || f instanceof Cosine || f instanceof Tangent || f instanceof ArcSine || f instanceof ArcCosine || f instanceof ArcTangent || f instanceof RootSquare) {
parenthesisneeded = false;
}
if (f instanceof Multiplication) {
if (((Multiplication) f).getVariable1() instanceof Number) {
parenthesisneeded = !(((Multiplication) f).getVariable2() instanceof Variable);
} else if (((Multiplication) f).getVariable2() instanceof Number) {
parenthesisneeded = !(((Multiplication) f).getVariable1() instanceof Variable);
} else if (((Multiplication) f).getVariable1() instanceof Variable || ((Multiplication) f).getVariable2() instanceof Variable) {
if (((Multiplication) f).getParameter1() instanceof Number) {
parenthesisneeded = !(((Multiplication) f).getParameter2() instanceof Variable);
} else if (((Multiplication) f).getParameter2() instanceof Number) {
parenthesisneeded = !(((Multiplication) f).getParameter1() instanceof Variable);
} else if (((Multiplication) f).getParameter1() instanceof Variable || ((Multiplication) f).getParameter2() instanceof Variable) {
parenthesisneeded = false;
}
}
@ -637,136 +623,29 @@ public class Expression extends FunctionMultipleValues {
return parenthesisneeded;
}
@Override
public void draw(int x, int y) {
if (parenthesisNeeded() == false) {
functions[0].draw(x, y);
} else {
final float miny = y;
final float maxy = y + getHeight();
final int h = getHeight();
x += 1;
DisplayManager.renderer.glDrawLine(x, y + 2, x, y + 2);
DisplayManager.renderer.glDrawLine( x + 1, y + 1, x + 1, y + 1);
DisplayManager.renderer.glDrawLine( x + 2, y, x + 2, y);
DisplayManager.renderer.glDrawLine(x, y + 2, x, y + h - 3);
DisplayManager.renderer.glDrawLine(x, y + h - 3, x, y + h - 3);
DisplayManager.renderer.glDrawLine(x + 1, y + h - 2, x + 1, y + h - 2);
DisplayManager.renderer.glDrawLine(x + 2, y + h - 1, x + 2, y + h - 1);
x += 4;
for (final Function f : functions) {
final float fheight = f.getHeight();
final float y2 = miny + ((maxy - miny) / 2 - fheight / 2);
f.draw(x, (int) y2);
x += f.getWidth();
}
x += 2;
DisplayManager.renderer.glDrawLine(x, y, x, y);
DisplayManager.renderer.glDrawLine(x + 1, y + 1, x + 1, y + 1);
DisplayManager.renderer.glDrawLine(x + 2, y + 2, x + 2, y + 2);
DisplayManager.renderer.glDrawLine(x + 2, y + 2, x + 2, y + h - 3);
DisplayManager.renderer.glDrawLine(x, y + h - 1, x, y + h - 1);
DisplayManager.renderer.glDrawLine(x + 1, y + h - 2, x + 1, y + h - 2);
DisplayManager.renderer.glDrawLine(x + 2, y + h - 3, x + 2, y + h - 3);
x += 4;
}
}
@Override
public int getWidth() {
return width;
}
private int calcWidth() {
if (parenthesisNeeded() == false) {
return functions[0].getWidth();
} else {
int w = 0;
for (final Function f : functions) {
w += f.getWidth();
}
return 1 + 4 + w + 2 + 4;
}
}
@Override
public int getHeight() {
return height;
}
private int calcHeight() {
if (initialParenthesis || functions.length == 1) {
return functions[0].getHeight();
} else {
Function tmin = null;
Function tmax = null;
for (final Function t : functions) {
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 || functions.length == 1) {
return functions[0].getLine();
} else {
Function tl = null;
for (final Function t : functions) {
if (tl == null || t.getLine() >= tl.getLine()) {
tl = t;
}
}
if (tl == null) {
return Utils.getFontHeight(small) / 2;
}
return tl.getLine();
}
}
@Override
public String toString() {
String vars = "null";
if (functions != null && functions.length > 0) {
if (functions.length == 1) {
if (functions[0] != null) {
vars = functions[0].toString();
}
String s = "(";
if (functions.length > 0) {
for (final Function f : functions) {
if (f == null) {
s += "[null],";
} else {
for (final Function variable : functions) {
if (variable != null) {
vars += ", " + variable.toString();
s += f.toString() + ",";
}
}
vars = vars.substring(2);
s = s.substring(0, s.length() - 1);
}
}
return "(" + vars + ")";
s += ")";
return s;
}
@Override
public boolean equals(Object o) {
if (o instanceof Expression) {
final Expression f = (Expression) o;
final Function[] exprFuncs1 = functions;
final Function[] exprFuncs2 = f.functions;
final Function[] exprFuncs1 = getParameters();
final Function[] exprFuncs2 = f.getParameters();
if (exprFuncs1.length == exprFuncs2.length) {
for (int i = 0; i < exprFuncs1.length; i++) {
if (exprFuncs1[i].equals(exprFuncs2[i]) == false) {
@ -775,13 +654,18 @@ public class Expression extends FunctionMultipleValues {
}
return true;
}
} else if (o != null & getVariablesLength() == 1) {
} else if (o != null & getParametersLength() == 1) {
final Function f = (Function) o;
return (functions[0].equals(f));
} else if (o == null & getVariablesLength() == 0) {
return (getParameter(0).equals(f));
} else if (o == null & getParametersLength() == 0) {
return true;
}
return false;
}
@Override
public Expression clone() {
return new Expression(root, functions);
}
}

View File

@ -1,34 +0,0 @@
package org.warp.picalculator.math.functions;
import java.util.List;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Calculator;
public interface Function {
public String getSymbol();
public List<Function> solveOneStep() throws Error;
public boolean isSolved();
public void generateGraphics() throws NullPointerException;
public void draw(int x, int y);
public int getWidth();
public int getHeight();
public int getLine();
public Calculator getRoot();
public void setSmall(boolean small);
@Override
public int hashCode();
@Override
public boolean equals(Object o);
}

View File

@ -1,129 +0,0 @@
package org.warp.picalculator.math.functions;
import java.util.Arrays;
import java.util.List;
import org.warp.picalculator.math.Calculator;
import com.rits.cloning.Cloner;
public abstract class FunctionMultipleValues implements Function {
public FunctionMultipleValues(Calculator root) {
this.root = root;
functions = new Function[] {};
}
public FunctionMultipleValues(Function[] values) {
if (values.length > 0) {
root = values[0].getRoot();
} else {
throw new NullPointerException("Nessun elemento nell'array. Impossibile ricavare il nodo root");
}
functions = values;
}
public FunctionMultipleValues(Calculator root, Function[] values) {
this.root = root;
functions = values;
}
protected final Calculator root;
protected Function[] functions;
protected int width;
protected int height;
protected int line;
protected boolean small;
public Function[] getVariables() {
return functions;
}
public void setVariables(final List<Function> value) {
final int vsize = value.size();
final Function[] tmp = new Function[vsize];
for (int i = 0; i < vsize; i++) {
tmp[i] = value.get(i);
}
functions = tmp;
}
public void setVariables(final Function[] value) {
functions = value;
}
public Function getVariable(int index) {
return functions[index];
}
public void setVariable(int index, Function value) {
functions[index] = value;
}
public void addFunctionToEnd(Function value) {
final int index = functions.length;
setVariablesLength(index + 1);
functions[index] = value;
}
public int getVariablesLength() {
return functions.length;
}
public void setVariablesLength(int length) {
functions = Arrays.copyOf(functions, length);
}
@Override
public abstract String getSymbol();
@Override
public boolean isSolved() {
for (final Function variable : functions) {
if (!variable.isSolved()) {
return false;
}
}
return !isSolvable();
}
protected abstract boolean isSolvable();
@Override
public Calculator getRoot() {
return root;
}
@Override
public abstract void generateGraphics();
@Override
public String toString() {
// try {
// return solve().toString();
return "TODO: fare una nuova alternativa a solve().toString()";
// } catch (Error e) {
// return e.id.toString();
// }
}
@Override
public Function clone() {
final Cloner cloner = new Cloner();
return cloner.deepClone(this);
}
@Override
public void setSmall(boolean small) {
this.small = small;
}
@Override
public int hashCode() {
return functions.hashCode() + 883 * getSymbol().hashCode();
}
@Override
public boolean equals(Object o) {
return false;
}
}

View File

@ -1,197 +0,0 @@
package org.warp.picalculator.math.functions;
import java.util.ArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
import org.warp.picalculator.math.Calculator;
import com.rits.cloning.Cloner;
public abstract class FunctionTwoValues implements Function {
public FunctionTwoValues(Calculator root, Function value1, Function value2) {
this.root = root;
variable1 = value1;
variable2 = value2;
}
protected abstract Function NewInstance(Calculator root, Function value1, Function value2);
protected final Calculator root;
protected Function variable1 = null;
protected Function variable2 = null;
protected int width;
protected int height;
protected int line;
protected boolean small;
public Function getVariable1() {
return variable1;
}
public void setVariable1(Function value) {
variable1 = value;
}
@Override
public Calculator getRoot() {
return root;
}
public Function getVariable2() {
return variable2;
}
public void setVariable2(Function value) {
variable2 = value;
}
@Override
public abstract String getSymbol();
@Override
public boolean isSolved() {
return (variable1.isSolved() & variable2.isSolved()) ? !isSolvable() : false;
}
protected abstract boolean isSolvable();
@Override
public final ArrayList<Function> solveOneStep() throws Error {
final boolean solved = variable1.isSolved() & variable2.isSolved();
ArrayList<Function> result = solved ? solve() : null;;
if (result == null || result.isEmpty()) {
result = new ArrayList<>();
final ArrayList<Function> l1 = new ArrayList<>();
final ArrayList<Function> l2 = new ArrayList<>();
if (variable1.isSolved()) {
l1.add(variable1);
} else {
l1.addAll(variable1.solveOneStep());
}
if (variable2.isSolved()) {
l2.add(variable2);
} else {
l2.addAll(variable2.solveOneStep());
}
final Function[][] results = Utils.joinFunctionsResults(l1, l2);
for (final Function[] f : results) {
result.add(NewInstance(root, f[0], f[1]));
}
}
return result;
}
protected abstract ArrayList<Function> solve() throws Error;
@Override
public void generateGraphics() {
variable1.setSmall(small);
variable1.generateGraphics();
variable2.setSmall(small);
variable2.generateGraphics();
width = calcWidth();
height = calcHeight();
line = calcLine();
}
@Override
public void draw(int x, int y) {
final int ln = getLine();
int dx = 0;
variable1.draw(dx + x, ln - variable1.getLine() + y);
dx += 1 + variable1.getWidth();
if (drawSignum()) {
Utils.getFont(small).use(DisplayManager.engine);
DisplayManager.renderer.glDrawStringLeft(dx + x, ln - Utils.getFontHeight(small) / 2 + y, getSymbol());
dx += Utils.getFont(small).getStringWidth(getSymbol());
}
variable2.draw(dx + x, ln - variable2.getLine() + y);
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
@Override
public String toString() {
String val1 = "null";
String val2 = "null";
if (variable1 != null) {
val1 = variable1.toString();
}
if (variable2 != null) {
val2 = variable2.toString();
}
return val1 + getSymbol() + val2;
}
@Override
public FunctionTwoValues clone() {
final Cloner cloner = new Cloner();
return cloner.deepClone(this);
}
public boolean drawSignum() {
return true;
}
@Override
public void setSmall(boolean small) {
this.small = small;
}
protected int calcWidth() {
return variable1.getWidth() + 1 + (drawSignum() ? Utils.getFont(small).getStringWidth(getSymbol()) : 0) + variable2.getWidth();
}
protected int calcHeight() {
Function tmin = variable1;
Function tmax = variable1;
if (tmin == null || variable2.getLine() >= tmin.getLine()) {
tmin = variable2;
}
if (tmax == null || variable2.getHeight() - variable2.getLine() >= tmax.getHeight() - tmax.getLine()) {
tmax = variable2;
}
return tmin.getLine() + tmax.getHeight() - tmax.getLine();
}
protected int calcLine() {
Function tl = variable1;
if (tl == null || variable2.getLine() >= tl.getLine()) {
tl = variable2;
}
return tl.getLine();
}
@Override
public int hashCode() {
return variable1.hashCode() + 7 * variable2.hashCode() + 883 * getSymbol().hashCode();
}
@Override
public abstract boolean equals(Object o);
}

View File

@ -1,13 +1,9 @@
package org.warp.picalculator.math.functions;
import java.util.List;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
public class Joke implements Function {
@ -17,78 +13,41 @@ public class Joke implements Function {
private static final String[] jokes = new String[] { "", "TORNADO", "SHARKNADO" };
private static final int[] jokesFont = new int[] { 4, -1, -1 };
private final byte joke;
private final Calculator root;
private final MathContext root;
public Joke(Calculator root, byte joke) {
public Joke(MathContext root, byte joke) {
this.root = root;
this.joke = joke;
}
@Override
public String getSymbol() {
return "joke";
}
@Override
public List<Function> solveOneStep() throws Error {
public ObjectArrayList<Function> simplify() throws Error {
return null;
}
@Override
public boolean isSolved() {
public boolean isSimplified() {
return true;
}
@Override
public void generateGraphics() {
}
@Override
public void draw(int x, int y) {
final BinaryFont rf = DisplayManager.renderer.getCurrentFont();
if (jokesFont[joke] >= 0) {
DisplayManager.fonts[jokesFont[joke]].use(DisplayManager.engine);
}
DisplayManager.renderer.glDrawStringLeft(x, y, jokes[joke]);
if (jokesFont[joke] >= 0) {
rf.use(DisplayManager.engine);
}
}
@Override
public int getWidth() {
if (jokesFont[joke] >= 0) {
return DisplayManager.fonts[jokesFont[joke]].getStringWidth(jokes[joke]);
} else {
return Utils.getFont(small).getStringWidth(jokes[joke]);
}
}
@Override
public int getHeight() {
if (jokesFont[joke] >= 0) {
return DisplayManager.fonts[jokesFont[joke]].getCharacterHeight();
} else {
return Utils.getFont(small).getCharacterHeight();
}
}
@Override
public int getLine() {
return getHeight() / 2;
}
@Override
public Calculator getRoot() {
public MathContext getMathContext() {
return root;
}
private boolean small = false;
@Override
public Function clone() {
return new Joke(root, joke);
}
@Override
public void setSmall(boolean small) {
this.small = small;
public Function setParameter(int index, Function var) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
@Override
public Function getParameter(int index) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
}

View File

@ -1,10 +1,11 @@
package org.warp.picalculator.math.functions;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.rules.ExponentRule15;
import org.warp.picalculator.math.rules.ExponentRule16;
import org.warp.picalculator.math.rules.FractionsRule14;
@ -14,28 +15,20 @@ import org.warp.picalculator.math.rules.NumberRule6;
import org.warp.picalculator.math.rules.SyntaxRule1;
import org.warp.picalculator.math.rules.methods.MultiplicationMethod1;
public class Multiplication extends FunctionTwoValues {
public class Multiplication extends FunctionOperator {
public Multiplication(Calculator root, Function value1, Function value2) {
public Multiplication(MathContext root, Function value1, Function value2) {
super(root, value1, value2);
if (value1 instanceof Variable && value2 instanceof Variable == false) {
variable1 = value2;
variable2 = value1;
parameter1 = value2;
parameter2 = value1;
}
}
@Override
protected Function NewInstance(Calculator root, Function value1, Function value2) {
return new Multiplication(root, value1, value2);
}
@Override
public String getSymbol() {
return MathematicalSymbols.MULTIPLICATION;
}
@Override
protected boolean isSolvable() {
final Function variable1 = getParameter1();
final Function variable2 = getParameter2();
if (variable1 instanceof Number & variable2 instanceof Number) {
return true;
}
@ -67,8 +60,8 @@ public class Multiplication extends FunctionTwoValues {
}
@Override
public ArrayList<Function> solve() throws Error {
ArrayList<Function> result = new ArrayList<>();
public ObjectArrayList<Function> solve() throws Error {
ObjectArrayList<Function> result = new ObjectArrayList<>();
if (SyntaxRule1.compare(this)) {
result = SyntaxRule1.execute(this);
} else if (NumberRule1.compare(this)) {
@ -85,92 +78,32 @@ public class Multiplication extends FunctionTwoValues {
result = FractionsRule14.execute(this);
} else if (MultiplicationMethod1.compare(this)) {
result = MultiplicationMethod1.execute(this);
} else if (variable1.isSolved() & variable2.isSolved()) {
result.add(((Number) variable1).multiply((Number) variable2));
} else if (parameter1.isSimplified() & parameter2.isSimplified()) {
result.add(((Number) parameter1).multiply((Number) parameter2));
}
return result;
}
@Override
public boolean drawSignum() {
final Function[] tmpVar = new Function[] { variable1, variable2 };
final boolean[] ok = new boolean[] { false, false };
for (int val = 0; val < 2; val++) {
while (!ok[val]) {
if (tmpVar[val] instanceof Division) {
ok[0] = true;
ok[1] = true;
} else if (tmpVar[val] instanceof Variable) {
ok[val] = true;
} else if (tmpVar[val] instanceof Number) {
if (val == 0) {
ok[val] = true;
} else {
if (!(tmpVar[0] instanceof Number)) {
ok[val] = true;
} else {
break;
}
}
} else if (tmpVar[val] instanceof Power) {
tmpVar[val] = ((Power) tmpVar[val]).variable1;
} else if (tmpVar[val] instanceof Root) {
if (val == 0) {
break;
}
ok[val] = true;
} else if (tmpVar[val] instanceof RootSquare) {
if (val == 0) {
break;
}
ok[val] = true;
} else if (tmpVar[val] instanceof Undefined) {
break;
} else if (tmpVar[val] instanceof Joke) {
break;
} else if (tmpVar[val] instanceof Negative) {
if (val == 1) {
break;
}
ok[val] = true;
} else if (tmpVar[val] instanceof Expression) {
if (((Expression)tmpVar[val]).parenthesisNeeded() == true) {
ok[0] = true;
ok[1] = true;
} else {
break;
}
} else if (tmpVar[val] instanceof FunctionTwoValues) {
if (val == 0) {
tmpVar[val] = ((FunctionTwoValues) tmpVar[val]).variable2;
} else {
tmpVar[val] = ((FunctionTwoValues) tmpVar[val]).variable1;
}
} else if (tmpVar[val] instanceof AnteriorFunction) {
tmpVar[val] = ((AnteriorFunction) tmpVar[val]).variable;
} else {
ok[val] = true;
}
}
}
if (ok[0] == true && ok[1] == true) {
return false;
} else {
public boolean equals(Object o) {
if (o instanceof Multiplication) {
final FunctionOperator f = (FunctionOperator) o;
if (parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2())) {
return true;
} else if (parameter1.equals(f.getParameter2()) && parameter2.equals(f.getParameter1())) {
return true;
}
}
return false;
}
@Override
public boolean equals(Object o) {
if (o instanceof Multiplication) {
final FunctionTwoValues f = (FunctionTwoValues) o;
if (variable1.equals(f.variable1) && variable2.equals(f.variable2)) {
return true;
} else if (variable1.equals(f.variable2) && variable2.equals(f.variable1)) {
return true;
}
}
return false;
public Multiplication clone() {
return new Multiplication(mathContext, parameter1, parameter2);
}
@Override
public String toString() {
return "(" + parameter1.toString() + ")*(" + parameter2.toString() + ")";
}
}

View File

@ -1,46 +1,24 @@
package org.warp.picalculator.math.functions;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
import org.warp.picalculator.math.rules.ExpandRule1;
import org.warp.picalculator.math.rules.ExpandRule5;
public class Negative extends AnteriorFunction {
public class Negative extends FunctionSingle {
public Negative(Calculator root, Function value) {
public Negative(MathContext root, Function value) {
super(root, value);
}
@Override
public Function NewInstance(Calculator root, Function value) {
return new Negative(root, value);
}
@Override
public String getSymbol() {
return MathematicalSymbols.MINUS;
}
@Override
public void generateGraphics() {
variable.setSmall(small);
variable.generateGraphics();
height = getVariable().getHeight();
width = Utils.getFont(small).getCharacterWidth() /* Width of - */ + getVariable().getWidth();
line = getVariable().getLine();
}
@Override
protected boolean isSolvable() {
if (variable instanceof Number) {
if (parameter instanceof Number) {
return true;
}
if (ExpandRule1.compare(this)) {
@ -53,19 +31,19 @@ public class Negative extends AnteriorFunction {
}
@Override
public ArrayList<Function> solve() throws Error {
if (variable == null) {
public ObjectArrayList<Function> solve() throws Error {
if (parameter == null) {
throw new Error(Errors.SYNTAX_ERROR);
}
ArrayList<Function> result = new ArrayList<>();
ObjectArrayList<Function> result = new ObjectArrayList<>();
if (ExpandRule1.compare(this)) {
result = ExpandRule1.execute(this);
} else if (ExpandRule5.compare(this)) {
result = ExpandRule5.execute(this);
} else if (variable.isSolved()) {
} else if (parameter.isSimplified()) {
try {
final Number var = (Number) getVariable();
result.add(var.multiply(new Number(root, "-1")));
final Number var = (Number) getParameter();
result.add(var.multiply(new Number(mathContext, "-1")));
} catch (final NullPointerException ex) {
throw new Error(Errors.ERROR);
} catch (final NumberFormatException ex) {
@ -74,40 +52,30 @@ public class Negative extends AnteriorFunction {
throw new Error(Errors.NUMBER_TOO_SMALL);
}
} else {
final ArrayList<Function> l1 = new ArrayList<>();
if (variable.isSolved()) {
l1.add(variable);
final ObjectArrayList<Function> l1 = new ObjectArrayList<>();
if (parameter.isSimplified()) {
l1.add(parameter);
} else {
l1.addAll(variable.solveOneStep());
l1.addAll(parameter.simplify());
}
for (final Function f : l1) {
result.add(new Negative(root, f));
result.add(new Negative(mathContext, f));
}
}
return result;
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
@Override
public boolean equals(Object o) {
if (o instanceof Negative) {
return ((Negative) o).variable.equals(variable);
return ((Negative) o).getParameter().equals(parameter);
}
return false;
}
@Override
public Negative clone() {
return new Negative(mathContext, parameter);
}
}

View File

@ -2,52 +2,44 @@ package org.warp.picalculator.math.functions;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.LinkedList;
import java.util.List;
import org.nevec.rjm.BigDecimalMath;
import org.nevec.rjm.BigIntegerMath;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.math.Calculator;
import com.rits.cloning.Cloner;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
public class Number implements Function {
private final Calculator root;
private final MathContext root;
protected BigDecimal term;
protected int width;
protected int height;
protected int line;
protected boolean small;
public Number(Calculator root, BigInteger val) {
public Number(MathContext root, BigInteger val) {
this.root = root;
term = new BigDecimal(val).setScale(Utils.scale, Utils.scaleMode2);
}
public Number(Calculator root, BigDecimal val) {
public Number(MathContext root, BigDecimal val) {
this.root = root;
term = val.setScale(Utils.scale, Utils.scaleMode2);
}
public Number(Calculator root, String s) throws Error {
public Number(MathContext root, String s) throws Error {
this(root, new BigDecimal(s).setScale(Utils.scale, Utils.scaleMode2));
}
public Number(Calculator root, int s) {
public Number(MathContext root, int s) {
this(root, BigDecimal.valueOf(s).setScale(Utils.scale, Utils.scaleMode2));
}
public Number(Calculator root, float s) {
public Number(MathContext root, float s) {
this(root, BigDecimal.valueOf(s).setScale(Utils.scale, Utils.scaleMode2));
}
public Number(Calculator root, double s) {
public Number(MathContext root, double s) {
this(root, BigDecimal.valueOf(s).setScale(Utils.scale, Utils.scaleMode2));
}
@ -59,18 +51,6 @@ public class Number implements Function {
term = val.setScale(Utils.scale, Utils.scaleMode2);
}
@Override
public void generateGraphics() {
line = calcLine(); //TODO pp
height = calcHeight();
width = calcWidth();
}
@Override
public String getSymbol() {
return toString();
}
public Number add(Number f) {
final Number ret = new Number(root, getTerm().add(f.getTerm()));
return ret;
@ -120,115 +100,13 @@ public class Number implements Function {
return s;
}
// public void draw(int x, int y, PIDisplay g, boolean small, boolean drawMinus) {
// boolean beforedrawminus = this.drawMinus;
// this.drawMinus = drawMinus;
// draw(x, y, small);
// this.drawMinus = beforedrawminus;
// }
private boolean drawMinus = true;
@Override
public void draw(int x, int y) {
Utils.getFont(small).use(DisplayManager.engine);
String t = toString();
if (t.startsWith("-")) {
if (drawMinus) {
} else {
t = t.substring(1);
}
}
if (t.contains("")) {
final BinaryFont defaultf = Utils.getFont(small);
final BinaryFont smallf = Utils.getFont(true);
final String s = t.substring(0, t.indexOf("") + 2);
final int sw = defaultf.getStringWidth(s);
DisplayManager.renderer.glDrawStringLeft(x + 1, y + smallf.getCharacterHeight() - 2, s);
smallf.use(DisplayManager.engine);
DisplayManager.renderer.glDrawStringLeft(x + 1 + sw - 3, y, t.substring(t.indexOf("") + 2));
} else {
DisplayManager.renderer.glDrawStringLeft(x + 1, y, t);
}
}
public int getHeight(boolean drawMinus) {
final boolean beforedrawminus = this.drawMinus;
this.drawMinus = drawMinus;
final int h = getHeight();
this.drawMinus = beforedrawminus;
return h;
}
@Override
public int getHeight() {
return height;
}
private int calcHeight() {
final String t = toString();
if (t.contains("")) {
return Utils.getFontHeight(small) - 2 + Utils.getFontHeight(true);
} else {
final int h1 = Utils.getFontHeight(small);
return h1;
}
}
@Override
public int getWidth() {
return width;
}
public int calcWidth() {
String t = toString();
if (t.startsWith("-")) {
if (drawMinus) {
} else {
t = t.substring(1);
}
}
if (t.contains("")) {
final BinaryFont defaultf = Utils.getFont(small);
final BinaryFont smallf = Utils.getFont(true);
final String s = t.substring(0, t.indexOf("") + 2);
final int sw = defaultf.getStringWidth(s);
return 1 + sw - 3 + smallf.getStringWidth(t.substring(t.indexOf("") + 2));
} else {
return Utils.getFont(small).getStringWidth(t) + 1;
}
}
@Override
public int getLine() {
return line;
}
private int calcLine() {
final String t = toString();
if (t.contains("")) {
return (Utils.getFontHeight(small) / 2) - 2 + Utils.getFontHeight(true);
} else {
return Utils.getFontHeight(small) / 2;
}
}
@Override
public Number clone() {
final Cloner cloner = new Cloner();
return cloner.deepClone(this);
return new Number(root, term);
}
@Override
public void setSmall(boolean small) {
this.small = small;
}
@Override
public boolean isSolved() {
public boolean isSimplified() {
if (root.exactMode) {
return isInteger();
} else {
@ -237,12 +115,12 @@ public class Number implements Function {
}
@Override
public List<Function> solveOneStep() throws Error {
final List<Function> result = new ArrayList<>();
public List<Function> simplify() throws Error {
final List<Function> result = new ObjectArrayList<>();
if (root.exactMode) {
Number divisor = new Number(root, BigInteger.TEN.pow(getNumberOfDecimalPlaces()));
Number numb = new Number(root, term.multiply(divisor.term));
Division div = new Division(root, numb, divisor);
final Number divisor = new Number(root, BigInteger.TEN.pow(getNumberOfDecimalPlaces()));
final Number numb = new Number(root, term.multiply(divisor.term));
final Division div = new Division(root, numb, divisor);
result.add(div);
} else {
result.add(this);
@ -284,7 +162,7 @@ public class Number implements Function {
}
@Override
public Calculator getRoot() {
public MathContext getMathContext() {
return root;
}
@ -340,4 +218,14 @@ public class Number implements Function {
return fs;
}
@Override
public Function setParameter(int index, Function var) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
@Override
public Function getParameter(int index) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
}

View File

@ -1,10 +1,11 @@
package org.warp.picalculator.math.functions;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.rules.ExponentRule1;
import org.warp.picalculator.math.rules.ExponentRule2;
import org.warp.picalculator.math.rules.ExponentRule3;
@ -14,25 +15,15 @@ import org.warp.picalculator.math.rules.FractionsRule4;
import org.warp.picalculator.math.rules.FractionsRule5;
import org.warp.picalculator.math.rules.UndefinedRule1;
public class Power extends FunctionTwoValues {
public class Power extends FunctionOperator {
public Power(Calculator root, Function value1, Function value2) {
public Power(MathContext root, Function value1, Function value2) {
super(root, value1, value2);
}
@Override
protected Function NewInstance(Calculator root, Function value1, Function value2) {
return new Power(root, value1, value2);
}
@Override
public String getSymbol() {
return MathematicalSymbols.POWER;
}
@Override
protected boolean isSolvable() {
if (variable1 instanceof Number & variable2 instanceof Number) {
if (parameter1 instanceof Number & parameter2 instanceof Number) {
return true;
}
if (UndefinedRule1.compare(this)) {
@ -63,21 +54,8 @@ public class Power extends FunctionTwoValues {
}
@Override
public void generateGraphics() {
variable1.setSmall(small);
variable1.generateGraphics();
variable2.setSmall(true);
variable2.generateGraphics();
height = variable1.getHeight() + variable2.getHeight() - 4;
line = variable2.getHeight() - 4 + variable1.getLine();
width = getVariable1().getWidth() + getVariable2().getWidth() + 1;
}
@Override
public ArrayList<Function> solve() throws Error {
final ArrayList<Function> result = new ArrayList<>();
public ObjectArrayList<Function> solve() throws Error {
final ObjectArrayList<Function> result = new ObjectArrayList<>();
if (UndefinedRule1.compare(this)) {
result.addAll(UndefinedRule1.execute(this));
} else if (ExponentRule1.compare(this)) {
@ -94,45 +72,23 @@ public class Power extends FunctionTwoValues {
result.addAll(FractionsRule4.execute(this));
} else if (FractionsRule5.compare(this)) {
result.addAll(FractionsRule5.execute(this));
} else if (variable1 instanceof Number & variable2 instanceof Number) {
result.add(((Number) variable1).pow((Number) variable2));
} else if (parameter1 instanceof Number & parameter2 instanceof Number) {
result.add(((Number) parameter1).pow((Number) parameter2));
}
return result;
}
@Override
public void draw(int x, int y) {
// glColor3f(0, 127-50+new Random().nextInt(50), 0);
// glFillRect(x,y,width,height);
// glColor3f(0, 0, 0);
int dx = 0;
variable1.draw(dx + x, getHeight() - variable1.getHeight() + y);
dx += variable1.getWidth();
variable2.draw(dx + x, y);
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
@Override
public int getWidth() {
return width;
}
@Override
public boolean equals(Object o) {
if (o instanceof Power) {
final FunctionTwoValues f = (FunctionTwoValues) o;
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
final FunctionOperator f = (FunctionOperator) o;
return parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2());
}
return false;
}
@Override
public Power clone() {
return new Power(mathContext, parameter1, parameter2);
}
}

View File

@ -2,131 +2,75 @@ package org.warp.picalculator.math.functions;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
public class Root extends FunctionTwoValues {
public class Root extends FunctionOperator {
public Root(Calculator root, Function value1, Function value2) {
public Root(MathContext root, Function value1, Function value2) {
super(root, value1, value2);
}
@Override
protected Function NewInstance(Calculator root, Function value1, Function value2) {
return new Root(root, value1, value2);
}
@Override
public String getSymbol() {
return MathematicalSymbols.NTH_ROOT;
}
@Override
public void generateGraphics() {
variable1.setSmall(true);
variable1.generateGraphics();
variable2.setSmall(small);
variable2.generateGraphics();
width = 1 + variable1.getWidth() + 2 + variable2.getWidth() + 2;
height = variable1.getHeight() + variable2.getHeight() - 2;
line = variable1.getHeight() + variable2.getLine() - 2;
}
@Override
protected boolean isSolvable() {
if (variable1 instanceof Number & variable2 instanceof Number) {
if (root.exactMode == false) {
if (parameter1 instanceof Number & parameter2 instanceof Number) {
if (mathContext.exactMode == false) {
return true;
}
try {
Number exponent = new Number(root, BigDecimal.ONE);
exponent = exponent.divide((Number) variable1);
final Number resultVal = ((Number) variable2).pow(exponent);
final Number originalVariable = resultVal.pow(new Number(root, 2));
if (originalVariable.equals(variable2)) {
Number exponent = new Number(mathContext, BigDecimal.ONE);
exponent = exponent.divide((Number) parameter1);
final Number resultVal = ((Number) parameter2).pow(exponent);
final Number originalVariable = resultVal.pow(new Number(mathContext, 2));
if (originalVariable.equals(parameter2)) {
return true;
}
} catch (Exception | Error ex) {
ex.printStackTrace();
}
}
if (variable1 instanceof Number && ((Number) variable1).equals(new Number(root, 2))) {
if (parameter1 instanceof Number && ((Number) parameter1).equals(new Number(mathContext, 2))) {
return true;
}
return false;
}
@Override
public ArrayList<Function> solve() throws Error {
final ArrayList<Function> result = new ArrayList<>();
if (root.exactMode) {
if (variable1 instanceof Number && ((Number) variable1).equals(new Number(root, 2))) {
result.add(new RootSquare(root, variable2));
public ObjectArrayList<Function> solve() throws Error {
final ObjectArrayList<Function> result = new ObjectArrayList<>();
if (mathContext.exactMode) {
if (parameter1 instanceof Number && ((Number) parameter1).equals(new Number(mathContext, 2))) {
result.add(new RootSquare(mathContext, parameter2));
} else {
Number exponent = new Number(root, BigInteger.ONE);
exponent = exponent.divide((Number) variable1);
result.add(((Number) variable2).pow(exponent));
Number exponent = new Number(mathContext, BigInteger.ONE);
exponent = exponent.divide((Number) parameter1);
result.add(((Number) parameter2).pow(exponent));
}
} else {
final Number exp = (Number) variable1;
final Number numb = (Number) variable2;
final Number exp = (Number) parameter1;
final Number numb = (Number) parameter2;
result.add(numb.pow(new Number(root, 1).divide(exp)));
result.add(numb.pow(new Number(mathContext, 1).divide(exp)));
}
return result;
}
@Override
public void draw(int x, int y) {
// glColor3f(0, 255, 0);
// glFillRect(x,y,width,height);
// glColor3f(0, 0, 0);
final int w1 = getVariable2().getWidth();
final int h1 = getVariable2().getHeight();
final int w2 = getVariable1().getWidth();
final int h2 = getVariable1().getHeight();
final int height = getHeight();
final int hh = (int) Math.ceil((double) h1 / 2);
getVariable1().draw(x + 1, y);
getVariable2().draw(x + 1 + w2 + 2, y + h2 - 2);
DisplayManager.renderer.glDrawLine(x + 1 + w2 - 2, y + height - 2, x + 1 + w2 - 2, y + height - 2);
DisplayManager.renderer.glDrawLine(x + 1 + w2 - 1, y + height - 1, x + 1 + w2 - 1, y + height - 1);
DisplayManager.renderer.glDrawLine(x + 1 + w2 - 0, y + height - 0, x + 1 + w2 - 0, y + height - 0);
DisplayManager.renderer.glDrawLine(x + 1 + w2, y + height - 1 - hh, x + 1 + w2, y + height - 1);
DisplayManager.renderer.glDrawLine(x + 1 + w2 + 1, y + height - 2 - h1, x + 1 + w2 + 1, y + height - 1 - hh - 1);
DisplayManager.renderer.glDrawLine(x + 1 + w2 + 1, y + height - h1 - 2, x + 1 + w2 + 2 + w1 + 1, y + height - h1 - 2);
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
@Override
public boolean equals(Object o) {
if (o instanceof Root) {
final FunctionTwoValues f = (FunctionTwoValues) o;
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
final FunctionOperator f = (FunctionOperator) o;
return parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2());
}
return false;
}
@Override
public Root clone() {
return new Root(mathContext, parameter1, parameter2);
}
}

View File

@ -1,51 +1,31 @@
package org.warp.picalculator.math.functions;
import java.math.BigInteger;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
public class RootSquare extends AnteriorFunction {
public class RootSquare extends FunctionSingle {
public RootSquare(Calculator root, Function value) {
public RootSquare(MathContext root, Function value) {
super(root, value);
}
@Override
public Function NewInstance(Calculator root, Function value) {
return new RootSquare(root, value);
}
@Override
public String getSymbol() {
return MathematicalSymbols.SQUARE_ROOT;
}
@Override
public void generateGraphics() {
variable.setSmall(small);
variable.generateGraphics();
height = getVariable().getHeight() + 2;
width = 1 + 4 + getVariable().getWidth() + 1;
line = getVariable().getLine() + 2;
}
@Override
protected boolean isSolvable() {
if (variable instanceof Number) {
if (root.exactMode == false) {
if (parameter instanceof Number) {
if (mathContext.exactMode == false) {
return true;
}
try {
Number exponent = new Number(root, BigInteger.ONE);
exponent = exponent.divide(new Number(root, 2));
final Number resultVal = ((Number) variable).pow(exponent);
final Number originalVariable = resultVal.pow(new Number(root, 2));
if (originalVariable.equals(variable)) {
Number exponent = new Number(mathContext, BigInteger.ONE);
exponent = exponent.divide(new Number(mathContext, 2));
final Number resultVal = ((Number) parameter).pow(exponent);
final Number originalVariable = resultVal.pow(new Number(mathContext, 2));
if (originalVariable.equals(parameter)) {
return true;
}
} catch (Exception | Error ex) {
@ -56,50 +36,31 @@ public class RootSquare extends AnteriorFunction {
}
@Override
public ArrayList<Function> solve() throws Error {
final ArrayList<Function> result = new ArrayList<>();
if (root.exactMode) {
Number exponent = new Number(root, BigInteger.ONE);
exponent = exponent.divide(new Number(root, 2));
result.add(((Number) variable).pow(exponent));
public ObjectArrayList<Function> solve() throws Error {
final ObjectArrayList<Function> result = new ObjectArrayList<>();
if (mathContext.exactMode) {
Number exponent = new Number(mathContext, BigInteger.ONE);
exponent = exponent.divide(new Number(mathContext, 2));
result.add(((Number) parameter).pow(exponent));
} else {
final Number exp = new Number(root, 2);
final Number numb = (Number) variable;
final Number exp = new Number(mathContext, 2);
final Number numb = (Number) parameter;
result.add(numb.pow(new Number(root, 1).divide(exp)));
result.add(numb.pow(new Number(mathContext, 1).divide(exp)));
}
return result;
}
@Override
public void draw(int x, int y) {
// glColor3f(0, 255, 0);
// glFillRect(x,y,width,height);
// glColor3f(0, 0, 0);
Utils.writeSquareRoot(getVariable(), x, y, small);
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
@Override
public boolean equals(Object o) {
if (o instanceof RootSquare) {
return ((RootSquare) o).variable.equals(variable);
return ((RootSquare) o).getParameter().equals(parameter);
}
return false;
}
@Override
public RootSquare clone() {
return new RootSquare(mathContext, parameter);
}
}

View File

@ -1,10 +1,11 @@
package org.warp.picalculator.math.functions;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.rules.ExpandRule1;
import org.warp.picalculator.math.rules.ExpandRule5;
import org.warp.picalculator.math.rules.NumberRule3;
@ -14,25 +15,15 @@ import org.warp.picalculator.math.rules.VariableRule2;
import org.warp.picalculator.math.rules.VariableRule3;
import org.warp.picalculator.math.rules.methods.SumMethod1;
public class Subtraction extends FunctionTwoValues {
public class Subtraction extends FunctionOperator {
public Subtraction(Calculator root, Function value1, Function value2) {
public Subtraction(MathContext root, Function value1, Function value2) {
super(root, value1, value2);
}
@Override
protected Function NewInstance(Calculator root, Function value1, Function value2) {
return new Subtraction(root, value1, value2);
}
@Override
public String getSymbol() {
return MathematicalSymbols.SUBTRACTION;
}
@Override
protected boolean isSolvable() {
if (variable1 instanceof Number & variable2 instanceof Number) {
if (parameter1 instanceof Number & parameter2 instanceof Number) {
return true;
}
if (VariableRule1.compare(this)) {
@ -63,8 +54,8 @@ public class Subtraction extends FunctionTwoValues {
}
@Override
public ArrayList<Function> solve() throws Error {
ArrayList<Function> result = new ArrayList<>();
public ObjectArrayList<Function> solve() throws Error {
ObjectArrayList<Function> result = new ObjectArrayList<>();
if (VariableRule1.compare(this)) {
result = VariableRule1.execute(this);
} else if (VariableRule2.compare(this)) {
@ -81,8 +72,8 @@ public class Subtraction extends FunctionTwoValues {
result = NumberRule5.execute(this);
} else if (SumMethod1.compare(this)) {
result = SumMethod1.execute(this);
} else if (variable1.isSolved() & variable2.isSolved()) {
result.add(((Number) variable1).add(((Number) variable2).multiply(new Number(root, "-1"))));
} else if (parameter1.isSimplified() & parameter2.isSimplified()) {
result.add(((Number) parameter1).add(((Number) parameter2).multiply(new Number(mathContext, "-1"))));
}
return result;
}
@ -90,9 +81,15 @@ public class Subtraction extends FunctionTwoValues {
@Override
public boolean equals(Object o) {
if (o instanceof Subtraction) {
final FunctionTwoValues f = (FunctionTwoValues) o;
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
final FunctionOperator f = (FunctionOperator) o;
return parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2());
}
return false;
}
@Override
public Subtraction clone() {
return new Subtraction(mathContext, parameter1, parameter2);
}
}

View File

@ -1,14 +1,13 @@
package org.warp.picalculator.math.functions;
import java.math.BigDecimal;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.rules.NumberRule3;
import org.warp.picalculator.math.rules.NumberRule5;
import org.warp.picalculator.math.rules.NumberRule7;
@ -18,25 +17,15 @@ import org.warp.picalculator.math.rules.VariableRule2;
import org.warp.picalculator.math.rules.VariableRule3;
import org.warp.picalculator.math.rules.methods.SumMethod1;
public class Sum extends FunctionTwoValues {
public class Sum extends FunctionOperator {
public Sum(Calculator root, Function value1, Function value2) {
public Sum(MathContext root, Function value1, Function value2) {
super(root, value1, value2);
}
@Override
protected Function NewInstance(Calculator root, Function value1, Function value2) {
return new Sum(root, value1, value2);
}
@Override
public String getSymbol() {
return MathematicalSymbols.SUM;
}
@Override
protected boolean isSolvable() {
if (variable1 instanceof Number & variable2 instanceof Number) {
if (parameter1 instanceof Number & parameter2 instanceof Number) {
return true;
}
if (SyntaxRule2.compare(this)) {
@ -67,11 +56,11 @@ public class Sum extends FunctionTwoValues {
}
@Override
public ArrayList<Function> solve() throws Error {
if (variable1 == null || variable2 == null) {
public ObjectArrayList<Function> solve() throws Error {
if (parameter1 == null || parameter2 == null) {
throw new Error(Errors.SYNTAX_ERROR);
}
ArrayList<Function> result = new ArrayList<>();
ObjectArrayList<Function> result = new ObjectArrayList<>();
if (SyntaxRule2.compare(this)) {
result = SyntaxRule2.execute(this);
} else if (VariableRule1.compare(this)) {
@ -88,61 +77,40 @@ public class Sum extends FunctionTwoValues {
result = NumberRule7.execute(this);
} else if (SumMethod1.compare(this)) {
result = SumMethod1.execute(this);
} else if (variable1.isSolved() & variable2.isSolved()) {
if ((root.getChild().equals(this))) {
if (((Number) variable1).term.compareTo(new BigDecimal(2)) == 0 && ((Number) variable2).term.compareTo(new BigDecimal(2)) == 0) {
result.add(new Joke(root, Joke.FISH));
} else if (parameter1.isSimplified() & parameter2.isSimplified()) {
if ((mathContext.getChild().equals(this))) {
if (((Number) parameter1).term.compareTo(new BigDecimal(2)) == 0 && ((Number) parameter2).term.compareTo(new BigDecimal(2)) == 0) {
result.add(new Joke(mathContext, Joke.FISH));
return result;
} else if (((Number) variable1).term.compareTo(new BigDecimal(20)) == 0 && ((Number) variable2).term.compareTo(new BigDecimal(20)) == 0) {
result.add(new Joke(root, Joke.TORNADO));
} else if (((Number) parameter1).term.compareTo(new BigDecimal(20)) == 0 && ((Number) parameter2).term.compareTo(new BigDecimal(20)) == 0) {
result.add(new Joke(mathContext, Joke.TORNADO));
return result;
} else if (((Number) variable1).term.compareTo(new BigDecimal(29)) == 0 && ((Number) variable2).term.compareTo(new BigDecimal(29)) == 0) {
result.add(new Joke(root, Joke.SHARKNADO));
} else if (((Number) parameter1).term.compareTo(new BigDecimal(29)) == 0 && ((Number) parameter2).term.compareTo(new BigDecimal(29)) == 0) {
result.add(new Joke(mathContext, Joke.SHARKNADO));
return result;
}
}
result.add(((Number) variable1).add((Number) variable2));
result.add(((Number) parameter1).add((Number) parameter2));
}
return result;
}
@Override
public void generateGraphics() {
variable1.setSmall(small);
variable1.generateGraphics();
variable2.setSmall(small);
variable2.generateGraphics();
width = calcWidth();
height = calcHeight();
line = calcLine();
}
@Override
public int getWidth() {
return width;
}
@Override
protected int calcWidth() {
int dx = 0;
dx += variable1.getWidth();
dx += 1;
dx += Utils.getFont(small).getStringWidth(getSymbol());
return dx += variable2.getWidth();
}
@Override
public boolean equals(Object o) {
if (o instanceof Sum) {
final FunctionTwoValues f = (FunctionTwoValues) o;
if (variable1.equals(f.variable1) && variable2.equals(f.variable2)) {
final FunctionOperator f = (FunctionOperator) o;
if (parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2())) {
return true;
} else if (variable1.equals(f.variable2) && variable2.equals(f.variable1)) {
} else if (parameter1.equals(f.getParameter2()) && parameter2.equals(f.getParameter1())) {
return true;
}
}
return false;
}
@Override
public Sum clone() {
return new Sum(mathContext, parameter1, parameter2);
}
}

View File

@ -1,38 +1,26 @@
package org.warp.picalculator.math.functions;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.rules.ExpandRule1;
import org.warp.picalculator.math.rules.NumberRule3;
import org.warp.picalculator.math.rules.NumberRule4;
import org.warp.picalculator.math.rules.NumberRule5;
public class SumSubtraction extends FunctionTwoValues {
public class SumSubtraction extends FunctionOperator {
public SumSubtraction(Calculator root, Function value1, Function value2) {
public SumSubtraction(MathContext root, Function value1, Function value2) {
super(root, value1, value2);
}
@Override
protected Function NewInstance(Calculator root, Function value1, Function value2) {
return new SumSubtraction(root, value1, value2);
}
@Override
public String getSymbol() {
return MathematicalSymbols.SUM_SUBTRACTION;
}
@Override
protected boolean isSolvable() {
if (variable1 instanceof Number & variable2 instanceof Number) {
if (parameter1 instanceof Number & parameter2 instanceof Number) {
return true;
}
if (NumberRule3.compare(this)) {
@ -51,11 +39,11 @@ public class SumSubtraction extends FunctionTwoValues {
}
@Override
public ArrayList<Function> solve() throws Error {
if (variable1 == null || variable2 == null) {
public ObjectArrayList<Function> solve() throws Error {
if (parameter1 == null || parameter2 == null) {
throw new Error(Errors.SYNTAX_ERROR);
}
ArrayList<Function> result = new ArrayList<>();
ObjectArrayList<Function> result = new ObjectArrayList<>();
if (NumberRule3.compare(this)) {
result = NumberRule3.execute(this);
} else if (ExpandRule1.compare(this)) {
@ -64,63 +52,25 @@ public class SumSubtraction extends FunctionTwoValues {
result = NumberRule4.execute(this);
} else if (NumberRule5.compare(this)) {
result = NumberRule5.execute(this);
} else if (variable1.isSolved() & variable2.isSolved()) {
result.add(((Number) variable1).add((Number) variable2));
result.add(((Number) variable1).add(((Number) variable2).multiply(new Number(root, "-1"))));
} else if (parameter1.isSimplified() & parameter2.isSimplified()) {
result.add(((Number) parameter1).add((Number) parameter2));
result.add(((Number) parameter1).add(((Number) parameter2).multiply(new Number(mathContext, "-1"))));
}
return result;
}
@Override
public void generateGraphics() {
variable1.setSmall(small);
variable1.generateGraphics();
variable2.setSmall(small);
variable2.generateGraphics();
width = calcWidth();
height = calcHeight();
line = calcLine();
}
@Override
public void draw(int x, int y) {
// glColor3f(127, 127-50+new Random().nextInt(50), 255);
// glFillRect(x,y,width,height);
// glColor3f(0, 0, 0);
final int ln = getLine();
int dx = 0;
variable1.draw(dx + x, ln - variable1.getLine() + y);
dx += variable1.getWidth();
Utils.getFont(small).use(DisplayManager.engine);
dx += 1;
DisplayManager.renderer.glDrawStringLeft(dx + x, ln - Utils.getFontHeight(small) / 2 + y, getSymbol());
dx += Utils.getFont(small).getStringWidth(getSymbol());
variable2.draw(dx + x, ln - variable2.getLine() + y);
}
@Override
public int getWidth() {
return width;
}
@Override
protected int calcWidth() {
int dx = 0;
dx += variable1.getWidth();
dx += 1;
dx += Utils.getFont(small).getStringWidth(getSymbol());
return dx += variable2.getWidth();
}
@Override
public boolean equals(Object o) {
if (o instanceof SumSubtraction) {
final FunctionTwoValues f = (FunctionTwoValues) o;
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
final FunctionOperator f = (FunctionOperator) o;
return parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2());
}
return false;
}
@Override
public SumSubtraction clone() {
return new SumSubtraction(mathContext, parameter1, parameter2);
}
}

View File

@ -3,75 +3,32 @@ package org.warp.picalculator.math.functions;
import java.util.List;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
public class Undefined implements Function {
protected final Calculator root;
protected final MathContext root;
public Undefined(Calculator root) {
public Undefined(MathContext root) {
this.root = root;
}
@Override
public String getSymbol() {
return "undefined";
}
@Override
public List<Function> solveOneStep() throws Error {
public List<Function> simplify() throws Error {
return null;
}
@Override
public boolean isSolved() {
public boolean isSimplified() {
return true;
}
private int width, height, line;
private boolean small;
@Override
public void generateGraphics() {
width = Utils.getFont(small).getStringWidth("UNDEFINED");
height = Utils.getFontHeight(small);
line = height / 2;
}
@Override
public void draw(int x, int y) {
Utils.getFont(small).use(DisplayManager.engine);
DisplayManager.renderer.glDrawStringLeft(x, y, "UNDEFINED");
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
@Override
public Calculator getRoot() {
public MathContext getMathContext() {
return root;
}
@Override
public void setSmall(boolean small) {
this.small = small;
}
@Override
public boolean equals(Object o) {
if (o instanceof Undefined) {
@ -80,4 +37,19 @@ public class Undefined implements Function {
return false;
}
@Override
public Undefined clone() {
return new Undefined(root);
}
@Override
public Function setParameter(int index, Function var) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
@Override
public Function getParameter(int index) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
}

View File

@ -1,33 +1,25 @@
package org.warp.picalculator.math.functions;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import org.warp.picalculator.Error;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.math.Calculator;
import com.rits.cloning.Cloner;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
public class Variable implements Function {
protected char var;
protected int width;
protected int height;
protected int line;
protected int[] varColor;
protected boolean small;
protected final Calculator root;
protected final MathContext root;
protected V_TYPE type = V_TYPE.KNOWN;
public Variable(Calculator root, char val, V_TYPE type) {
public Variable(MathContext root, char val, V_TYPE type) {
this.root = root;
var = val;
this.type = type;
}
public Variable(Calculator root, String s, V_TYPE type) throws Error {
public Variable(MathContext root, String s, V_TYPE type) throws Error {
this(root, s.charAt(0), type);
}
@ -47,84 +39,11 @@ public class Variable implements Function {
return new Variable(root, var, typ);
}
@Override
public void generateGraphics() {
line = calcLine();
height = calcHeight();
width = calcWidth();
varColor = new int[3];
switch (type) {
case KNOWN:
varColor[0] = 0;
varColor[1] = 200;
varColor[2] = 0;
break;
case UNKNOWN:
varColor[0] = 200;
varColor[1] = 0;
varColor[2] = 0;
break;
case SOLUTION:
varColor[0] = 0;
varColor[1] = 0;
varColor[2] = 200;
break;
}
}
@Override
public String getSymbol() {
return toString();
}
@Override
public String toString() {
return "" + getChar();
}
// public void draw(int x, int y, PIDisplay g, boolean small, boolean drawMinus) {
// boolean beforedrawminus = this.drawMinus;
// this.drawMinus = drawMinus;
// draw(x, y, small);
// this.drawMinus = beforedrawminus;
// }
@Override
public void draw(int x, int y) {
Utils.getFont(small).use(DisplayManager.engine);
DisplayManager.renderer.glColor3i(varColor[0], varColor[1], varColor[2]);
DisplayManager.renderer.glDrawStringLeft(x + 1, y, toString());
DisplayManager.renderer.glColor3i(0, 0, 0);
}
@Override
public int getHeight() {
return height;
}
private int calcHeight() {
final int h1 = Utils.getFontHeight(small);
return h1;
}
@Override
public int getWidth() {
return width;
}
public int calcWidth() {
return Utils.getFont(small).getStringWidth(toString()) + 1;
}
@Override
public int getLine() {
return line;
}
private int calcLine() {
return Utils.getFontHeight(small) / 2;
}
public static class VariableValue {
public final Variable v;
public final Number n;
@ -136,24 +55,13 @@ public class Variable implements Function {
}
@Override
public Variable clone() {
final Cloner cloner = new Cloner();
return cloner.deepClone(this);
}
@Override
public void setSmall(boolean small) {
this.small = small;
}
@Override
public boolean isSolved() {
public boolean isSimplified() {
return true;
}
@Override
public List<Function> solveOneStep() throws Error {
final List<Function> result = new ArrayList<>();
public List<Function> simplify() throws Error {
final List<Function> result = new ObjectArrayList<>();
result.add(this);
return result;
}
@ -172,13 +80,26 @@ public class Variable implements Function {
}
@Override
public Calculator getRoot() {
public MathContext getMathContext() {
return root;
}
@Override
public Variable clone() {
return new Variable(root, var, type);
}
public static enum V_TYPE {
KNOWN,
UNKNOWN,
SOLUTION
KNOWN, UNKNOWN, SOLUTION
}
@Override
public Function setParameter(int index, Function var) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
@Override
public Function getParameter(int index) throws IndexOutOfBoundsException {
throw new IndexOutOfBoundsException();
}
}

View File

@ -1,60 +1,47 @@
package org.warp.picalculator.math.functions.equations;
import java.math.BigDecimal;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.SolveMethod;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.functions.FunctionTwoValues;
import org.warp.picalculator.math.functions.Number;
import org.warp.picalculator.math.functions.Subtraction;
import com.rits.cloning.Cloner;
public class Equation extends FunctionOperator {
public class Equation extends FunctionTwoValues {
public Equation(Calculator root, Function value1, Function value2) {
public Equation(MathContext root, Function value1, Function value2) {
super(root, value1, value2);
}
@Override
protected Function NewInstance(Calculator root, Function value1, Function value2) {
return new Equation(root, value1, value2);
}
@Override
public String getSymbol() {
return MathematicalSymbols.EQUATION;
}
@Override
protected boolean isSolvable() {
if (variable1 instanceof Number & variable2 instanceof Number) {
if (parameter1 instanceof Number & parameter2 instanceof Number) {
return true;
}
return false;
}
@Override
public ArrayList<Function> solve() throws Error {
if (variable1 == null || variable2 == null) {
public ObjectArrayList<Function> solve() throws Error {
if (parameter1 == null || parameter2 == null) {
throw new Error(Errors.SYNTAX_ERROR);
}
final ArrayList<Function> result = new ArrayList<>();
if (variable1.isSolved() & variable2.isSolved()) {
if (((Number) variable2).getTerm().compareTo(new BigDecimal(0)) == 0) {
final ObjectArrayList<Function> result = new ObjectArrayList<>();
if (parameter1.isSimplified() & parameter2.isSimplified()) {
if (((Number) parameter2).getTerm().compareTo(new BigDecimal(0)) == 0) {
result.add(this);
} else {
final Equation e = new Equation(root, null, null);
e.setVariable1(new Subtraction(root, variable1, variable2));
e.setVariable2(new Number(root, "0"));
final Equation e = new Equation(mathContext, null, null);
e.setParameter1(new Subtraction(mathContext, parameter1, parameter2));
e.setParameter2(new Number(mathContext, "0"));
result.add(e);
}
}
@ -63,18 +50,18 @@ public class Equation extends FunctionTwoValues {
public List<Function> solve(char variableCharacter) {
@SuppressWarnings("unused")
final ArrayList<Equation> e;
final ObjectArrayList<Equation> e;
//TODO: WORK IN PROGRESS.
//TODO: Finire. Fare in modo che risolva i passaggi fino a che non ce ne sono più
return null;
}
//WORK IN PROGRESS
public ArrayList<Equation> solveStep(char charIncognita) {
ArrayList<Equation> result = new ArrayList<>();
public ObjectArrayList<Equation> solveStep(char charIncognita) {
ObjectArrayList<Equation> result = new ObjectArrayList<>();
result.add(clone());
for (final SolveMethod t : SolveMethod.techniques) {
final ArrayList<Equation> newResults = new ArrayList<>();
final ObjectArrayList<Equation> newResults = new ObjectArrayList<>();
final int sz = result.size();
for (int n = 0; n < sz; n++) {
newResults.addAll(t.solve(result.get(n)));
@ -91,8 +78,7 @@ public class Equation extends FunctionTwoValues {
@Override
public Equation clone() {
final Cloner cloner = new Cloner();
return cloner.deepClone(this);
return new Equation(mathContext, parameter1, parameter2);
}
@Override

View File

@ -1,36 +1,30 @@
package org.warp.picalculator.math.functions.equations;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import org.warp.picalculator.Error;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionDynamic;
import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.functions.FunctionMultipleValues;
import org.warp.picalculator.math.functions.Number;
public class EquationsSystem extends FunctionMultipleValues {
public class EquationsSystem extends FunctionDynamic {
static final int spacing = 2;
public EquationsSystem(Calculator root) {
public EquationsSystem(MathContext root) {
super(root);
}
public EquationsSystem(Calculator root, Function value) {
public EquationsSystem(MathContext root, Function value) {
super(root, new Function[] { value });
}
public EquationsSystem(Calculator root, Function[] value) {
public EquationsSystem(MathContext root, Function[] value) {
super(root, value);
}
@Override
public String getSymbol() {
return null;
}
@Override
protected boolean isSolvable() {
if (functions.length >= 1) {
@ -40,14 +34,14 @@ public class EquationsSystem extends FunctionMultipleValues {
}
@Override
public List<Function> solveOneStep() throws Error {
final List<Function> ret = new ArrayList<>();
public ObjectArrayList<Function> solve() throws Error {
final ObjectArrayList<Function> ret = new ObjectArrayList<>();
if (functions.length == 1) {
if (functions[0].isSolved()) {
if (functions[0].isSimplified()) {
ret.add(functions[0]);
return ret;
} else {
final List<Function> l = functions[0].solveOneStep();
final List<Function> l = functions[0].simplify();
for (final Function f : l) {
if (f instanceof Number) {
ret.add(f);
@ -59,8 +53,8 @@ public class EquationsSystem extends FunctionMultipleValues {
}
} else {
for (final Function f : functions) {
if (f.isSolved() == false) {
final List<Function> partial = f.solveOneStep();
if (f.isSimplified() == false) {
final List<Function> partial = f.simplify();
for (final Function fnc : partial) {
ret.add(new Expression(root, new Function[] { fnc }));
}
@ -71,63 +65,8 @@ public class EquationsSystem extends FunctionMultipleValues {
}
@Override
public void generateGraphics() {
for (final Function f : functions) {
f.setSmall(false);
f.generateGraphics();
public EquationsSystem clone() {
return new EquationsSystem(root, functions);
}
width = 0;
for (final Function f : functions) {
if (f.getWidth() > width) {
width = f.getWidth();
}
}
width += 5;
height = 3;
for (final Function f : functions) {
height += f.getHeight() + spacing;
}
height = height - spacing + 2;
line = height / 2;
}
@Override
public void draw(int x, int y) {
final int h = getHeight() - 1;
final int marginTop = 3;
final int marginBottom = (h - 3 - 2) / 2 + marginTop;
final int spazioSopra = h - marginBottom;
int dy = marginTop;
for (final Function f : functions) {
f.draw(x + 5, y + dy);
dy += f.getHeight() + spacing;
}
DisplayManager.renderer.glDrawLine(x + 2, y + 0, x + 3, y + 0);
DisplayManager.renderer.glDrawLine(x + 1, y + 1, x + 1, y + marginBottom / 2);
DisplayManager.renderer.glDrawLine(x + 2, y + marginBottom / 2 + 1, x + 2, y + marginBottom - 1);
DisplayManager.renderer.glDrawLine(x + 0, y + marginBottom, x + 1, y + marginBottom);
DisplayManager.renderer.glDrawLine(x + 2, y + marginBottom + 1, x + 2, y + marginBottom + spazioSopra / 2 - 1);
DisplayManager.renderer.glDrawLine(x + 1, y + marginBottom + spazioSopra / 2, x + 1, y + h - 1);
DisplayManager.renderer.glDrawLine(x + 2, y + h, x + 3, y + h);
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
}

View File

@ -1,74 +1,19 @@
package org.warp.picalculator.math.functions.equations;
import java.util.ArrayList;
import java.util.List;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
public class EquationsSystemPart extends AnteriorFunction {
public class EquationsSystemPart extends FunctionSingle {
public EquationsSystemPart(Calculator root, Equation equazione) {
public EquationsSystemPart(MathContext root, Equation equazione) {
super(root, equazione);
}
@Override
protected Function NewInstance(Calculator root, Function value) {
return new EquationsSystemPart(root, (Equation) value);
}
@Override
public String getSymbol() {
return MathematicalSymbols.SYSTEM;
}
@Override
public void generateGraphics() {
variable.setSmall(false);
variable.generateGraphics();
width = 5 + getVariable().getWidth();
height = 3 + getVariable().getHeight() + 2;
line = 3 + getVariable().getLine();
}
@Override
public void draw(int x, int y) {
final int h = getHeight() - 1;
final int paddingTop = 3;
final int spazioSotto = (h - 3 - 2) / 2 + paddingTop;
final int spazioSopra = h - spazioSotto;
variable.draw(x + 5, y + paddingTop);
DisplayManager.renderer.glDrawLine(x + 2, y + 0, x + 3, y + 0);
DisplayManager.renderer.glDrawLine(x + 1, y + 1, x + 1, y + spazioSotto / 2);
DisplayManager.renderer.glDrawLine(x + 2, y + spazioSotto / 2 + 1, x + 2, y + spazioSotto - 1);
DisplayManager.renderer.glDrawLine(x + 0, y + spazioSotto, x + 1, y + spazioSotto);
DisplayManager.renderer.glDrawLine(x + 2, y + spazioSotto + 1, x + 2, y + spazioSotto + spazioSopra / 2 - 1);
DisplayManager.renderer.glDrawLine(x + 1, y + spazioSotto + spazioSopra / 2, x + 1, y + h - 1);
DisplayManager.renderer.glDrawLine(x + 2, y + h, x + 3, y + h);
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getLine() {
return line;
}
@Override
protected ArrayList<Function> solve() throws Error {
protected ObjectArrayList<Function> solve() throws Error {
// TODO Auto-generated method stub
return null;
}
@ -84,4 +29,10 @@ public class EquationsSystemPart extends AnteriorFunction {
// TODO Auto-generated method stub
return false;
}
@Override
public EquationsSystemPart clone() {
return new EquationsSystemPart(mathContext, (Equation) parameter);
}
}

View File

@ -1,31 +1,20 @@
package org.warp.picalculator.math.functions.trigonometry;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
public class ArcCosine extends AnteriorFunction {
public class ArcCosine extends FunctionSingle {
public ArcCosine(Calculator root, Function value) {
public ArcCosine(MathContext root, Function value) {
super(root, value);
}
@Override
public Function NewInstance(Calculator root, Function value) {
return new ArcCosine(root, value);
}
@Override
public String getSymbol() {
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.ARC_COSINE);
}
@Override
public ArrayList<Function> solve() throws Error {
public ObjectArrayList<Function> solve() throws Error {
// TODO Auto-generated method stub
return null;
}
@ -42,4 +31,10 @@ public class ArcCosine extends AnteriorFunction {
return false;
}
@Override
public FunctionSingle clone() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,31 +1,20 @@
package org.warp.picalculator.math.functions.trigonometry;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
public class ArcSine extends AnteriorFunction {
public class ArcSine extends FunctionSingle {
public ArcSine(Calculator root, Function value) {
public ArcSine(MathContext root, Function value) {
super(root, value);
}
@Override
public Function NewInstance(Calculator root, Function value) {
return new ArcSine(root, value);
}
@Override
public String getSymbol() {
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.ARC_SINE);
}
@Override
public ArrayList<Function> solve() throws Error {
public ObjectArrayList<Function> solve() throws Error {
// TODO Auto-generated method stub
return null;
}
@ -42,4 +31,10 @@ public class ArcSine extends AnteriorFunction {
return false;
}
@Override
public FunctionSingle clone() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,31 +1,20 @@
package org.warp.picalculator.math.functions.trigonometry;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
public class ArcTangent extends AnteriorFunction {
public class ArcTangent extends FunctionSingle {
public ArcTangent(Calculator root, Function value) {
public ArcTangent(MathContext root, Function value) {
super(root, value);
}
@Override
public Function NewInstance(Calculator root, Function value) {
return new ArcTangent(root, value);
}
@Override
public String getSymbol() {
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.ARC_TANGENT);
}
@Override
public ArrayList<Function> solve() throws Error {
public ObjectArrayList<Function> solve() throws Error {
// TODO Auto-generated method stub
return null;
}
@ -42,4 +31,10 @@ public class ArcTangent extends AnteriorFunction {
return false;
}
@Override
public FunctionSingle clone() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,31 +1,20 @@
package org.warp.picalculator.math.functions.trigonometry;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
public class Cosine extends AnteriorFunction {
public class Cosine extends FunctionSingle {
public Cosine(Calculator root, Function value) {
public Cosine(MathContext root, Function value) {
super(root, value);
}
@Override
public Function NewInstance(Calculator root, Function value) {
return new Cosine(root, value);
}
@Override
public String getSymbol() {
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.COSINE);
}
@Override
public ArrayList<Function> solve() throws Error {
public ObjectArrayList<Function> solve() throws Error {
// TODO Auto-generated method stub
return null;
}
@ -42,4 +31,10 @@ public class Cosine extends AnteriorFunction {
return false;
}
@Override
public FunctionSingle clone() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,51 +1,40 @@
package org.warp.picalculator.math.functions.trigonometry;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.nevec.rjm.BigDecimalMath;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.AngleMode;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
import org.warp.picalculator.math.functions.Number;
public class Sine extends AnteriorFunction {
public class Sine extends FunctionSingle {
public Sine(Calculator root, Function value) {
public Sine(MathContext root, Function value) {
super(root, value);
}
@Override
public Function NewInstance(Calculator root, Function value) {
return new Sine(root, value);
}
@Override
public String getSymbol() {
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.SINE);
}
@Override
protected boolean isSolvable() {
if (variable instanceof Number) {
if (root.exactMode == false) {
if (parameter instanceof Number) {
if (mathContext.exactMode == false) {
return true;
}
}
if (root.angleMode == AngleMode.DEG) {
final Function[] solvableValues = new Function[] { new Number(root, 0), new Number(root, 30), new Number(root, 90), };
if (mathContext.angleMode == AngleMode.DEG) {
final Function[] solvableValues = new Function[] { new Number(mathContext, 0), new Number(mathContext, 30), new Number(mathContext, 90), };
}
return false;
}
@Override
public ArrayList<Function> solve() throws Error {
final ArrayList<Function> results = new ArrayList<>();
if (variable instanceof Number) {
if (root.exactMode == false) {
results.add(new Number(root, BigDecimalMath.sin(((Number) variable).getTerm())));
public ObjectArrayList<Function> solve() throws Error {
final ObjectArrayList<Function> results = new ObjectArrayList<>();
if (parameter instanceof Number) {
if (mathContext.exactMode == false) {
results.add(new Number(mathContext, BigDecimalMath.sin(((Number) parameter).getTerm())));
}
}
return results;
@ -54,12 +43,17 @@ public class Sine extends AnteriorFunction {
@Override
public boolean equals(Object o) {
if (o instanceof Sine) {
final AnteriorFunction f = (AnteriorFunction) o;
if (variable.equals(f.getVariable())) {
final FunctionSingle f = (FunctionSingle) o;
if (parameter.equals(f.getParameter())) {
return true;
}
}
return false;
}
@Override
public Sine clone() {
return new Sine(mathContext, parameter);
}
}

View File

@ -1,31 +1,20 @@
package org.warp.picalculator.math.functions.trigonometry;
import java.util.ArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.functions.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionSingle;
public class Tangent extends AnteriorFunction {
public class Tangent extends FunctionSingle {
public Tangent(Calculator root, Function value) {
public Tangent(MathContext root, Function value) {
super(root, value);
}
@Override
public Function NewInstance(Calculator root, Function value) {
return new Tangent(root, value);
}
@Override
public String getSymbol() {
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.TANGENT);
}
@Override
public ArrayList<Function> solve() throws Error {
public ObjectArrayList<Function> solve() throws Error {
// TODO Auto-generated method stub
return null;
}
@ -42,4 +31,10 @@ public class Tangent extends AnteriorFunction {
return false;
}
@Override
public FunctionSingle clone() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,559 @@
package org.warp.picalculator.math.parser;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.gui.expression.blocks.Block;
import org.warp.picalculator.gui.expression.blocks.BlockChar;
import org.warp.picalculator.gui.expression.blocks.BlockContainer;
import org.warp.picalculator.gui.expression.blocks.BlockDivision;
import org.warp.picalculator.gui.expression.blocks.BlockExponentialNotation;
import org.warp.picalculator.gui.expression.blocks.BlockParenthesis;
import org.warp.picalculator.gui.expression.blocks.BlockPower;
import org.warp.picalculator.gui.expression.blocks.BlockSquareRoot;
import org.warp.picalculator.gui.expression.containers.InputContainer;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.FunctionSingle;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.Number;
import org.warp.picalculator.math.functions.Power;
import org.warp.picalculator.math.functions.RootSquare;
import org.warp.picalculator.math.functions.Subtraction;
import org.warp.picalculator.math.functions.Sum;
import org.warp.picalculator.math.functions.SumSubtraction;
import org.warp.picalculator.math.functions.Variable;
import org.warp.picalculator.math.functions.Variable.V_TYPE;
import org.warp.picalculator.math.functions.Division;
import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.functions.Multiplication;
import org.warp.picalculator.math.parser.features.FeatureChar;
import org.warp.picalculator.math.parser.features.FeatureDivision;
import org.warp.picalculator.math.parser.features.FeatureMultiplication;
import org.warp.picalculator.math.parser.features.FeatureNumber;
import org.warp.picalculator.math.parser.features.FeatureParenthesis;
import org.warp.picalculator.math.parser.features.FeaturePower;
import org.warp.picalculator.math.parser.features.FeatureSquareRoot;
import org.warp.picalculator.math.parser.features.FeatureSum;
import org.warp.picalculator.math.parser.features.FeatureVariable;
import org.warp.picalculator.math.parser.features.interfaces.Feature;
import org.warp.picalculator.math.parser.features.interfaces.FeatureDouble;
import org.warp.picalculator.math.parser.features.interfaces.FeatureSingle;
import com.sun.org.apache.xpath.internal.functions.Function2Args;
import com.sun.org.apache.xpath.internal.operations.Mult;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
public class MathParser {
public static Expression parseInput(MathContext context, InputContainer c) throws Error {
Expression result;
final Function resultFunction = parseContainer(context, c.getContent());
result = new Expression(context, resultFunction);
return result;
}
public static ObjectArrayList<Block> parseOutput(MathContext context, ObjectArrayList<Function> expr) throws Error {
final ObjectArrayList<Block> resultBlocks = new ObjectArrayList<>();
for (Function f : expr) {
resultBlocks.addAll(parseFunction(context, f));
}
return resultBlocks;
}
private static ObjectArrayList<Block> parseFunction(MathContext context, Function func) throws Error {
ObjectArrayList<Block> result = new ObjectArrayList<>();
if (func instanceof FunctionOperator) {
ObjectArrayList<Block> sub1 = parseFunction(context, func.getParameter(0));
ObjectArrayList<Block> sub2 = parseFunction(context, func.getParameter(1));
if (func instanceof Sum) {
result.addAll(sub1);
result.add(new BlockChar(MathematicalSymbols.SUM));
result.addAll(sub2);
return result;
}
if (func instanceof Subtraction) {
result.addAll(sub1);
result.add(new BlockChar(MathematicalSymbols.SUBTRACTION));
result.addAll(sub2);
return result;
}
if (func instanceof SumSubtraction) {
result.addAll(sub1);
result.add(new BlockChar(MathematicalSymbols.SUM_SUBTRACTION));
result.addAll(sub2);
return result;
}
if (func instanceof Multiplication) {
Block nearLeft = sub1.get(sub1.size()-1);
Block nearRight = sub2.get(0);
result.addAll(sub1);
if (nearLeft instanceof BlockChar && nearRight instanceof BlockChar) {
} else {
result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION));
}
result.addAll(sub2);
return result;
}
if (func instanceof Division) {
BlockDivision bd = new BlockDivision();
BlockContainer uc = bd.getUpperContainer();
BlockContainer lc = bd.getLowerContainer();
for (Block b : sub1) {
uc.appendBlockUnsafe(b);
}
for (Block b : sub2) {
lc.appendBlockUnsafe(b);
}
uc.recomputeDimensions();
lc.recomputeDimensions();
bd.recomputeDimensions();
result.add(bd);
return result;
}
if (func instanceof Power) {
BlockPower bp = new BlockPower();
BlockContainer ec = bp.getExponentContainer();
result.addAll(sub1);
for (Block b : sub2) {
ec.appendBlockUnsafe(b);
}
ec.recomputeDimensions();
bp.recomputeDimensions();
result.add(bp);
return result;
}
}
if (func instanceof FunctionSingle) {
ObjectArrayList<Block> sub = parseFunction(context, func.getParameter(0));
if (func instanceof RootSquare) {
BlockSquareRoot bsqr = new BlockSquareRoot();
BlockContainer bsqrc = bsqr.getNumberContainer();
for (Block b : sub) {
bsqrc.appendBlockUnsafe(b);
}
bsqrc.recomputeDimensions();
bsqr.recomputeDimensions();
result.add((bsqr));
return result;
}
}
if (func instanceof Expression) {
ObjectArrayList<Block> sub = parseFunction(context, ((Expression) func).getParameter(0));
BlockParenthesis bp = new BlockParenthesis();
BlockContainer bpc = bp.getNumberContainer();
for (Block b : sub) {
bpc.appendBlockUnsafe(b);
}
bpc.recomputeDimensions();
bp.recomputeDimensions();
result.add(bp);
return result;
}
if (func instanceof Number) {
Number numb = (Number) func;
String numberString = numb.toString();
if (numberString.contains("")) {
String[] numberParts = numberString.split("", 2);
BlockPower bp = new BlockExponentialNotation();
BlockContainer bpec = bp.getExponentContainer();
for (char c : numberParts[0].toCharArray()) {
result.add(new BlockChar(c));
}
for (char c : numberParts[1].toCharArray()) {
bpec.appendBlockUnsafe(new BlockChar(c));
};
bpec.recomputeDimensions();
bp.recomputeDimensions();
result.add(bp);
return result;
} else {
for (char c : numberString.toCharArray()) {
result.add(new BlockChar(c));
}
}
return result;
}
if (func instanceof Variable) {
//TODO: Temporary solution. In near future Variables will be distint objects and they will have a color. So they will be no longer a BlockChar/FeatureChar
result.add(new BlockChar(((Variable) func).getChar()));
return result;
}
throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + func.getClass().getSimpleName());
}
private static Function parseContainer(final MathContext context, final Iterable<Block> blocks) throws Error {
final ObjectArrayList<Feature> blockFeatures = new ObjectArrayList<>();
for (final Block block : blocks) {
final Feature blockFeature = parseBlock(context, block);
blockFeatures.add(blockFeature);
}
final Function result = joinFeatures(context, blockFeatures);
return result;
}
private static Feature parseBlock(final MathContext context, final Block block) throws Error {
Feature result;
final int blockType = block.getClassID();
switch (blockType) {
case BlockChar.CLASS_ID:
result = new FeatureChar(((BlockChar) block).getChar());
break;
case BlockDivision.CLASS_ID:
final BlockDivision bd = (BlockDivision) block;
final Function upper = parseContainer(context, bd.getUpperContainer().getContent());
final Function lower = parseContainer(context, bd.getLowerContainer().getContent());
result = new FeatureDivision(upper, lower);
break;
case BlockSquareRoot.CLASS_ID:
final BlockSquareRoot bsqr = (BlockSquareRoot) block;
final Function contnt = parseContainer(context, bsqr.getNumberContainer().getContent());
result = new FeatureSquareRoot(contnt);
break;
case BlockParenthesis.CLASS_ID:
final BlockParenthesis bp = (BlockParenthesis) block;
final Function cont = parseContainer(context, bp.getNumberContainer().getContent());
result = new FeatureParenthesis(cont);
break;
case BlockPower.CLASS_ID:
final BlockPower blp = (BlockPower) block;
final Function exp = parseContainer(context, blp.getExponentContainer().getContent());
result = new FeaturePower(exp);
break;
default:
throw new Error(Errors.NOT_IMPLEMENTED, "The block " + block.getClass().getSimpleName() + " isn't a known BLock");
}
return result;
}
private static Function joinFeatures(final MathContext context, ObjectArrayList<Feature> features) throws Error {
features = fixFeatures(context, features);
final ObjectArrayList<Function> process = makeFunctions(context, features);
fixStack(context, process);
if (process.size() > 1) {
throw new Error(Errors.UNBALANCED_STACK, "The stack is unbalanced. Not all the functions are nested correctly");
}
return process.get(0);
}
private static void fixStack(MathContext context, ObjectArrayList<Function> process) throws Error {
boolean lastLoopDidSomething;
ObjectListIterator<Function> stackIterator;
//Phase 0: join number and variables ([2][x] => [[2]*[x]])
do {
lastLoopDidSomething = false;
stackIterator = process.listIterator(process.size());
Function lastElement = null;
while (stackIterator.hasPrevious()) {
final Function f = stackIterator.previous();
final int curIndex = stackIterator.nextIndex();
if (f instanceof Number | f instanceof Variable) {
if (lastElement instanceof Variable) {
lastLoopDidSomething = true;
final Function var = process.get(curIndex + 1);
final Function numb = process.get(curIndex);
stackIterator.set(new Multiplication(context, numb, var));
process.remove(curIndex + 1);
}
}
lastElement = f;
}
} while (lastLoopDidSomething);
//Phase 1
do {
lastLoopDidSomething = false;
stackIterator = process.listIterator(process.size());
Function lastElement = null;
while (stackIterator.hasPrevious()) {
final Function f = stackIterator.previous();
if (f instanceof FunctionSingle) {
if (((FunctionSingle) f).getParameter() == null) {
lastLoopDidSomething = true;
if (lastElement == null) {
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
} else {
((FunctionSingle) f).setParameter(lastElement);
process.remove(stackIterator.nextIndex());
}
}
}
lastElement = f;
}
} while (lastLoopDidSomething);
//Phase 2
do {
lastLoopDidSomething = false;
stackIterator = process.listIterator();
while (stackIterator.hasNext()) {
final Function f = stackIterator.next();
final int curIndex = stackIterator.previousIndex();
if (f instanceof Multiplication || f instanceof Division) {
if (curIndex - 1 >= 0 && stackIterator.hasNext()) {
lastLoopDidSomething = true;
final Function next = process.get(curIndex + 1);
final Function prev = process.get(curIndex - 1);
stackIterator.set(f.setParameter(0, prev).setParameter(1, next));
process.remove(curIndex + 1);
process.remove(curIndex - 1);
} else {
if (f.getParameter(0) == null || f.getParameter(1) == null) {
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
}
}
}
}
} while (lastLoopDidSomething);
//Phase 3
do {
lastLoopDidSomething = false;
stackIterator = process.listIterator();
while (stackIterator.hasNext()) {
final Function f = stackIterator.next();
final int curIndex = stackIterator.previousIndex();
if (f instanceof Sum || f instanceof Subtraction || f instanceof SumSubtraction) {
if (curIndex - 1 >= 0 && stackIterator.hasNext()) {
lastLoopDidSomething = true;
final Function next = process.get(curIndex + 1);
final Function prev = process.get(curIndex - 1);
stackIterator.set(f.setParameter(0, prev).setParameter(1, next));
process.remove(curIndex + 1);
process.remove(curIndex - 1);
} else {
if (f.getParameter(0) == null || f.getParameter(1) == null) {
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
}
}
}
}
} while (lastLoopDidSomething);
//Phase 4
do {
lastLoopDidSomething = false;
stackIterator = process.iterator();
while (stackIterator.hasNext()) {
final Function f = stackIterator.next();
if (f instanceof Function2Args) {
}
}
} while (lastLoopDidSomething);
}
private static ObjectArrayList<Function> makeFunctions(MathContext context, ObjectArrayList<Feature> features)
throws Error {
final ObjectArrayList<Function> process = new ObjectArrayList<>();
for (final Feature f : features) {
if (f instanceof FeatureDivision) {
process.add(new Division(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2()));
} else if (f instanceof FeatureMultiplication) {
process.add(new Multiplication(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2()));
} else if (f instanceof FeatureVariable) {
process.add(new Variable(context, ((FeatureVariable) f).ch, ((FeatureVariable) f).varType));
} else if (f instanceof FeatureSum) {
process.add(new Sum(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2()));
} else if (f instanceof FeaturePower) {
if (process.isEmpty()) {
throw new Error(Errors.SYNTAX_ERROR, "There is a power at the beginning of the expression!");
} else {
Function prec = process.remove(process.size()-1);
process.add(new Power(context, prec, (Function) ((FeatureSingle) f).getChild()));
}
} else if (f instanceof FeatureSquareRoot) {
process.add(new RootSquare(context, (Function) ((FeatureSingle) f).getChild()));
} else if (f instanceof FeatureParenthesis) {
process.add(new Expression(context, (Function) ((FeatureSingle) f).getChild()));
// } else if (f instanceof FeatureSubtraction) {
// process.add(new Subtraction(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2()));
// } else if (f instanceof FeatureSumSubtraction) {
// process.add(new SumSubtraction(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2()));
} else if (f instanceof FeatureNumber) {
process.add(new Number(context, ((FeatureNumber) f).getNumberString()));
} else if (f instanceof FeatureChar) {
//All the char features must have been changed already before
throw new Error(Errors.SYNTAX_ERROR, "\"" + f.getClass().getSimpleName() + "\" can't be converted into a Function!");
} else {
throw new Error(Errors.SYNTAX_ERROR, "\"" + f.getClass().getSimpleName() + "\" can't be converted into a Function!");
}
}
return process;
}
private static ObjectArrayList<Feature> fixFeatures(final MathContext context, ObjectArrayList<Feature> features)
throws Error {
features = fixMinuses(context, features);
features = makeNumbers(context, features);
features = convertFunctionChars(context, features);
return features;
}
/**
* Create function features from char features
*
* @param context
* @param features
* @return
*/
private static ObjectArrayList<Feature> convertFunctionChars(MathContext context, ObjectArrayList<Feature> features)
throws Error {
final ObjectArrayList<Feature> process = new ObjectArrayList<>();
for (final Feature f : features) {
if (f instanceof FeatureChar) {
final char featureChar = ((FeatureChar) f).ch;
Feature result = null;
switch (featureChar) {
case MathematicalSymbols.SUM:
result = new FeatureSum(null, null);
break;
case MathematicalSymbols.MULTIPLICATION:
result = new FeatureMultiplication(null, null);
break;
}
//TODO: Temporary solution. In near future Variables will be distint objects and they will have a color. So they will be no longer a BlockChar/FeatureChar
for (char var : MathematicalSymbols.variables) {
if ( featureChar == var) {
result = new FeatureVariable(featureChar, V_TYPE.UNKNOWN);
break;
}
}
if (result == null) {
throw new Error(Errors.SYNTAX_ERROR, "Char " + featureChar + " isn't a known feature");
}
process.add(result);
} else {
process.add(f);
}
}
return process;
}
/**
* Make numbers [-][1][2][+][-][3] => [-12]
*
* @param context
* @param features
* @return
*/
private static ObjectArrayList<Feature> makeNumbers(MathContext context, ObjectArrayList<Feature> features) {
final ObjectArrayList<Feature> process = new ObjectArrayList<>();
FeatureNumber numberBuffer = null;
for (final Feature f : features) {
if (f instanceof FeatureChar) {
final FeatureChar bcf = (FeatureChar) f;
final char[] numbers = MathematicalSymbols.numbers;
boolean isNumber = false;
for (final char n : numbers) {
if (bcf.ch == n) {
isNumber = true;
break;
}
}
if (bcf.ch == '-' || bcf.ch == '.') {
isNumber = true;
}
if (isNumber) {
if (numberBuffer == null) {
numberBuffer = new FeatureNumber(bcf.ch);
process.add(numberBuffer);
} else {
numberBuffer.append(bcf.ch);
}
} else {
if (numberBuffer != null) {
numberBuffer = null;
}
process.add(f);
}
} else {
process.add(f);
}
}
return process;
}
/**
* Fix minuses [-][1][2][+][-][3][-][2] => [-][12][+][-][3][][2]
*
* @param context
* @param features
* @return
* @throws Error
*/
private static ObjectArrayList<Feature> fixMinuses(final MathContext context, ObjectArrayList<Feature> features)
throws Error {
final ObjectArrayList<Feature> process = new ObjectArrayList<>();
Feature lastFeature = null;
for (final Feature f : features) {
if (f instanceof FeatureChar && ((FeatureChar) f).ch == MathematicalSymbols.SUBTRACTION) {
boolean isNegativeOfNumber = false;
if (lastFeature == null) {
isNegativeOfNumber = true;
} else if (lastFeature instanceof FeatureChar) {
final FeatureChar lcf = (FeatureChar) lastFeature;
final char[] operators = MathematicalSymbols.functionsNSN;
for (final char operator : operators) {
if (lcf.ch == operator) {
isNegativeOfNumber = true;
break;
}
}
}
if (isNegativeOfNumber) {
process.add(new FeatureChar(MathematicalSymbols.MINUS));
} else {
process.add(new FeatureChar(MathematicalSymbols.SUBTRACTION));
}
} else {
process.add(f);
}
lastFeature = f;
}
return process;
}
}

View File

@ -0,0 +1,13 @@
package org.warp.picalculator.math.parser.features;
import org.warp.picalculator.math.parser.features.interfaces.Feature;
public class FeatureChar implements Feature {
public final char ch;
public FeatureChar(char ch) {
this.ch = ch;
}
}

View File

@ -0,0 +1,9 @@
package org.warp.picalculator.math.parser.features;
public class FeatureDivision extends FeatureDoubleImpl {
public FeatureDivision(Object child1, Object child2) {
super(child1, child2);
}
}

View File

@ -0,0 +1,33 @@
package org.warp.picalculator.math.parser.features;
import org.warp.picalculator.math.parser.features.interfaces.FeatureDouble;
public abstract class FeatureDoubleImpl implements FeatureDouble {
private Object child_1;
private Object child_2;
public FeatureDoubleImpl(Object child1, Object child2) {
child_1 = child1;
child_2 = child2;
}
@Override
public Object getChild1() {
return child_1;
}
@Override
public void setChild1(Object obj) {
child_1 = obj;
}
@Override
public Object getChild2() {
return child_2;
}
@Override
public void setChild2(Object obj) {
child_2 = obj;
}
}

View File

@ -0,0 +1,9 @@
package org.warp.picalculator.math.parser.features;
public class FeatureMultiplication extends FeatureDoubleImpl {
public FeatureMultiplication(Object child1, Object child2) {
super(child1, child2);
}
}

View File

@ -0,0 +1,27 @@
package org.warp.picalculator.math.parser.features;
import org.warp.picalculator.math.parser.features.interfaces.FeatureBasic;
public class FeatureNumber implements FeatureBasic {
private String numberString;
public FeatureNumber(char c) {
numberString = c + "";
}
public FeatureNumber(String s) {
numberString = s;
}
public FeatureNumber() {
numberString = "";
}
public String getNumberString() {
return numberString;
}
public void append(char ch) {
numberString += ch;
}
}

View File

@ -0,0 +1,9 @@
package org.warp.picalculator.math.parser.features;
public class FeatureParenthesis extends FeatureSingleImpl {
public FeatureParenthesis(Object child) {
super(child);
}
}

Some files were not shown because too many files have changed in this diff Show More