Merge remote-tracking branch 'origin/new-internal-structure'
This commit is contained in:
commit
0bf349ce9f
@ -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>
|
||||
|
BIN
res/algebra.png
BIN
res/algebra.png
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
BIN
res/algebra_input.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
BIN
res/draft unknown variable choice.png
Normal file
BIN
res/draft unknown variable choice.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
BIN
res/draft.png
Normal file
BIN
res/draft.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
res/draft2.png
Normal file
BIN
res/draft2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
BIN
res/font_ex.rft
BIN
res/font_ex.rft
Binary file not shown.
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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...");
|
||||
|
28
src/org/warp/picalculator/TestCalcBenchmark.java
Normal file
28
src/org/warp/picalculator/TestCalcBenchmark.java
Normal 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");
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ public class TestDrivers {
|
||||
try {
|
||||
Class.forName(className);
|
||||
return true;
|
||||
} catch( ClassNotFoundException e ) {
|
||||
} catch (final ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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")) {
|
||||
|
88
src/org/warp/picalculator/device/CacheFile.java
Normal file
88
src/org/warp/picalculator/device/CacheFile.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
13
src/org/warp/picalculator/device/KeyboardEventListener.java
Normal file
13
src/org/warp/picalculator/device/KeyboardEventListener.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
36
src/org/warp/picalculator/gui/GUIErrorMessage.java
Normal file
36
src/org/warp/picalculator/gui/GUIErrorMessage.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
30
src/org/warp/picalculator/gui/GraphicalElement.java
Normal file
30
src/org/warp/picalculator/gui/GraphicalElement.java
Normal 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();
|
||||
}
|
52
src/org/warp/picalculator/gui/expression/Caret.java
Normal file
52
src/org/warp/picalculator/gui/expression/Caret.java
Normal 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;
|
||||
}
|
||||
}
|
5
src/org/warp/picalculator/gui/expression/CaretState.java
Normal file
5
src/org/warp/picalculator/gui/expression/CaretState.java
Normal file
@ -0,0 +1,5 @@
|
||||
package org.warp.picalculator.gui.expression;
|
||||
|
||||
public enum CaretState {
|
||||
VISIBLE_ON, VISIBLE_OFF, HIDDEN
|
||||
}
|
58
src/org/warp/picalculator/gui/expression/blocks/Block.java
Normal file
58
src/org/warp/picalculator/gui/expression/blocks/Block.java
Normal 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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package org.warp.picalculator.gui.expression.containers;
|
||||
|
||||
public interface OutputLayout {
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() };
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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() + "-");
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
|
65
src/org/warp/picalculator/math/Function.java
Normal file
65
src/org/warp/picalculator/math/Function.java
Normal 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();
|
||||
}
|
170
src/org/warp/picalculator/math/FunctionDynamic.java
Normal file
170
src/org/warp/picalculator/math/FunctionDynamic.java
Normal 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;
|
||||
}
|
||||
}
|
180
src/org/warp/picalculator/math/FunctionOperator.java
Normal file
180
src/org/warp/picalculator/math/FunctionOperator.java
Normal 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);
|
||||
}
|
144
src/org/warp/picalculator/math/FunctionSingle.java
Normal file
144
src/org/warp/picalculator/math/FunctionSingle.java
Normal 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);
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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' };
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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() + ")";
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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() + ")";
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
559
src/org/warp/picalculator/math/parser/MathParser.java
Normal file
559
src/org/warp/picalculator/math/parser/MathParser.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user