Alpha version
This commit is contained in:
parent
20da14cfed
commit
f1b74b9842
26
.classpath
26
.classpath
@ -2,12 +2,30 @@
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="D:/Programmazione/Java/Progetti Eclipse/GatePack/libs/objenesis-2.4.jar"/>
|
||||
<classpathentry kind="src" path="res"/>
|
||||
<classpathentry kind="lib" path="D:/Users/Andrea/Downloads/PNGDecoder.jar"/>
|
||||
<classpathentry kind="lib" path="D:/Programmazione/Java/Progetti Eclipse/lwjgl-3.0.0b-raspberry/jar/lwjgl.jar">
|
||||
<classpathentry kind="lib" path="D:/Users/Andrea/Downloads/objenesis-2.4-bin/objenesis-2.4/objenesis-2.4.jar" sourcepath="D:/Users/Andrea/Downloads/objenesis-2.4-bin/objenesis-2.4/objenesis-2.4-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="D:/Programmazione/Java/Progetti Eclipse/lwjgl-3.0.0b-raspberry/native"/>
|
||||
<attribute name="javadoc_location" value="jar:file:/D:/Users/Andrea/Downloads/objenesis-2.4-bin/objenesis-2.4/objenesis-2.4-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-core.jar" sourcepath="G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-core-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-core-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-device.jar" sourcepath="G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-device-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-device-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-gpio-extension.jar" sourcepath="G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-gpio-extension-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-gpio-extension-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-service.jar" sourcepath="G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-service-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/G:/Users/Andrea/Downloads/pi4j-1.1/pi4j-1.1/lib/pi4j-service-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
|
@ -1,8 +1,12 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/org/nevec/rjm/BigSurd.java=UTF-8
|
||||
encoding//src/org/nevec/rjm/BigSurdVec.java=UTF-8
|
||||
encoding//src/org/warpgate/pi/calculator/Main.java=UTF-8
|
||||
encoding//src/org/warpgate/pi/calculator/Parentesi.java=UTF-8
|
||||
encoding//src/org/warpgate/pi/calculator/Radice.java=UTF-8
|
||||
encoding//src/org/warpgate/pi/calculator/RadiceQuadrata.java=UTF-8
|
||||
encoding//src/org/warpgate/pi/calculator/Simboli.java=UTF-8
|
||||
encoding//src/org/warp/engine=UTF-8
|
||||
encoding//src/org/warp/engine/Display.java=UTF-8
|
||||
encoding//src/org/warp/picalculator/Espressione.java=UTF-8
|
||||
encoding//src/org/warp/picalculator/Main.java=UTF-8
|
||||
encoding//src/org/warp/picalculator/Radice.java=UTF-8
|
||||
encoding//src/org/warp/picalculator/RadiceQuadrata.java=UTF-8
|
||||
encoding//src/org/warp/picalculator/Simboli.java=UTF-8
|
||||
encoding//src/org/warp/picalculator/screens/EquationScreen.java=UTF-8
|
||||
encoding/<project>=UTF-8
|
||||
|
BIN
res/font_big.rft
Normal file
BIN
res/font_big.rft
Normal file
Binary file not shown.
BIN
res/font_big.ttf
BIN
res/font_big.ttf
Binary file not shown.
BIN
res/font_small.rft
Normal file
BIN
res/font_small.rft
Normal file
Binary file not shown.
Binary file not shown.
BIN
res/marioskin.png
Normal file
BIN
res/marioskin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
res/marioskin.xcf
Normal file
BIN
res/marioskin.xcf
Normal file
Binary file not shown.
BIN
res/skin.png
BIN
res/skin.png
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
res/skin.xcf
BIN
res/skin.xcf
Binary file not shown.
@ -8,14 +8,26 @@ import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Cloner: deep clone objects.
|
||||
*
|
||||
* This class is thread safe. One instance can be used by multiple threads on the same time.
|
||||
* This class is thread safe. One instance can be used by multiple threads on
|
||||
* the same time.
|
||||
*
|
||||
* @author kostantinos.kougios
|
||||
* 18 Sep 2008
|
||||
@ -34,11 +46,13 @@ public class Cloner {
|
||||
}
|
||||
|
||||
/**
|
||||
* provide a cloned classes dumper (so i.e. they can be logged or stored in a file
|
||||
* provide a cloned classes dumper (so i.e. they can be logged or stored in
|
||||
* a file
|
||||
* instead of the default behaviour which is to println(cloned) )
|
||||
*
|
||||
* @param dumpCloned an implementation of the interface which can dump the
|
||||
* cloned classes.
|
||||
* @param dumpCloned
|
||||
* an implementation of the interface which can dump the
|
||||
* cloned classes.
|
||||
*/
|
||||
public void setDumpCloned(IDumpCloned dumpCloned) {
|
||||
this.dumpCloned = dumpCloned;
|
||||
@ -66,9 +80,11 @@ public class Cloner {
|
||||
/**
|
||||
* this makes the cloner to set a transient field to null upon cloning.
|
||||
*
|
||||
* NOTE: primitive types can't be nulled. Their value will be set to default, i.e. 0 for int
|
||||
* NOTE: primitive types can't be nulled. Their value will be set to
|
||||
* default, i.e. 0 for int
|
||||
*
|
||||
* @param nullTransient true for transient fields to be nulled
|
||||
* @param nullTransient
|
||||
* true for transient fields to be nulled
|
||||
*/
|
||||
public void setNullTransient(final boolean nullTransient) {
|
||||
this.nullTransient = nullTransient;
|
||||
@ -98,6 +114,7 @@ public class Cloner {
|
||||
}
|
||||
|
||||
private IDeepCloner deepCloner = new IDeepCloner() {
|
||||
@Override
|
||||
public <T> T deepClone(T o, Map<Object, Object> clones) {
|
||||
try {
|
||||
return cloneInternal(o, clones);
|
||||
@ -111,7 +128,8 @@ public class Cloner {
|
||||
protected Object fastClone(final Object o, final Map<Object, Object> clones) throws IllegalAccessException {
|
||||
final Class<? extends Object> c = o.getClass();
|
||||
final IFastCloner fastCloner = fastCloners.get(c);
|
||||
if (fastCloner != null) return fastCloner.clone(o, deepCloner, clones);
|
||||
if (fastCloner != null)
|
||||
return fastCloner.clone(o, deepCloner, clones);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -137,7 +155,8 @@ public class Cloner {
|
||||
}
|
||||
|
||||
/**
|
||||
* registers some known JDK immutable classes. Override this to register your
|
||||
* registers some known JDK immutable classes. Override this to register
|
||||
* your
|
||||
* own list of jdk's immutable classes
|
||||
*/
|
||||
protected void registerKnownJdkImmutableClasses() {
|
||||
@ -162,18 +181,21 @@ public class Cloner {
|
||||
}
|
||||
|
||||
protected void registerKnownConstants() {
|
||||
// registering known constants of the jdk.
|
||||
// registering known constants of the jdk.
|
||||
registerStaticFields(TreeSet.class, HashSet.class, HashMap.class, TreeMap.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* registers all static fields of these classes. Those static fields won't be cloned when an instance
|
||||
* registers all static fields of these classes. Those static fields won't
|
||||
* be cloned when an instance
|
||||
* of the class is cloned.
|
||||
*
|
||||
* This is useful i.e. when a static field object is added into maps or sets. At that point, there is no
|
||||
* This is useful i.e. when a static field object is added into maps or
|
||||
* sets. At that point, there is no
|
||||
* way for the cloner to know that it was static except if it is registered.
|
||||
*
|
||||
* @param classes array of classes
|
||||
* @param classes
|
||||
* array of classes
|
||||
*/
|
||||
public void registerStaticFields(final Class<?>... classes) {
|
||||
for (final Class<?> c : classes) {
|
||||
@ -190,18 +212,23 @@ public class Cloner {
|
||||
/**
|
||||
* spring framework friendly version of registerStaticFields
|
||||
*
|
||||
* @param set a set of classes which will be scanned for static fields
|
||||
* @param set
|
||||
* a set of classes which will be scanned for static fields
|
||||
*/
|
||||
public void setExtraStaticFields(final Set<Class<?>> set) {
|
||||
registerStaticFields((Class<?>[]) set.toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* instances of classes that shouldn't be cloned can be registered using this method.
|
||||
* instances of classes that shouldn't be cloned can be registered using
|
||||
* this method.
|
||||
*
|
||||
* @param c The class that shouldn't be cloned. That is, whenever a deep clone for
|
||||
* an object is created and c is encountered, the object instance of c will
|
||||
* be added to the clone.
|
||||
* @param c
|
||||
* The class that shouldn't be cloned. That is, whenever a deep
|
||||
* clone for
|
||||
* an object is created and c is encountered, the object instance
|
||||
* of c will
|
||||
* be added to the clone.
|
||||
*/
|
||||
public void dontClone(final Class<?>... c) {
|
||||
for (final Class<?> cl : c) {
|
||||
@ -222,7 +249,8 @@ public class Cloner {
|
||||
/**
|
||||
* instead of cloning these classes will set the field to null
|
||||
*
|
||||
* @param c the classes to nullify during cloning
|
||||
* @param c
|
||||
* the classes to nullify during cloning
|
||||
*/
|
||||
public void nullInsteadOfClone(final Class<?>... c) {
|
||||
for (final Class<?> cl : c) {
|
||||
@ -238,7 +266,8 @@ public class Cloner {
|
||||
/**
|
||||
* registers an immutable class. Immutable classes are not cloned.
|
||||
*
|
||||
* @param c the immutable class
|
||||
* @param c
|
||||
* the immutable class
|
||||
*/
|
||||
public void registerImmutable(final Class<?>... c) {
|
||||
for (final Class<?> cl : c) {
|
||||
@ -252,7 +281,8 @@ public class Cloner {
|
||||
}
|
||||
|
||||
public void registerFastCloner(final Class<?> c, final IFastCloner fastCloner) {
|
||||
if (fastCloners.containsKey(c)) throw new IllegalArgumentException(c + " already fast-cloned!");
|
||||
if (fastCloners.containsKey(c))
|
||||
throw new IllegalArgumentException(c + " already fast-cloned!");
|
||||
fastCloners.put(c, fastCloner);
|
||||
}
|
||||
|
||||
@ -263,8 +293,10 @@ public class Cloner {
|
||||
/**
|
||||
* creates a new instance of c. Override to provide your own implementation
|
||||
*
|
||||
* @param <T> the type of c
|
||||
* @param c the class
|
||||
* @param <T>
|
||||
* the type of c
|
||||
* @param c
|
||||
* the class
|
||||
* @return a new instance of c
|
||||
*/
|
||||
protected <T> T newInstance(final Class<T> c) {
|
||||
@ -275,7 +307,8 @@ public class Cloner {
|
||||
public <T> T fastCloneOrNewInstance(final Class<T> c) {
|
||||
try {
|
||||
final T fastClone = (T) fastClone(c, null);
|
||||
if (fastClone != null) return fastClone;
|
||||
if (fastClone != null)
|
||||
return fastClone;
|
||||
} catch (final IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -286,13 +319,17 @@ public class Cloner {
|
||||
/**
|
||||
* deep clones "o".
|
||||
*
|
||||
* @param <T> the type of "o"
|
||||
* @param o the object to be deep-cloned
|
||||
* @param <T>
|
||||
* the type of "o"
|
||||
* @param o
|
||||
* the object to be deep-cloned
|
||||
* @return a deep-clone of "o".
|
||||
*/
|
||||
public <T> T deepClone(final T o) {
|
||||
if (o == null) return null;
|
||||
if (!cloningEnabled) return o;
|
||||
if (o == null)
|
||||
return null;
|
||||
if (!cloningEnabled)
|
||||
return o;
|
||||
if (dumpCloned != null) {
|
||||
dumpCloned.startCloning(o.getClass());
|
||||
}
|
||||
@ -305,8 +342,10 @@ public class Cloner {
|
||||
}
|
||||
|
||||
public <T> T deepCloneDontCloneInstances(final T o, final Object... dontCloneThese) {
|
||||
if (o == null) return null;
|
||||
if (!cloningEnabled) return o;
|
||||
if (o == null)
|
||||
return null;
|
||||
if (!cloningEnabled)
|
||||
return o;
|
||||
if (dumpCloned != null) {
|
||||
dumpCloned.startCloning(o.getClass());
|
||||
}
|
||||
@ -325,13 +364,17 @@ public class Cloner {
|
||||
* shallow clones "o". This means that if c=shallowClone(o) then
|
||||
* c!=o. Any change to c won't affect o.
|
||||
*
|
||||
* @param <T> the type of o
|
||||
* @param o the object to be shallow-cloned
|
||||
* @param <T>
|
||||
* the type of o
|
||||
* @param o
|
||||
* the object to be shallow-cloned
|
||||
* @return a shallow clone of "o"
|
||||
*/
|
||||
public <T> T shallowClone(final T o) {
|
||||
if (o == null) return null;
|
||||
if (!cloningEnabled) return o;
|
||||
if (o == null)
|
||||
return null;
|
||||
if (!cloningEnabled)
|
||||
return o;
|
||||
try {
|
||||
return cloneInternal(o, null);
|
||||
} catch (final IllegalAccessException e) {
|
||||
@ -344,9 +387,11 @@ public class Cloner {
|
||||
private boolean cloneAnonymousParent = true;
|
||||
|
||||
/**
|
||||
* override this to decide if a class is immutable. Immutable classes are not cloned.
|
||||
* override this to decide if a class is immutable. Immutable classes are
|
||||
* not cloned.
|
||||
*
|
||||
* @param clz the class under check
|
||||
* @param clz
|
||||
* the class under check
|
||||
* @return true to mark clz as immutable and skip cloning it
|
||||
*/
|
||||
protected boolean considerImmutable(final Class<?> clz) {
|
||||
@ -360,13 +405,16 @@ public class Cloner {
|
||||
/**
|
||||
* decides if a class is to be considered immutable or not
|
||||
*
|
||||
* @param clz the class under check
|
||||
* @param clz
|
||||
* the class under check
|
||||
* @return true if the clz is considered immutable
|
||||
*/
|
||||
private boolean isImmutable(final Class<?> clz) {
|
||||
final Boolean isIm = immutables.get(clz);
|
||||
if (isIm != null) return isIm;
|
||||
if (considerImmutable(clz)) return true;
|
||||
if (isIm != null)
|
||||
return isIm;
|
||||
if (considerImmutable(clz))
|
||||
return true;
|
||||
|
||||
final Class<?> immutableAnnotation = getImmutableAnnotation();
|
||||
for (final Annotation annotation : clz.getDeclaredAnnotations()) {
|
||||
@ -394,24 +442,34 @@ public class Cloner {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T cloneInternal(final T o, final Map<Object, Object> clones) throws IllegalAccessException {
|
||||
if (o == null) return null;
|
||||
if (o == this) return null; // don't clone the cloner!
|
||||
if (ignoredInstances.containsKey(o)) return o;
|
||||
if (o instanceof Enum) return o;
|
||||
if (o == null)
|
||||
return null;
|
||||
if (o == this)
|
||||
return null; // don't clone the cloner!
|
||||
if (ignoredInstances.containsKey(o))
|
||||
return o;
|
||||
if (o instanceof Enum)
|
||||
return o;
|
||||
final Class<T> clz = (Class<T>) o.getClass();
|
||||
// skip cloning ignored classes
|
||||
if (nullInstead.contains(clz)) return null;
|
||||
if (ignored.contains(clz)) return o;
|
||||
if (nullInstead.contains(clz))
|
||||
return null;
|
||||
if (ignored.contains(clz))
|
||||
return o;
|
||||
for (final Class<?> iClz : ignoredInstanceOf) {
|
||||
if (iClz.isAssignableFrom(clz)) return o;
|
||||
if (iClz.isAssignableFrom(clz))
|
||||
return o;
|
||||
}
|
||||
if (isImmutable(clz)) return o;
|
||||
if (isImmutable(clz))
|
||||
return o;
|
||||
if (o instanceof IFreezable) {
|
||||
final IFreezable f = (IFreezable) o;
|
||||
if (f.isFrozen()) return o;
|
||||
if (f.isFrozen())
|
||||
return o;
|
||||
}
|
||||
final Object clonedPreviously = clones != null ? clones.get(o) : null;
|
||||
if (clonedPreviously != null) return (T) clonedPreviously;
|
||||
if (clonedPreviously != null)
|
||||
return (T) clonedPreviously;
|
||||
|
||||
final Object fastClone = fastClone(o, clones);
|
||||
if (fastClone != null) {
|
||||
@ -441,7 +499,7 @@ public class Cloner {
|
||||
for (final Field field : fields) {
|
||||
final int modifiers = field.getModifiers();
|
||||
if (!Modifier.isStatic(modifiers)) {
|
||||
if ( ! (nullTransient && Modifier.isTransient(modifiers)) ) {
|
||||
if (!(nullTransient && Modifier.isTransient(modifiers))) {
|
||||
// request by Jonathan : transient fields can be null-ed
|
||||
final Object fieldObject = field.get(o);
|
||||
final boolean shouldClone = (cloneSynthetics || !field.isSynthetic()) && (cloneAnonymousParent || !isAnonymousParent(field));
|
||||
@ -464,7 +522,7 @@ public class Cloner {
|
||||
if (clones != null) {
|
||||
clones.put(o, newInstance);
|
||||
}
|
||||
if(clz.getComponentType().isPrimitive() || isImmutable(clz.getComponentType())) {
|
||||
if (clz.getComponentType().isPrimitive() || isImmutable(clz.getComponentType())) {
|
||||
System.arraycopy(o, 0, newInstance, 0, length);
|
||||
} else {
|
||||
for (int i = 0; i < length; i++) {
|
||||
@ -481,14 +539,20 @@ public class Cloner {
|
||||
}
|
||||
|
||||
/**
|
||||
* copies all properties from src to dest. Src and dest can be of different class, provided they contain same field names/types
|
||||
* copies all properties from src to dest. Src and dest can be of different
|
||||
* class, provided they contain same field names/types
|
||||
*
|
||||
* @param src the source object
|
||||
* @param dest the destination object which must contain as minimum all the fields of src
|
||||
* @param src
|
||||
* the source object
|
||||
* @param dest
|
||||
* the destination object which must contain as minimum all the
|
||||
* fields of src
|
||||
*/
|
||||
public <T, E extends T> void copyPropertiesOfInheritedClass(final T src, final E dest) {
|
||||
if (src == null) throw new IllegalArgumentException("src can't be null");
|
||||
if (dest == null) throw new IllegalArgumentException("dest can't be null");
|
||||
if (src == null)
|
||||
throw new IllegalArgumentException("src can't be null");
|
||||
if (dest == null)
|
||||
throw new IllegalArgumentException("dest can't be null");
|
||||
final Class<? extends Object> srcClz = src.getClass();
|
||||
final Class<? extends Object> destClz = dest.getClass();
|
||||
if (srcClz.isArray()) {
|
||||
@ -559,20 +623,24 @@ public class Cloner {
|
||||
* setDumpCloned() if you want to control where to print the cloned
|
||||
* classes.
|
||||
*
|
||||
* @param dumpClonedClasses true to enable printing all cloned classes
|
||||
* @param dumpClonedClasses
|
||||
* true to enable printing all cloned classes
|
||||
*/
|
||||
public void setDumpClonedClasses(final boolean dumpClonedClasses) {
|
||||
if (dumpClonedClasses) {
|
||||
dumpCloned = new IDumpCloned() {
|
||||
@Override
|
||||
public void startCloning(Class<?> clz) {
|
||||
System.out.println("clone>" + clz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cloning(Field field, Class<?> clz) {
|
||||
System.out.println("cloned field>" + field + " -- of class " + clz);
|
||||
}
|
||||
};
|
||||
} else dumpCloned = null;
|
||||
} else
|
||||
dumpCloned = null;
|
||||
}
|
||||
|
||||
public boolean isCloningEnabled() {
|
||||
@ -602,9 +670,10 @@ public class Cloner {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if Cloner lib is in a shared jar folder for a container (i.e. tomcat/shared), then
|
||||
* this method is preferable in order to instantiate cloner. Please
|
||||
* see https://code.google.com/p/cloning/issues/detail?id=23
|
||||
* @return if Cloner lib is in a shared jar folder for a container (i.e.
|
||||
* tomcat/shared), then
|
||||
* this method is preferable in order to instantiate cloner. Please
|
||||
* see https://code.google.com/p/cloning/issues/detail?id=23
|
||||
*/
|
||||
public static Cloner shared() {
|
||||
return new Cloner(new ObjenesisInstantiationStrategy());
|
||||
|
@ -5,14 +5,12 @@ package com.rits.cloning;
|
||||
*
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 18 Jan 2009
|
||||
* 18 Jan 2009
|
||||
*/
|
||||
public class CloningException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 3815175312001146867L;
|
||||
public class CloningException extends RuntimeException {
|
||||
private static final long serialVersionUID = 3815175312001146867L;
|
||||
|
||||
public CloningException(final String message, final Throwable cause)
|
||||
{
|
||||
public CloningException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
|
||||
}
|
||||
|
@ -6,18 +6,17 @@ import java.util.Map;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 21 May 2009
|
||||
* 21 May 2009
|
||||
*/
|
||||
public class FastClonerArrayList implements IFastCloner
|
||||
{
|
||||
public class FastClonerArrayList implements IFastCloner {
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
final ArrayList al = (ArrayList) t;
|
||||
final ArrayList l = new ArrayList(al.size());
|
||||
for (final Object o : al)
|
||||
{
|
||||
final Object cloneInternal = cloner.deepClone(o, clones);
|
||||
l.add(cloneInternal);
|
||||
for (final Object o : al) {
|
||||
final Object cloneInternal = cloner.deepClone(o, clones);
|
||||
l.add(cloneInternal);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
@ -8,11 +8,11 @@ import java.util.TimeZone;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 21 May 2009
|
||||
* 21 May 2009
|
||||
*/
|
||||
public class FastClonerCalendar implements IFastCloner
|
||||
{
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
public class FastClonerCalendar implements IFastCloner {
|
||||
@Override
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
final GregorianCalendar gc = new GregorianCalendar();
|
||||
Calendar c = (Calendar) t;
|
||||
gc.setTimeInMillis(c.getTimeInMillis());
|
||||
|
@ -6,18 +6,17 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 18 Oct 2011
|
||||
* 18 Oct 2011
|
||||
*/
|
||||
public class FastClonerConcurrentHashMap implements IFastCloner
|
||||
{
|
||||
public class FastClonerConcurrentHashMap implements IFastCloner {
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
final ConcurrentHashMap<Object, Object> m = (ConcurrentHashMap) t;
|
||||
final ConcurrentHashMap result = new ConcurrentHashMap();
|
||||
for (final Map.Entry e : m.entrySet())
|
||||
{
|
||||
final Object key = cloner.deepClone(e.getKey(), clones);
|
||||
final Object value = cloner.deepClone(e.getValue(), clones);
|
||||
for (final Map.Entry e : m.entrySet()) {
|
||||
final Object key = cloner.deepClone(e.getKey(), clones);
|
||||
final Object value = cloner.deepClone(e.getValue(), clones);
|
||||
|
||||
result.put(key, value);
|
||||
}
|
||||
|
@ -6,20 +6,19 @@ import java.util.Map;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 21 May 2009
|
||||
* 21 May 2009
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public abstract class FastClonerCustomCollection<T extends Collection> implements IFastCloner
|
||||
{
|
||||
public abstract class FastClonerCustomCollection<T extends Collection> implements IFastCloner {
|
||||
public abstract T getInstance(T o);
|
||||
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
@Override
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
final T c = getInstance((T) t);
|
||||
final T l = (T) t;
|
||||
for (final Object o : l)
|
||||
{
|
||||
final Object clone = cloner.deepClone(o, clones);
|
||||
c.add(clone);
|
||||
for (final Object o : l) {
|
||||
final Object clone = cloner.deepClone(o, clones);
|
||||
c.add(clone);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
@ -6,20 +6,19 @@ import java.util.Set;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 21 May 2009
|
||||
* 21 May 2009
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public abstract class FastClonerCustomMap<T extends Map> implements IFastCloner
|
||||
{
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
public abstract class FastClonerCustomMap<T extends Map> implements IFastCloner {
|
||||
@Override
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
final T m = (T) t;
|
||||
final T result = getInstance((T) t);
|
||||
final Set<Map.Entry<Object, Object>> entrySet = m.entrySet();
|
||||
for (final Map.Entry e : entrySet)
|
||||
{
|
||||
final Object key = cloner.deepClone(e.getKey(), clones);
|
||||
final Object value = cloner.deepClone(e.getValue(), clones);
|
||||
result.put(key, value);
|
||||
for (final Map.Entry e : entrySet) {
|
||||
final Object key = cloner.deepClone(e.getKey(), clones);
|
||||
final Object value = cloner.deepClone(e.getValue(), clones);
|
||||
result.put(key, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -6,18 +6,17 @@ import java.util.Map;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 21 May 2009
|
||||
* 21 May 2009
|
||||
*/
|
||||
public class FastClonerHashMap implements IFastCloner
|
||||
{
|
||||
public class FastClonerHashMap implements IFastCloner {
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
final HashMap<Object, Object> m = (HashMap) t;
|
||||
final HashMap result = new HashMap();
|
||||
for (final Map.Entry e : m.entrySet())
|
||||
{
|
||||
final Object key = cloner.deepClone(e.getKey(), clones);
|
||||
final Object value = cloner.deepClone(e.getValue(), clones);
|
||||
for (final Map.Entry e : m.entrySet()) {
|
||||
final Object key = cloner.deepClone(e.getKey(), clones);
|
||||
final Object value = cloner.deepClone(e.getValue(), clones);
|
||||
|
||||
result.put(key, value);
|
||||
}
|
||||
|
@ -6,18 +6,17 @@ import java.util.Map;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 21 May 2009
|
||||
* 21 May 2009
|
||||
*/
|
||||
public class FastClonerHashSet implements IFastCloner
|
||||
{
|
||||
public class FastClonerHashSet implements IFastCloner {
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
final HashSet al = (HashSet) t;
|
||||
final HashSet l = new HashSet();
|
||||
for (final Object o : al)
|
||||
{
|
||||
final Object cloneInternal = cloner.deepClone(o, clones);
|
||||
l.add(cloneInternal);
|
||||
for (final Object o : al) {
|
||||
final Object cloneInternal = cloner.deepClone(o, clones);
|
||||
l.add(cloneInternal);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
@ -6,18 +6,17 @@ import java.util.Map;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 21 May 2009
|
||||
* 21 May 2009
|
||||
*/
|
||||
public class FastClonerLinkedList implements IFastCloner
|
||||
{
|
||||
public class FastClonerLinkedList implements IFastCloner {
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
final LinkedList al = (LinkedList) t;
|
||||
final LinkedList l = new LinkedList();
|
||||
for (final Object o : al)
|
||||
{
|
||||
final Object cloneInternal = cloner.deepClone(o, clones);
|
||||
l.add(cloneInternal);
|
||||
for (final Object o : al) {
|
||||
final Object cloneInternal = cloner.deepClone(o, clones);
|
||||
l.add(cloneInternal);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
@ -6,19 +6,18 @@ import java.util.TreeMap;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 21 May 2009
|
||||
* 21 May 2009
|
||||
*/
|
||||
public class FastClonerTreeMap implements IFastCloner
|
||||
{
|
||||
public class FastClonerTreeMap implements IFastCloner {
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
public Object clone(final Object t, final IDeepCloner cloner, final Map<Object, Object> clones) {
|
||||
final TreeMap<Object, Object> m = (TreeMap) t;
|
||||
final TreeMap result = new TreeMap(m.comparator());
|
||||
for (final Map.Entry e : m.entrySet())
|
||||
{
|
||||
final Object key = cloner.deepClone(e.getKey(), clones);
|
||||
final Object value = cloner.deepClone(e.getValue(), clones);
|
||||
result.put(key, value);
|
||||
for (final Map.Entry e : m.entrySet()) {
|
||||
final Object key = cloner.deepClone(e.getKey(), clones);
|
||||
final Object value = cloner.deepClone(e.getValue(), clones);
|
||||
result.put(key, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -8,13 +8,16 @@ import java.util.Map;
|
||||
* @author kostas.kougios Date 24/06/14
|
||||
*/
|
||||
public interface IDeepCloner {
|
||||
/**
|
||||
* deep clones o
|
||||
*
|
||||
* @param o the object to be deep cloned
|
||||
* @param clones pass on the same map from IFastCloner
|
||||
* @param <T> the type of o
|
||||
* @return a clone of o
|
||||
*/
|
||||
<T> T deepClone(final T o, final Map<Object, Object> clones);
|
||||
/**
|
||||
* deep clones o
|
||||
*
|
||||
* @param o
|
||||
* the object to be deep cloned
|
||||
* @param clones
|
||||
* pass on the same map from IFastCloner
|
||||
* @param <T>
|
||||
* the type of o
|
||||
* @return a clone of o
|
||||
*/
|
||||
<T> T deepClone(final T o, final Map<Object, Object> clones);
|
||||
}
|
||||
|
@ -4,10 +4,9 @@ import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author: kostas.kougios
|
||||
* Date: 06/08/13
|
||||
* Date: 06/08/13
|
||||
*/
|
||||
public interface IDumpCloned
|
||||
{
|
||||
public interface IDumpCloned {
|
||||
void startCloning(Class<?> clz);
|
||||
|
||||
void cloning(Field field, Class<?> clz);
|
||||
|
@ -7,8 +7,8 @@ import java.util.Map;
|
||||
* (it has to be registered with Cloner)
|
||||
*
|
||||
* @author kostantinos.kougios
|
||||
* 21 May 2009
|
||||
* 21 May 2009
|
||||
*/
|
||||
public interface IFastCloner {
|
||||
public Object clone(Object t, IDeepCloner cloner, Map<Object, Object> clones);
|
||||
public Object clone(Object t, IDeepCloner cloner, Map<Object, Object> clones);
|
||||
}
|
||||
|
@ -3,10 +3,9 @@ package com.rits.cloning;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 15 Nov 2010
|
||||
* 15 Nov 2010
|
||||
*/
|
||||
public interface IFreezable
|
||||
{
|
||||
public interface IFreezable {
|
||||
public boolean isFrozen();
|
||||
|
||||
}
|
||||
|
@ -3,9 +3,8 @@ package com.rits.cloning;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 17 Jul 2012
|
||||
* 17 Jul 2012
|
||||
*/
|
||||
public interface IInstantiationStrategy
|
||||
{
|
||||
public interface IInstantiationStrategy {
|
||||
<T> T newInstance(final Class<T> c);
|
||||
}
|
||||
|
@ -11,15 +11,17 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 24 Mar 2011
|
||||
* 24 Mar 2011
|
||||
*/
|
||||
@Target(TYPE)
|
||||
@Retention(RUNTIME)
|
||||
public @interface Immutable
|
||||
{
|
||||
public @interface Immutable {
|
||||
/**
|
||||
* by default all subclasses of the @Immutable class are not immutable. This can override it.
|
||||
* @return true for subclasses of @Immutable class to be regarded as immutable from the cloner
|
||||
* by default all subclasses of the @Immutable class are not immutable. This
|
||||
* can override it.
|
||||
*
|
||||
* @return true for subclasses of @Immutable class to be regarded as
|
||||
* immutable from the cloner
|
||||
*/
|
||||
boolean subClass() default false;
|
||||
}
|
||||
|
@ -6,21 +6,19 @@ import org.objenesis.ObjenesisStd;
|
||||
/**
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 17 Jul 2012
|
||||
* 17 Jul 2012
|
||||
*/
|
||||
public class ObjenesisInstantiationStrategy implements IInstantiationStrategy
|
||||
{
|
||||
private final Objenesis objenesis = new ObjenesisStd();
|
||||
public class ObjenesisInstantiationStrategy implements IInstantiationStrategy {
|
||||
private final Objenesis objenesis = new ObjenesisStd();
|
||||
|
||||
public <T> T newInstance(Class<T> c)
|
||||
{
|
||||
@Override
|
||||
public <T> T newInstance(Class<T> c) {
|
||||
return objenesis.newInstance(c);
|
||||
}
|
||||
|
||||
private static ObjenesisInstantiationStrategy instance = new ObjenesisInstantiationStrategy();
|
||||
private static ObjenesisInstantiationStrategy instance = new ObjenesisInstantiationStrategy();
|
||||
|
||||
public static ObjenesisInstantiationStrategy getInstance()
|
||||
{
|
||||
public static ObjenesisInstantiationStrategy getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
@ -5,66 +5,85 @@ import java.util.Collection;
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
/**
|
||||
* Perspectives: an object instance of a class behaving differently according to the "view angle".
|
||||
*
|
||||
* Perspectives: an object instance of a class behaving differently according to
|
||||
* the "view angle".
|
||||
*
|
||||
* @author kostantinos.kougios
|
||||
*
|
||||
* 30 Nov 2009
|
||||
* 30 Nov 2009
|
||||
*/
|
||||
public class Perspectives
|
||||
{
|
||||
private final Cloner cloner;
|
||||
public class Perspectives {
|
||||
private final Cloner cloner;
|
||||
|
||||
public Perspectives(final Cloner cloner)
|
||||
{
|
||||
public Perspectives(final Cloner cloner) {
|
||||
this.cloner = cloner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample: if o is an instance of Product and c is OrderedProduct.class then this returns
|
||||
* and instance of OrderedProduct.class which has equal field values to those of the instance of Product.
|
||||
* In other words, the returned instance of OrderedProduct.class is the Product instance from the perspective
|
||||
* Sample: if o is an instance of Product and c is OrderedProduct.class then
|
||||
* this returns
|
||||
* and instance of OrderedProduct.class which has equal field values to
|
||||
* those of the instance of Product.
|
||||
* In other words, the returned instance of OrderedProduct.class is the
|
||||
* Product instance from the perspective
|
||||
* of an OrderedProduct
|
||||
*
|
||||
* View an object o from the perspective of class c. (view o as an instance of c). c must be instanceof o.getClass()
|
||||
* View an object o from the perspective of class c. (view o as an instance
|
||||
* of c). c must be instanceof o.getClass()
|
||||
*
|
||||
* @param <T> the object
|
||||
* @param <E> this will be the returned type and it must be instanceof T. All properties of o will be copied to this instance.
|
||||
* @param c the class of E. This is used to generate new instances of c
|
||||
* @param o the object that must be viewed from a different perspective
|
||||
* @return the E perspective of o
|
||||
* @param <T>
|
||||
* the object
|
||||
* @param <E>
|
||||
* this will be the returned type and it must be instanceof T.
|
||||
* All properties of o will be copied to this instance.
|
||||
* @param c
|
||||
* the class of E. This is used to generate new instances of c
|
||||
* @param o
|
||||
* the object that must be viewed from a different perspective
|
||||
* @return the E perspective of o
|
||||
*/
|
||||
public <T, E extends T> E viewAs(final Class<E> c, final T o)
|
||||
{
|
||||
if (o == null) return null;
|
||||
if (o instanceof Collection<?>) throw new IllegalArgumentException("for collections please use viewCollectionAs() method. Invalid object " + o);
|
||||
public <T, E extends T> E viewAs(final Class<E> c, final T o) {
|
||||
if (o == null)
|
||||
return null;
|
||||
if (o instanceof Collection<?>)
|
||||
throw new IllegalArgumentException("for collections please use viewCollectionAs() method. Invalid object " + o);
|
||||
final E newInstance = cloner.fastCloneOrNewInstance(c);
|
||||
cloner.copyPropertiesOfInheritedClass(o, newInstance);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample: if o is a [ Products extends LinkedList<Product> ] then the returned instance
|
||||
* Sample: if o is a [ Products extends LinkedList<Product> ] then the
|
||||
* returned instance
|
||||
* is a [ OrderedProducts extends LinkedList<OrderedProduct> ].
|
||||
*
|
||||
* View a collection o from the perspective of collection E.
|
||||
*
|
||||
* NOTE: order of the items might not be preserved, depending on the collection type
|
||||
* NOTE: order of the items might not be preserved, depending on the
|
||||
* collection type
|
||||
*
|
||||
* @param <T> the type of the collection o
|
||||
* @param <I> the type of the elements of the collection o
|
||||
* @param <E> the type of the perspective collection
|
||||
* @param <NI> the type of the perspective's elements
|
||||
* @param newCollection the collection to which the adapted instances should be added
|
||||
* @param currentCollection the collection with the instances to be adapted
|
||||
* @param perspectiveCollectionItemClass the class of the NI
|
||||
* @return E, the collection from a different perspective or null if currentCollection is null
|
||||
* @param <T>
|
||||
* the type of the collection o
|
||||
* @param <I>
|
||||
* the type of the elements of the collection o
|
||||
* @param <E>
|
||||
* the type of the perspective collection
|
||||
* @param <NI>
|
||||
* the type of the perspective's elements
|
||||
* @param newCollection
|
||||
* the collection to which the adapted instances should be added
|
||||
* @param currentCollection
|
||||
* the collection with the instances to be adapted
|
||||
* @param perspectiveCollectionItemClass
|
||||
* the class of the NI
|
||||
* @return E, the collection from a different perspective or null if
|
||||
* currentCollection is null
|
||||
*/
|
||||
public <I, NI extends I, T extends Collection<I>, E extends Collection<NI>> E viewCollectionAs(final E newCollection, final Class<NI> perspectiveCollectionItemClass, final T currentCollection)
|
||||
{
|
||||
if (currentCollection == null) return null;
|
||||
for (final I item : currentCollection)
|
||||
{
|
||||
public <I, NI extends I, T extends Collection<I>, E extends Collection<NI>> E viewCollectionAs(
|
||||
final E newCollection, final Class<NI> perspectiveCollectionItemClass, final T currentCollection) {
|
||||
if (currentCollection == null)
|
||||
return null;
|
||||
for (final I item : currentCollection) {
|
||||
final NI newItem = viewAs(perspectiveCollectionItemClass, item);
|
||||
newCollection.add(newItem);
|
||||
}
|
||||
|
@ -1,99 +1,99 @@
|
||||
package org.nevec.rjm ;
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.warpgate.pi.calculator.Errore;
|
||||
import org.warp.picalculator.Errore;
|
||||
|
||||
/**
|
||||
* Bernoulli numbers.
|
||||
*
|
||||
* @since 2006-06-25
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Bernoulli {
|
||||
/*
|
||||
* The list of all Bernoulli numbers as a vector, n=0,2,4,....
|
||||
*/
|
||||
static Vector<Rational> a = new Vector<Rational>();
|
||||
|
||||
/** Bernoulli numbers.
|
||||
* @since 2006-06-25
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Bernoulli
|
||||
{
|
||||
/*
|
||||
* The list of all Bernoulli numbers as a vector, n=0,2,4,....
|
||||
*/
|
||||
static Vector<Rational> a = new Vector<Rational>() ;
|
||||
public Bernoulli() {
|
||||
if (a.size() == 0) {
|
||||
a.add(Rational.ONE);
|
||||
a.add(new Rational(1, 6));
|
||||
}
|
||||
}
|
||||
|
||||
public Bernoulli()
|
||||
{
|
||||
if ( a.size() == 0 )
|
||||
{
|
||||
a.add(Rational.ONE) ;
|
||||
a.add(new Rational(1,6)) ;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set a coefficient in the internal table.
|
||||
*
|
||||
* @param n
|
||||
* the zero-based index of the coefficient. n=0 for the constant
|
||||
* term.
|
||||
* @param value
|
||||
* the new value of the coefficient.
|
||||
*/
|
||||
protected void set(final int n, final Rational value) {
|
||||
final int nindx = n / 2;
|
||||
if (nindx < a.size())
|
||||
a.set(nindx, value);
|
||||
else {
|
||||
while (a.size() < nindx)
|
||||
a.add(Rational.ZERO);
|
||||
a.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/** Set a coefficient in the internal table.
|
||||
* @param n the zero-based index of the coefficient. n=0 for the constant term.
|
||||
* @param value the new value of the coefficient.
|
||||
*/
|
||||
protected void set(final int n, final Rational value)
|
||||
{
|
||||
final int nindx = n /2 ;
|
||||
if ( nindx < a.size())
|
||||
a.set(nindx,value) ;
|
||||
else
|
||||
{
|
||||
while ( a.size() < nindx )
|
||||
a.add( Rational.ZERO ) ;
|
||||
a.add(value) ;
|
||||
}
|
||||
}
|
||||
|
||||
/** The Bernoulli number at the index provided.
|
||||
* @param n the index, non-negative.
|
||||
* @return the B_0=1 for n=0, B_1=-1/2 for n=1, B_2=1/6 for n=2 etc
|
||||
* @throws Errore
|
||||
*/
|
||||
public Rational at(int n) throws Errore
|
||||
{
|
||||
if ( n == 1)
|
||||
return(new Rational(-1,2)) ;
|
||||
else if ( n % 2 != 0 )
|
||||
return Rational.ZERO ;
|
||||
else
|
||||
{
|
||||
final int nindx = n /2 ;
|
||||
if( a.size() <= nindx )
|
||||
{
|
||||
for(int i= 2*a.size() ; i <= n; i+= 2)
|
||||
set(i, doubleSum(i) ) ;
|
||||
}
|
||||
return a.elementAt(nindx) ;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate a new B_n by a standard double sum.
|
||||
* @param n The index of the Bernoulli number.
|
||||
* @return The Bernoulli number at n.
|
||||
*/
|
||||
private Rational doubleSum(int n) throws Errore
|
||||
{
|
||||
Rational resul = Rational.ZERO ;
|
||||
for(int k=0 ; k <= n ; k++)
|
||||
{
|
||||
Rational jsum = Rational.ZERO ;
|
||||
BigInteger bin = BigInteger.ONE ;
|
||||
for(int j=0 ; j <= k ; j++)
|
||||
{
|
||||
BigInteger jpown = (new BigInteger(""+j)).pow(n);
|
||||
if ( j % 2 == 0)
|
||||
jsum = jsum.add(bin.multiply(jpown)) ;
|
||||
else
|
||||
jsum = jsum.subtract(bin.multiply(jpown)) ;
|
||||
|
||||
/* update binomial(k,j) recursively
|
||||
*/
|
||||
bin = bin.multiply( new BigInteger(""+(k-j))). divide( new BigInteger(""+(j+1)) ) ;
|
||||
}
|
||||
resul = resul.add(jsum.divide(new BigInteger(""+(k+1)))) ;
|
||||
}
|
||||
return resul ;
|
||||
}
|
||||
/**
|
||||
* The Bernoulli number at the index provided.
|
||||
*
|
||||
* @param n
|
||||
* the index, non-negative.
|
||||
* @return the B_0=1 for n=0, B_1=-1/2 for n=1, B_2=1/6 for n=2 etc
|
||||
* @throws Errore
|
||||
*/
|
||||
public Rational at(int n) throws Errore {
|
||||
if (n == 1)
|
||||
return (new Rational(-1, 2));
|
||||
else if (n % 2 != 0)
|
||||
return Rational.ZERO;
|
||||
else {
|
||||
final int nindx = n / 2;
|
||||
if (a.size() <= nindx) {
|
||||
for (int i = 2 * a.size(); i <= n; i += 2)
|
||||
set(i, doubleSum(i));
|
||||
}
|
||||
return a.elementAt(nindx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a new B_n by a standard double sum.
|
||||
*
|
||||
* @param n The index of the Bernoulli number.
|
||||
*
|
||||
* @return The Bernoulli number at n.
|
||||
*/
|
||||
private Rational doubleSum(int n) throws Errore {
|
||||
Rational resul = Rational.ZERO;
|
||||
for (int k = 0; k <= n; k++) {
|
||||
Rational jsum = Rational.ZERO;
|
||||
BigInteger bin = BigInteger.ONE;
|
||||
for (int j = 0; j <= k; j++) {
|
||||
BigInteger jpown = (new BigInteger("" + j)).pow(n);
|
||||
if (j % 2 == 0)
|
||||
jsum = jsum.add(bin.multiply(jpown));
|
||||
else
|
||||
jsum = jsum.subtract(bin.multiply(jpown));
|
||||
|
||||
/*
|
||||
* update binomial(k,j) recursively
|
||||
*/
|
||||
bin = bin.multiply(new BigInteger("" + (k - j))).divide(new BigInteger("" + (j + 1)));
|
||||
}
|
||||
resul = resul.add(jsum.divide(new BigInteger("" + (k + 1))));
|
||||
}
|
||||
return resul;
|
||||
}
|
||||
|
||||
} /* Bernoulli */
|
||||
|
@ -1,188 +1,218 @@
|
||||
package org.nevec.rjm ;
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
|
||||
/**
|
||||
* Complex numbers with BigDecimal real and imaginary components
|
||||
*
|
||||
* @since 2008-10-26
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class BigComplex {
|
||||
/**
|
||||
* real part
|
||||
*/
|
||||
BigDecimal re;
|
||||
|
||||
/** Complex numbers with BigDecimal real and imaginary components
|
||||
* @since 2008-10-26
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class BigComplex
|
||||
{
|
||||
/** real part
|
||||
*/
|
||||
BigDecimal re ;
|
||||
/**
|
||||
* imaginary part
|
||||
*/
|
||||
BigDecimal im;
|
||||
|
||||
/** imaginary part
|
||||
*/
|
||||
BigDecimal im ;
|
||||
/**
|
||||
* The constant that equals zero
|
||||
*/
|
||||
final static BigComplex ZERO = new BigComplex(BigDecimal.ZERO, BigDecimal.ZERO);
|
||||
|
||||
/** The constant that equals zero
|
||||
*/
|
||||
final static BigComplex ZERO = new BigComplex(BigDecimal.ZERO, BigDecimal.ZERO) ;
|
||||
/**
|
||||
* Default ctor equivalent to zero.
|
||||
*/
|
||||
public BigComplex() {
|
||||
re = BigDecimal.ZERO;
|
||||
im = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
/** Default ctor equivalent to zero.
|
||||
*/
|
||||
public BigComplex()
|
||||
{
|
||||
re= BigDecimal.ZERO ;
|
||||
im= BigDecimal.ZERO ;
|
||||
}
|
||||
/**
|
||||
* ctor with real and imaginary parts
|
||||
*
|
||||
* @param x
|
||||
* real part
|
||||
* @param y
|
||||
* imaginary part
|
||||
*/
|
||||
public BigComplex(BigDecimal x, BigDecimal y) {
|
||||
re = x;
|
||||
im = y;
|
||||
}
|
||||
|
||||
/** ctor with real and imaginary parts
|
||||
* @param x real part
|
||||
* @param y imaginary part
|
||||
*/
|
||||
public BigComplex( BigDecimal x, BigDecimal y)
|
||||
{
|
||||
re=x ;
|
||||
im=y ;
|
||||
}
|
||||
/**
|
||||
* ctor with real part.
|
||||
*
|
||||
* @param x
|
||||
* real part.
|
||||
* The imaginary part is set to zero.
|
||||
*/
|
||||
public BigComplex(BigDecimal x) {
|
||||
re = x;
|
||||
im = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
/** ctor with real part.
|
||||
* @param x real part.
|
||||
* The imaginary part is set to zero.
|
||||
*/
|
||||
public BigComplex( BigDecimal x )
|
||||
{
|
||||
re=x ;
|
||||
im= BigDecimal.ZERO ;
|
||||
}
|
||||
/**
|
||||
* ctor with real and imaginary parts
|
||||
*
|
||||
* @param x
|
||||
* real part
|
||||
* @param y
|
||||
* imaginary part
|
||||
*/
|
||||
public BigComplex(double x, double y) {
|
||||
re = new BigDecimal(x);
|
||||
im = new BigDecimal(y);
|
||||
}
|
||||
|
||||
/** ctor with real and imaginary parts
|
||||
* @param x real part
|
||||
* @param y imaginary part
|
||||
*/
|
||||
public BigComplex( double x, double y)
|
||||
{
|
||||
re= new BigDecimal(x) ;
|
||||
im= new BigDecimal(y) ;
|
||||
}
|
||||
/**
|
||||
* Multiply with another BigComplex
|
||||
*
|
||||
* @param oth
|
||||
* The BigComplex which is a factor in the product
|
||||
* @param mc
|
||||
* Defining precision and rounding mode
|
||||
* @return This multiplied by oth
|
||||
* @since 2010-07-19 implemented with 3 multiplications and 5
|
||||
* additions/subtractions
|
||||
*/
|
||||
BigComplex multiply(final BigComplex oth, MathContext mc) {
|
||||
final BigDecimal a = re.add(im).multiply(oth.re);
|
||||
final BigDecimal b = oth.re.add(oth.im).multiply(im);
|
||||
final BigDecimal c = oth.im.subtract(oth.re).multiply(re);
|
||||
final BigDecimal x = a.subtract(b, mc);
|
||||
final BigDecimal y = a.add(c, mc);
|
||||
return new BigComplex(x, y);
|
||||
}
|
||||
|
||||
/** Multiply with another BigComplex
|
||||
* @param oth The BigComplex which is a factor in the product
|
||||
* @param mc Defining precision and rounding mode
|
||||
* @return This multiplied by oth
|
||||
* @since 2010-07-19 implemented with 3 multiplications and 5 additions/subtractions
|
||||
*/
|
||||
BigComplex multiply(final BigComplex oth, MathContext mc)
|
||||
{
|
||||
final BigDecimal a = re.add(im).multiply(oth.re) ;
|
||||
final BigDecimal b = oth.re.add(oth.im).multiply(im) ;
|
||||
final BigDecimal c = oth.im.subtract(oth.re).multiply(re) ;
|
||||
final BigDecimal x = a.subtract(b,mc) ;
|
||||
final BigDecimal y = a.add(c,mc) ;
|
||||
return new BigComplex(x,y) ;
|
||||
}
|
||||
/**
|
||||
* Add a BigDecimal
|
||||
*
|
||||
* @param oth
|
||||
* the value to be added to the real part.
|
||||
* @return this added to oth
|
||||
*/
|
||||
BigComplex add(final BigDecimal oth) {
|
||||
final BigDecimal x = re.add(oth);
|
||||
return new BigComplex(x, im);
|
||||
}
|
||||
|
||||
/** Add a BigDecimal
|
||||
* @param oth the value to be added to the real part.
|
||||
* @return this added to oth
|
||||
*/
|
||||
BigComplex add(final BigDecimal oth)
|
||||
{
|
||||
final BigDecimal x = re.add(oth) ;
|
||||
return new BigComplex(x,im) ;
|
||||
}
|
||||
/**
|
||||
* Subtract another BigComplex
|
||||
*
|
||||
* @param oth
|
||||
* the value to be subtracted from this.
|
||||
* @return this minus oth
|
||||
*/
|
||||
BigComplex subtract(final BigComplex oth) {
|
||||
final BigDecimal x = re.subtract(oth.re);
|
||||
final BigDecimal y = im.subtract(oth.im);
|
||||
return new BigComplex(x, y);
|
||||
}
|
||||
|
||||
/** Subtract another BigComplex
|
||||
* @param oth the value to be subtracted from this.
|
||||
* @return this minus oth
|
||||
*/
|
||||
BigComplex subtract(final BigComplex oth)
|
||||
{
|
||||
final BigDecimal x = re.subtract(oth.re) ;
|
||||
final BigDecimal y = im.subtract(oth.im) ;
|
||||
return new BigComplex(x,y) ;
|
||||
}
|
||||
/**
|
||||
* Complex-conjugation
|
||||
*
|
||||
* @return the complex conjugate of this.
|
||||
*/
|
||||
BigComplex conj() {
|
||||
return new BigComplex(re, im.negate());
|
||||
}
|
||||
|
||||
/** Complex-conjugation
|
||||
* @return the complex conjugate of this.
|
||||
*/
|
||||
BigComplex conj()
|
||||
{
|
||||
return new BigComplex(re,im.negate()) ;
|
||||
}
|
||||
/**
|
||||
* The absolute value squared.
|
||||
*
|
||||
* @return The sum of the squares of real and imaginary parts.
|
||||
* This is the square of BigComplex.abs() .
|
||||
*/
|
||||
BigDecimal norm() {
|
||||
return re.multiply(re).add(im.multiply(im));
|
||||
}
|
||||
|
||||
/** The absolute value squared.
|
||||
* @return The sum of the squares of real and imaginary parts.
|
||||
* This is the square of BigComplex.abs() .
|
||||
*/
|
||||
BigDecimal norm()
|
||||
{
|
||||
return re.multiply(re).add(im.multiply(im)) ;
|
||||
}
|
||||
/**
|
||||
* The absolute value.
|
||||
*
|
||||
* @return the square root of the sum of the squares of real and imaginary
|
||||
* parts.
|
||||
* @since 2008-10-27
|
||||
*/
|
||||
BigDecimal abs(MathContext mc) {
|
||||
return BigDecimalMath.sqrt(norm(), mc);
|
||||
}
|
||||
|
||||
/** The absolute value.
|
||||
* @return the square root of the sum of the squares of real and imaginary parts.
|
||||
* @since 2008-10-27
|
||||
*/
|
||||
BigDecimal abs(MathContext mc)
|
||||
{
|
||||
return BigDecimalMath.sqrt(norm(),mc) ;
|
||||
}
|
||||
/**
|
||||
* The square root.
|
||||
*
|
||||
* @return the square root of the this.
|
||||
* The branch is chosen such that the imaginary part of the result
|
||||
* has the
|
||||
* same sign as the imaginary part of this.
|
||||
* @see Tim Ahrendt, <a href="http://dx.doi.org/10.1145/236869.236924">Fast
|
||||
* High-precision computation of complex square roots</a>,
|
||||
* ISSAC 1996 p142-149.
|
||||
* @since 2008-10-27
|
||||
*/
|
||||
BigComplex sqrt(MathContext mc) {
|
||||
final BigDecimal half = new BigDecimal("2");
|
||||
/*
|
||||
* compute l=sqrt(re^2+im^2), then u=sqrt((l+re)/2)
|
||||
* and v= +- sqrt((l-re)/2 as the new real and imaginary parts.
|
||||
*/
|
||||
final BigDecimal l = abs(mc);
|
||||
if (l.compareTo(BigDecimal.ZERO) == 0)
|
||||
return new BigComplex(BigDecimalMath.scalePrec(BigDecimal.ZERO, mc), BigDecimalMath.scalePrec(BigDecimal.ZERO, mc));
|
||||
final BigDecimal u = BigDecimalMath.sqrt(l.add(re).divide(half, mc), mc);
|
||||
final BigDecimal v = BigDecimalMath.sqrt(l.subtract(re).divide(half, mc), mc);
|
||||
if (im.compareTo(BigDecimal.ZERO) >= 0)
|
||||
return new BigComplex(u, v);
|
||||
else
|
||||
return new BigComplex(u, v.negate());
|
||||
}
|
||||
|
||||
/** The square root.
|
||||
* @return the square root of the this.
|
||||
* The branch is chosen such that the imaginary part of the result has the
|
||||
* same sign as the imaginary part of this.
|
||||
* @see Tim Ahrendt, <a href="http://dx.doi.org/10.1145/236869.236924">Fast High-precision computation of complex square roots</a>,
|
||||
* ISSAC 1996 p142-149.
|
||||
* @since 2008-10-27
|
||||
*/
|
||||
BigComplex sqrt(MathContext mc)
|
||||
{
|
||||
final BigDecimal half = new BigDecimal("2") ;
|
||||
/* compute l=sqrt(re^2+im^2), then u=sqrt((l+re)/2)
|
||||
* and v= +- sqrt((l-re)/2 as the new real and imaginary parts.
|
||||
*/
|
||||
final BigDecimal l = abs(mc) ;
|
||||
if ( l.compareTo(BigDecimal.ZERO) == 0 )
|
||||
return new BigComplex( BigDecimalMath.scalePrec(BigDecimal.ZERO,mc),
|
||||
BigDecimalMath.scalePrec(BigDecimal.ZERO,mc) ) ;
|
||||
final BigDecimal u = BigDecimalMath.sqrt( l.add(re).divide(half,mc), mc );
|
||||
final BigDecimal v = BigDecimalMath.sqrt( l.subtract(re).divide(half,mc), mc );
|
||||
if ( im.compareTo(BigDecimal.ZERO)>= 0 )
|
||||
return new BigComplex(u,v) ;
|
||||
else
|
||||
return new BigComplex(u,v.negate()) ;
|
||||
}
|
||||
/**
|
||||
* The inverse of this.
|
||||
*
|
||||
* @return 1/this
|
||||
*/
|
||||
BigComplex inverse(MathContext mc) {
|
||||
final BigDecimal hyp = norm();
|
||||
/* 1/(x+iy)= (x-iy)/(x^2+y^2 */
|
||||
return new BigComplex(re.divide(hyp, mc), im.divide(hyp, mc).negate());
|
||||
}
|
||||
|
||||
/** The inverse of this.
|
||||
* @return 1/this
|
||||
*/
|
||||
BigComplex inverse(MathContext mc)
|
||||
{
|
||||
final BigDecimal hyp = norm() ;
|
||||
/* 1/(x+iy)= (x-iy)/(x^2+y^2 */
|
||||
return new BigComplex( re.divide(hyp,mc), im.divide(hyp,mc).negate() ) ;
|
||||
}
|
||||
/**
|
||||
* Divide through another BigComplex number.
|
||||
*
|
||||
* @return this/oth
|
||||
*/
|
||||
BigComplex divide(BigComplex oth, MathContext mc) {
|
||||
/* lazy implementation: (x+iy)/(a+ib)= (x+iy)* 1/(a+ib) */
|
||||
return multiply(oth.inverse(mc), mc);
|
||||
}
|
||||
|
||||
/** Divide through another BigComplex number.
|
||||
* @return this/oth
|
||||
*/
|
||||
BigComplex divide(BigComplex oth, MathContext mc)
|
||||
{
|
||||
/* lazy implementation: (x+iy)/(a+ib)= (x+iy)* 1/(a+ib) */
|
||||
return multiply(oth.inverse(mc),mc) ;
|
||||
}
|
||||
|
||||
/** Human-readable Fortran-type display
|
||||
* @return real and imaginary part in parenthesis, divided by a comma.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "("+re.toString()+","+im.toString()+")" ;
|
||||
}
|
||||
|
||||
/** Human-readable Fortran-type display
|
||||
* @return real and imaginary part in parenthesis, divided by a comma.
|
||||
*/
|
||||
public String toString(MathContext mc)
|
||||
{
|
||||
return "("+re.round(mc).toString()+","+im.round(mc).toString()+")" ;
|
||||
}
|
||||
/**
|
||||
* Human-readable Fortran-type display
|
||||
*
|
||||
* @return real and imaginary part in parenthesis, divided by a comma.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + re.toString() + "," + im.toString() + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Human-readable Fortran-type display
|
||||
*
|
||||
* @return real and imaginary part in parenthesis, divided by a comma.
|
||||
*/
|
||||
public String toString(MathContext mc) {
|
||||
return "(" + re.round(mc).toString() + "," + im.round(mc).toString() + ")";
|
||||
}
|
||||
|
||||
} /* BigComplex */
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,488 +1,557 @@
|
||||
package org.nevec.rjm ;
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.security.ProviderException;
|
||||
|
||||
import org.warpgate.pi.calculator.Errore;
|
||||
import org.warpgate.pi.calculator.Utils;
|
||||
import org.warp.picalculator.Errore;
|
||||
import org.warp.picalculator.Utils;
|
||||
|
||||
/** Square roots on the real line.
|
||||
* These represent numbers which are a product of a (signed) fraction by
|
||||
* a square root of a non-negative fraction.
|
||||
* This might be extended to values on the imaginary axis by allowing negative
|
||||
* values underneath the square root, but this is not yet implemented.
|
||||
* @since 2011-02-12
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class BigSurd implements Cloneable, Comparable<BigSurd>
|
||||
{
|
||||
/** The value of zero.
|
||||
*/
|
||||
static public BigSurd ZERO = new BigSurd() ;
|
||||
/**
|
||||
* Square roots on the real line.
|
||||
* These represent numbers which are a product of a (signed) fraction by
|
||||
* a square root of a non-negative fraction.
|
||||
* This might be extended to values on the imaginary axis by allowing negative
|
||||
* values underneath the square root, but this is not yet implemented.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
/**
|
||||
* The value of zero.
|
||||
*/
|
||||
static public BigSurd ZERO = new BigSurd();
|
||||
|
||||
/** The value of one.
|
||||
*/
|
||||
static public BigSurd ONE = new BigSurd(Rational.ONE,Rational.ONE) ;
|
||||
/** Prefactor
|
||||
*/
|
||||
Rational pref ;
|
||||
/**
|
||||
* The value of one.
|
||||
*/
|
||||
static public BigSurd ONE = new BigSurd(Rational.ONE, Rational.ONE);
|
||||
/**
|
||||
* Prefactor
|
||||
*/
|
||||
Rational pref;
|
||||
|
||||
/** The number underneath the square root, always non-negative.
|
||||
* The mathematical object has the value pref*sqrt(disc).
|
||||
*/
|
||||
Rational disc ;
|
||||
/**
|
||||
* The number underneath the square root, always non-negative.
|
||||
* The mathematical object has the value pref*sqrt(disc).
|
||||
*/
|
||||
Rational disc;
|
||||
|
||||
/** Default ctor, which represents the zero.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd()
|
||||
{
|
||||
pref = Rational.ZERO ;
|
||||
disc = Rational.ZERO ;
|
||||
}
|
||||
/**
|
||||
* Default ctor, which represents the zero.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd() {
|
||||
pref = Rational.ZERO;
|
||||
disc = Rational.ZERO;
|
||||
}
|
||||
|
||||
/** ctor given the prefactor and the basis of the root.
|
||||
* This creates an object of value a*sqrt(b).
|
||||
* @param a the prefactor.
|
||||
* @param b the discriminant.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(Rational a, Rational b)
|
||||
{
|
||||
this.pref = a ;
|
||||
/* reject attempts to use a negative b
|
||||
*/
|
||||
if ( b.signum() < 0 )
|
||||
throw new ProviderException("Not implemented: imaginary surds") ;
|
||||
this.disc = b ;
|
||||
try {
|
||||
normalize() ;
|
||||
normalizeG() ;
|
||||
} catch (Errore e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ctor given the prefactor and the basis of the root.
|
||||
* This creates an object of value a*sqrt(b).
|
||||
*
|
||||
* @param a
|
||||
* the prefactor.
|
||||
* @param b
|
||||
* the discriminant.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(Rational a, Rational b) {
|
||||
this.pref = a;
|
||||
/*
|
||||
* reject attempts to use a negative b
|
||||
*/
|
||||
if (b.signum() < 0)
|
||||
throw new ProviderException("Not implemented: imaginary surds");
|
||||
this.disc = b;
|
||||
try {
|
||||
normalize();
|
||||
normalizeG();
|
||||
} catch (Errore e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/** ctor given the numerator and denominator of the root.
|
||||
* This creates an object of value sqrt(a/b).
|
||||
* @param a the numerator
|
||||
* @param b the denominator.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(int a, int b)
|
||||
{
|
||||
this( Rational.ONE, new Rational(a,b) ) ;
|
||||
}
|
||||
/**
|
||||
* ctor given the numerator and denominator of the root.
|
||||
* This creates an object of value sqrt(a/b).
|
||||
*
|
||||
* @param a
|
||||
* the numerator
|
||||
* @param b
|
||||
* the denominator.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(int a, int b) {
|
||||
this(Rational.ONE, new Rational(a, b));
|
||||
}
|
||||
|
||||
/** ctor given the value under the root.
|
||||
* This creates an object of value sqrt(a).
|
||||
* @param a the discriminant.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(BigInteger a)
|
||||
{
|
||||
this( Rational.ONE, new Rational(a,BigInteger.ONE) ) ;
|
||||
}
|
||||
|
||||
public BigSurd(Rational a)
|
||||
{
|
||||
this( Rational.ONE, a) ;
|
||||
}
|
||||
/**
|
||||
* ctor given the value under the root.
|
||||
* This creates an object of value sqrt(a).
|
||||
*
|
||||
* @param a
|
||||
* the discriminant.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(BigInteger a) {
|
||||
this(Rational.ONE, new Rational(a, BigInteger.ONE));
|
||||
}
|
||||
|
||||
/** Create a deep copy.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd clone()
|
||||
{
|
||||
Rational fclon = pref.clone() ;
|
||||
Rational dclon = disc.clone() ;
|
||||
/* the main intent here is to bypass any attempt to reduce the discriminant
|
||||
* by figuring out the square-free part in normalize(), which has already done
|
||||
* in the current copy of the number.
|
||||
*/
|
||||
BigSurd cl = new BigSurd() ;
|
||||
cl.pref = fclon ;
|
||||
cl.disc = dclon ;
|
||||
return cl ;
|
||||
} /* BigSurd.clone */
|
||||
|
||||
/** Add two surds of compatible discriminant.
|
||||
* @param val The value to be added to this.
|
||||
*/
|
||||
|
||||
public BigSurdVec add(final BigSurd val)
|
||||
{
|
||||
//zero plus somethings yields something
|
||||
if ( signum() == 0 )
|
||||
return new BigSurdVec(val) ;
|
||||
else if (val.signum() == 0 )
|
||||
return new BigSurdVec(this) ;
|
||||
else
|
||||
// let the ctor of BigSurdVec to the work
|
||||
return new BigSurdVec(this,val) ;
|
||||
} /* BigSurd.add */
|
||||
public BigSurd(Rational a) {
|
||||
this(Rational.ONE, a);
|
||||
}
|
||||
|
||||
/** Multiply by another square root.
|
||||
* @param val a second number of this type.
|
||||
* @return the product of this with the val.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final BigSurd val)
|
||||
{
|
||||
return new BigSurd( pref.multiply(val.pref), disc.multiply(val.disc) ) ;
|
||||
} /* BigSurd.multiply */
|
||||
/**
|
||||
* Create a deep copy.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@Override
|
||||
public BigSurd clone() {
|
||||
Rational fclon = pref.clone();
|
||||
Rational dclon = disc.clone();
|
||||
/*
|
||||
* the main intent here is to bypass any attempt to reduce the
|
||||
* discriminant
|
||||
* by figuring out the square-free part in normalize(), which has
|
||||
* already done
|
||||
* in the current copy of the number.
|
||||
*/
|
||||
BigSurd cl = new BigSurd();
|
||||
cl.pref = fclon;
|
||||
cl.disc = dclon;
|
||||
return cl;
|
||||
} /* BigSurd.clone */
|
||||
|
||||
/** Multiply by a rational number.
|
||||
* @param val the factor.
|
||||
* @return the product of this with the val.
|
||||
* @since 2011-02-15
|
||||
*/
|
||||
public BigSurd multiply(final Rational val)
|
||||
{
|
||||
return new BigSurd( pref.multiply(val), disc) ;
|
||||
} /* BigSurd.multiply */
|
||||
/**
|
||||
* Add two surds of compatible discriminant.
|
||||
*
|
||||
* @param val
|
||||
* The value to be added to this.
|
||||
*/
|
||||
|
||||
/** Multiply by a BigInteger.
|
||||
* @param val a second number.
|
||||
* @return the product of this with the value.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final BigInteger val)
|
||||
{
|
||||
return new BigSurd(pref.multiply(val), disc) ;
|
||||
} /* BigSurd.multiply */
|
||||
public BigSurdVec add(final BigSurd val) {
|
||||
// zero plus somethings yields something
|
||||
if (signum() == 0)
|
||||
return new BigSurdVec(val);
|
||||
else if (val.signum() == 0)
|
||||
return new BigSurdVec(this);
|
||||
else
|
||||
// let the ctor of BigSurdVec to the work
|
||||
return new BigSurdVec(this, val);
|
||||
} /* BigSurd.add */
|
||||
|
||||
/** Multiply by an integer.
|
||||
* @param val a second number.
|
||||
* @return the product of this with the value.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final int val)
|
||||
{
|
||||
BigInteger tmp = new BigInteger(""+val) ;
|
||||
return multiply(tmp) ;
|
||||
} /* BigSurd.multiply */
|
||||
/**
|
||||
* Multiply by another square root.
|
||||
*
|
||||
* @param val
|
||||
* a second number of this type.
|
||||
* @return the product of this with the val.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final BigSurd val) {
|
||||
return new BigSurd(pref.multiply(val.pref), disc.multiply(val.disc));
|
||||
} /* BigSurd.multiply */
|
||||
|
||||
/**
|
||||
* Multiply by a rational number.
|
||||
*
|
||||
* @param val
|
||||
* the factor.
|
||||
* @return the product of this with the val.
|
||||
* @since 2011-02-15
|
||||
*/
|
||||
public BigSurd multiply(final Rational val) {
|
||||
return new BigSurd(pref.multiply(val), disc);
|
||||
} /* BigSurd.multiply */
|
||||
|
||||
/** Compute the square.
|
||||
* @return this value squared.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public Rational sqr()
|
||||
{
|
||||
Rational res = pref.pow(2) ;
|
||||
res = res.multiply(disc) ;
|
||||
return res;
|
||||
} /* BigSurd.sqr */
|
||||
/**
|
||||
* Multiply by a BigInteger.
|
||||
*
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the product of this with the value.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final BigInteger val) {
|
||||
return new BigSurd(pref.multiply(val), disc);
|
||||
} /* BigSurd.multiply */
|
||||
|
||||
/** Divide by another square root.
|
||||
* @param val A second number of this type.
|
||||
* @return The value of this/val
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(final BigSurd val) throws Errore
|
||||
{
|
||||
if( val.signum() == 0 )
|
||||
throw new ArithmeticException("Dividing "+ toFancyString() + " through zero.") ;
|
||||
return new BigSurd( pref.divide(val.pref), disc.divide(val.disc) ) ;
|
||||
} /* BigSurd.divide */
|
||||
/**
|
||||
* Multiply by an integer.
|
||||
*
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the product of this with the value.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final int val) {
|
||||
BigInteger tmp = new BigInteger("" + val);
|
||||
return multiply(tmp);
|
||||
} /* BigSurd.multiply */
|
||||
|
||||
private String toFancyString() {
|
||||
BigSurd bs = this;
|
||||
BigInteger denominator = pref.b;
|
||||
String s = "";
|
||||
if (denominator.compareTo(BigInteger.ONE) != 0) {
|
||||
/**
|
||||
* Compute the square.
|
||||
*
|
||||
* @return this value squared.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public Rational sqr() {
|
||||
Rational res = pref.pow(2);
|
||||
res = res.multiply(disc);
|
||||
return res;
|
||||
} /* BigSurd.sqr */
|
||||
|
||||
/**
|
||||
* Divide by another square root.
|
||||
*
|
||||
* @param val
|
||||
* A second number of this type.
|
||||
* @return The value of this/val
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(final BigSurd val) throws Errore {
|
||||
if (val.signum() == 0)
|
||||
throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
|
||||
return new BigSurd(pref.divide(val.pref), disc.divide(val.disc));
|
||||
} /* BigSurd.divide */
|
||||
|
||||
private String toFancyString() {
|
||||
BigSurd bs = this;
|
||||
BigInteger denominator = pref.b;
|
||||
String s = "";
|
||||
if (denominator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += "(";
|
||||
}
|
||||
if (bs.isBigInteger()) {
|
||||
s += bs.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)).toBigInteger().toString();
|
||||
} else if (bs.isRational()) {
|
||||
s += bs.toRational().toString();
|
||||
} else {
|
||||
BigInteger numerator = bs.pref.a;
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += numerator.toString();
|
||||
s += "*";
|
||||
s += "(";
|
||||
}
|
||||
if (bs.isBigInteger()) {
|
||||
s += bs.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)).toBigInteger().toString();
|
||||
} else if (bs.isRational()) {
|
||||
s += bs.toRational().toString();
|
||||
s += "2√";
|
||||
if (bs.disc.isInteger()) {
|
||||
s += bs.disc.toString();
|
||||
} else {
|
||||
BigInteger numerator = bs.pref.a;
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += numerator.toString();
|
||||
s += "*";
|
||||
s += "(";
|
||||
}
|
||||
s += "2√";
|
||||
if (bs.disc.isInteger()) {
|
||||
s += bs.disc.toString();
|
||||
} else {
|
||||
s += "("+bs.disc.toString()+")";
|
||||
}
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += ")";
|
||||
}
|
||||
s += "(" + bs.disc.toString() + ")";
|
||||
}
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += ")";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/** Divide by an integer.
|
||||
* @param val a second number.
|
||||
* @return the value of this/val
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(final BigInteger val) throws Errore
|
||||
{
|
||||
if( val.signum() == 0 )
|
||||
throw new ArithmeticException("Dividing "+ toFancyString() + " through zero.") ;
|
||||
return new BigSurd( pref.divide(val), disc ) ;
|
||||
} /* BigSurd.divide */
|
||||
/**
|
||||
* Divide by an integer.
|
||||
*
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the value of this/val
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(final BigInteger val) throws Errore {
|
||||
if (val.signum() == 0)
|
||||
throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
|
||||
return new BigSurd(pref.divide(val), disc);
|
||||
} /* BigSurd.divide */
|
||||
|
||||
/** Divide by an integer.
|
||||
* @param val A second number.
|
||||
* @return The value of this/val
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(int val) throws Errore
|
||||
{
|
||||
if( val == 0 )
|
||||
throw new ArithmeticException("Dividing "+ toFancyString() + " through zero.") ;
|
||||
return new BigSurd( pref.divide(val), disc ) ;
|
||||
} /* BigSurd.divide */
|
||||
/**
|
||||
* Divide by an integer.
|
||||
*
|
||||
* @param val
|
||||
* A second number.
|
||||
* @return The value of this/val
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(int val) throws Errore {
|
||||
if (val == 0)
|
||||
throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
|
||||
return new BigSurd(pref.divide(val), disc);
|
||||
} /* BigSurd.divide */
|
||||
|
||||
/** Compute the negative.
|
||||
* @return -this.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd negate()
|
||||
{
|
||||
/* This is trying to be quick, avoiding normalize(), by toggling
|
||||
* the sign in a clone()
|
||||
*/
|
||||
BigSurd n = clone() ;
|
||||
n.pref = n.pref.negate() ;
|
||||
return n ;
|
||||
} /* BigSurd.negate */
|
||||
/**
|
||||
* Compute the negative.
|
||||
*
|
||||
* @return -this.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd negate() {
|
||||
/*
|
||||
* This is trying to be quick, avoiding normalize(), by toggling
|
||||
* the sign in a clone()
|
||||
*/
|
||||
BigSurd n = clone();
|
||||
n.pref = n.pref.negate();
|
||||
return n;
|
||||
} /* BigSurd.negate */
|
||||
|
||||
/** Absolute value.
|
||||
* @return The absolute (non-negative) value of this.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd abs()
|
||||
{
|
||||
return new BigSurd(pref.abs(),disc) ;
|
||||
}
|
||||
/**
|
||||
* Absolute value.
|
||||
*
|
||||
* @return The absolute (non-negative) value of this.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd abs() {
|
||||
return new BigSurd(pref.abs(), disc);
|
||||
}
|
||||
|
||||
/** Compares the value of this with another constant.
|
||||
* @param val the other constant to compare with
|
||||
* @return -1, 0 or 1 if this number is numerically less than, equal to,
|
||||
* or greater than val.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public int compareTo(final BigSurd val)
|
||||
{
|
||||
/* Since we keep the discriminant positive, the rough estimate
|
||||
* comes from comparing the signs of the prefactors.
|
||||
*/
|
||||
final int sig = signum() ;
|
||||
final int sigv = val.signum() ;
|
||||
if ( sig < 0 && sigv >= 0 )
|
||||
return -1 ;
|
||||
if ( sig > 0 && sigv <= 0 )
|
||||
return 1 ;
|
||||
if ( sig == 0 && sigv == 0 )
|
||||
return 0 ;
|
||||
if ( sig == 0 && sigv > 0 )
|
||||
return -1 ;
|
||||
if ( sig == 0 && sigv < 0 )
|
||||
return 1 ;
|
||||
/**
|
||||
* Compares the value of this with another constant.
|
||||
*
|
||||
* @param val
|
||||
* the other constant to compare with
|
||||
* @return -1, 0 or 1 if this number is numerically less than, equal to,
|
||||
* or greater than val.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final BigSurd val) {
|
||||
/*
|
||||
* Since we keep the discriminant positive, the rough estimate
|
||||
* comes from comparing the signs of the prefactors.
|
||||
*/
|
||||
final int sig = signum();
|
||||
final int sigv = val.signum();
|
||||
if (sig < 0 && sigv >= 0)
|
||||
return -1;
|
||||
if (sig > 0 && sigv <= 0)
|
||||
return 1;
|
||||
if (sig == 0 && sigv == 0)
|
||||
return 0;
|
||||
if (sig == 0 && sigv > 0)
|
||||
return -1;
|
||||
if (sig == 0 && sigv < 0)
|
||||
return 1;
|
||||
|
||||
/* Work out the cases of equal sign. Compare absolute values by comparison
|
||||
* of the squares which is forwarded to the comparison of the Rational class.
|
||||
*/
|
||||
final Rational this2 = sqr() ;
|
||||
final Rational val2 = val.sqr() ;
|
||||
final int c = this2.compareTo(val2) ;
|
||||
if ( c == 0 )
|
||||
return 0 ;
|
||||
/* If both values have negative sign, the one with the smaller square is the larger number.
|
||||
*/
|
||||
else if ( sig >0 && c >0 || sig <0 && c <0 )
|
||||
return 1;
|
||||
else
|
||||
return -1 ;
|
||||
} /* BigSurd.compareTo */
|
||||
/*
|
||||
* Work out the cases of equal sign. Compare absolute values by
|
||||
* comparison
|
||||
* of the squares which is forwarded to the comparison of the Rational
|
||||
* class.
|
||||
*/
|
||||
final Rational this2 = sqr();
|
||||
final Rational val2 = val.sqr();
|
||||
final int c = this2.compareTo(val2);
|
||||
if (c == 0)
|
||||
return 0;
|
||||
/*
|
||||
* If both values have negative sign, the one with the smaller square is
|
||||
* the larger number.
|
||||
*/
|
||||
else if (sig > 0 && c > 0 || sig < 0 && c < 0)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
} /* BigSurd.compareTo */
|
||||
|
||||
/** Return a string in the format (number/denom)*()^(1/2).
|
||||
* If the discriminant equals 1, print just the prefactor.
|
||||
* @return the human-readable version in base 10
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
if ( disc.compareTo(Rational.ONE) != 0 && disc.compareTo(Rational.ZERO) != 0)
|
||||
return( "("+pref.toString()+")*("+disc.toString()+")^(1/2)" ) ;
|
||||
else
|
||||
return pref.toString() ;
|
||||
} /* BigSurd.toString */
|
||||
/**
|
||||
* Return a string in the format (number/denom)*()^(1/2).
|
||||
* If the discriminant equals 1, print just the prefactor.
|
||||
*
|
||||
* @return the human-readable version in base 10
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (disc.compareTo(Rational.ONE) != 0 && disc.compareTo(Rational.ZERO) != 0)
|
||||
return ("(" + pref.toString() + ")*(" + disc.toString() + ")^(1/2)");
|
||||
else
|
||||
return pref.toString();
|
||||
} /* BigSurd.toString */
|
||||
|
||||
/** Return a double value representation.
|
||||
* @return The value with double precision.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public double doubleValue()
|
||||
{
|
||||
/* First compute the square to prevent overflows if the two pieces of
|
||||
* the prefactor and the discriminant are of very different magnitude.
|
||||
*/
|
||||
Rational p2 = pref.pow(2).multiply(disc) ;
|
||||
System.out.println("dv sq " + p2.toString()) ;
|
||||
double res = p2.doubleValue() ;
|
||||
System.out.println("dv sq " + res) ;
|
||||
return (pref.signum() >= 0) ? Math.sqrt(res) : -Math.sqrt(res) ;
|
||||
} /* BigSurd.doubleValue */
|
||||
/**
|
||||
* Return a double value representation.
|
||||
*
|
||||
* @return The value with double precision.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public double doubleValue() {
|
||||
/*
|
||||
* First compute the square to prevent overflows if the two pieces of
|
||||
* the prefactor and the discriminant are of very different magnitude.
|
||||
*/
|
||||
Rational p2 = pref.pow(2).multiply(disc);
|
||||
System.out.println("dv sq " + p2.toString());
|
||||
double res = p2.doubleValue();
|
||||
System.out.println("dv sq " + res);
|
||||
return (pref.signum() >= 0) ? Math.sqrt(res) : -Math.sqrt(res);
|
||||
} /* BigSurd.doubleValue */
|
||||
|
||||
/** Return a float value representation.
|
||||
* @return The value with single precision.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public float floatValue()
|
||||
{
|
||||
return (float)(doubleValue()) ;
|
||||
} /* BigSurd.floatValue */
|
||||
/**
|
||||
* Return a float value representation.
|
||||
*
|
||||
* @return The value with single precision.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public float floatValue() {
|
||||
return (float) (doubleValue());
|
||||
} /* BigSurd.floatValue */
|
||||
|
||||
/** True if the value is integer.
|
||||
* Equivalent to the indication whether a conversion to an integer
|
||||
* can be exact.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public boolean isBigInteger()
|
||||
{
|
||||
return pref.isBigInteger() && ( disc.signum() ==0 || disc.compareTo(Rational.ONE) == 0 ) ;
|
||||
} /* BigSurd.isBigInteger */
|
||||
/**
|
||||
* True if the value is integer.
|
||||
* Equivalent to the indication whether a conversion to an integer
|
||||
* can be exact.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public boolean isBigInteger() {
|
||||
return pref.isBigInteger() && (disc.signum() == 0 || disc.compareTo(Rational.ONE) == 0);
|
||||
} /* BigSurd.isBigInteger */
|
||||
|
||||
/** True if the value is rational.
|
||||
* Equivalent to the indication whether a conversion to a Rational can be exact.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public boolean isRational()
|
||||
{
|
||||
return ( disc.signum() ==0 || disc.compareTo(Rational.ONE) == 0 ) ;
|
||||
} /* BigSurd.isRational */
|
||||
/**
|
||||
* True if the value is rational.
|
||||
* Equivalent to the indication whether a conversion to a Rational can be
|
||||
* exact.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public boolean isRational() {
|
||||
return (disc.signum() == 0 || disc.compareTo(Rational.ONE) == 0);
|
||||
} /* BigSurd.isRational */
|
||||
|
||||
/** Convert to a rational value if possible
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public Rational toRational()
|
||||
{
|
||||
if ( isRational() )
|
||||
return pref ;
|
||||
else
|
||||
throw new ArithmeticException("Undefined conversion "+ toFancyString() + " to Rational.") ;
|
||||
} /* BigSurd.toRational */
|
||||
/**
|
||||
* Convert to a rational value if possible
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public Rational toRational() {
|
||||
if (isRational())
|
||||
return pref;
|
||||
else
|
||||
throw new ArithmeticException("Undefined conversion " + toFancyString() + " to Rational.");
|
||||
} /* BigSurd.toRational */
|
||||
|
||||
/** The sign: 1 if the number is >0, 0 if ==0, -1 if <0
|
||||
* @return the signum of the value.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public int signum()
|
||||
{
|
||||
/* Since the disc is kept positive, this is the same
|
||||
* as the sign of the prefactor. This works because a zero discriminant
|
||||
* is always copied over to the prefactor, not hidden.
|
||||
*/
|
||||
return pref.signum() ;
|
||||
} /* BigSurd.signum */
|
||||
/**
|
||||
* The sign: 1 if the number is >0, 0 if ==0, -1 if <0
|
||||
*
|
||||
* @return the signum of the value.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public int signum() {
|
||||
/*
|
||||
* Since the disc is kept positive, this is the same
|
||||
* as the sign of the prefactor. This works because a zero discriminant
|
||||
* is always copied over to the prefactor, not hidden.
|
||||
*/
|
||||
return pref.signum();
|
||||
} /* BigSurd.signum */
|
||||
|
||||
/** Normalize to squarefree discriminant.
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
protected void normalize() throws Errore
|
||||
{
|
||||
/* Move squares out of the numerator and denominator of the discriminant
|
||||
*/
|
||||
if ( disc.signum() != 0 )
|
||||
{
|
||||
/* square-free part of the numerator: numer = numC*some^2
|
||||
*/
|
||||
BigInteger numC = BigIntegerMath.core(disc.numer()) ;
|
||||
/* extract the perfect square of the numerator
|
||||
*/
|
||||
BigInteger sq = disc.numer().divide(numC) ;
|
||||
/* extract the associated square root
|
||||
*/
|
||||
BigInteger sqf = BigIntegerMath.isqrt(sq) ;
|
||||
/**
|
||||
* Normalize to squarefree discriminant.
|
||||
*
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
protected void normalize() throws Errore {
|
||||
/*
|
||||
* Move squares out of the numerator and denominator of the discriminant
|
||||
*/
|
||||
if (disc.signum() != 0) {
|
||||
/*
|
||||
* square-free part of the numerator: numer = numC*some^2
|
||||
*/
|
||||
BigInteger numC = BigIntegerMath.core(disc.numer());
|
||||
/*
|
||||
* extract the perfect square of the numerator
|
||||
*/
|
||||
BigInteger sq = disc.numer().divide(numC);
|
||||
/*
|
||||
* extract the associated square root
|
||||
*/
|
||||
BigInteger sqf = BigIntegerMath.isqrt(sq);
|
||||
|
||||
/* move sqf over to the pre-factor
|
||||
*/
|
||||
pref = pref.multiply(sqf) ;
|
||||
/*
|
||||
* move sqf over to the pre-factor
|
||||
*/
|
||||
pref = pref.multiply(sqf);
|
||||
|
||||
BigInteger denC = BigIntegerMath.core(disc.denom()) ;
|
||||
sq = disc.denom().divide(denC) ;
|
||||
sqf = BigIntegerMath.isqrt(sq) ;
|
||||
pref = pref.divide(sqf) ;
|
||||
BigInteger denC = BigIntegerMath.core(disc.denom());
|
||||
sq = disc.denom().divide(denC);
|
||||
sqf = BigIntegerMath.isqrt(sq);
|
||||
pref = pref.divide(sqf);
|
||||
|
||||
disc = new Rational(numC,denC) ;
|
||||
}
|
||||
else
|
||||
pref = Rational.ZERO ;
|
||||
} /* BigSurd.normalize */
|
||||
|
||||
/** Normalize to coprime numerator and denominator in prefactor and discriminant
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
protected void normalizeG() throws Errore
|
||||
{
|
||||
/* Is there a common factor between the numerator of the prefactor
|
||||
* and the denominator of the discriminant ?
|
||||
*/
|
||||
BigInteger d = pref.numer().abs().gcd( disc.denom()) ;
|
||||
if ( d.compareTo(BigInteger.ONE) > 0 )
|
||||
{
|
||||
pref = pref.divide(d) ;
|
||||
/* instead of multiplying with the square of d, using two steps
|
||||
* offers a change to recognize the common factor..
|
||||
*/
|
||||
disc = disc.multiply(d) ;
|
||||
disc = disc.multiply(d) ;
|
||||
}
|
||||
/* Is there a common factor between the denominator of the prefactor
|
||||
* and the numerator of the discriminant ?
|
||||
*/
|
||||
d = pref.denom().gcd( disc.numer()) ;
|
||||
if ( d.compareTo(BigInteger.ONE) > 0 )
|
||||
{
|
||||
pref = pref.multiply(d) ;
|
||||
/* instead of dividing through the square of d, using two steps
|
||||
* offers a change to recognize the common factor..
|
||||
*/
|
||||
disc = disc.divide(d) ;
|
||||
disc = disc.divide(d) ;
|
||||
}
|
||||
} /* BigSurd.normalizeG */
|
||||
|
||||
/** Return the approximate floating point representation.
|
||||
* @param mc Description of the accuracy needed.
|
||||
* @return A representation with digits valid as described by mc
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigDecimal BigDecimalValue(MathContext mc)
|
||||
{
|
||||
/* the relative error of the result equals the relative error of the
|
||||
* prefactor plus half of the relative error of the discriminant.
|
||||
* So adding 3 digits temporarily is sufficient.
|
||||
*/
|
||||
final MathContext locmc = new MathContext(mc.getPrecision()+3,mc.getRoundingMode()) ;
|
||||
/* first the square root of the discriminant
|
||||
*/
|
||||
BigDecimal sqrdis = BigDecimalMath.sqrt(disc.BigDecimalValue(locmc),locmc ) ;
|
||||
/* Then multiply by the prefactor. If sqrdis is a terminating decimal fraction,
|
||||
* we prevent early truncation of the result by truncating later.
|
||||
*/
|
||||
BigDecimal res = sqrdis.multiply(pref.BigDecimalValue(mc)) ;
|
||||
return BigDecimalMath.scalePrec(res,mc) ;
|
||||
} /* BigDecimalValue */
|
||||
disc = new Rational(numC, denC);
|
||||
} else
|
||||
pref = Rational.ZERO;
|
||||
} /* BigSurd.normalize */
|
||||
|
||||
/**
|
||||
* Normalize to coprime numerator and denominator in prefactor and
|
||||
* discriminant
|
||||
*
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
protected void normalizeG() throws Errore {
|
||||
/*
|
||||
* Is there a common factor between the numerator of the prefactor
|
||||
* and the denominator of the discriminant ?
|
||||
*/
|
||||
BigInteger d = pref.numer().abs().gcd(disc.denom());
|
||||
if (d.compareTo(BigInteger.ONE) > 0) {
|
||||
pref = pref.divide(d);
|
||||
/*
|
||||
* instead of multiplying with the square of d, using two steps
|
||||
* offers a change to recognize the common factor..
|
||||
*/
|
||||
disc = disc.multiply(d);
|
||||
disc = disc.multiply(d);
|
||||
}
|
||||
/*
|
||||
* Is there a common factor between the denominator of the prefactor
|
||||
* and the numerator of the discriminant ?
|
||||
*/
|
||||
d = pref.denom().gcd(disc.numer());
|
||||
if (d.compareTo(BigInteger.ONE) > 0) {
|
||||
pref = pref.multiply(d);
|
||||
/*
|
||||
* instead of dividing through the square of d, using two steps
|
||||
* offers a change to recognize the common factor..
|
||||
*/
|
||||
disc = disc.divide(d);
|
||||
disc = disc.divide(d);
|
||||
}
|
||||
} /* BigSurd.normalizeG */
|
||||
|
||||
/**
|
||||
* Return the approximate floating point representation.
|
||||
*
|
||||
* @param mc
|
||||
* Description of the accuracy needed.
|
||||
* @return A representation with digits valid as described by mc
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigDecimal BigDecimalValue(MathContext mc) {
|
||||
/*
|
||||
* the relative error of the result equals the relative error of the
|
||||
* prefactor plus half of the relative error of the discriminant.
|
||||
* So adding 3 digits temporarily is sufficient.
|
||||
*/
|
||||
final MathContext locmc = new MathContext(mc.getPrecision() + 3, mc.getRoundingMode());
|
||||
/*
|
||||
* first the square root of the discriminant
|
||||
*/
|
||||
BigDecimal sqrdis = BigDecimalMath.sqrt(disc.BigDecimalValue(locmc), locmc);
|
||||
/*
|
||||
* Then multiply by the prefactor. If sqrdis is a terminating decimal
|
||||
* fraction,
|
||||
* we prevent early truncation of the result by truncating later.
|
||||
*/
|
||||
BigDecimal res = sqrdis.multiply(pref.BigDecimalValue(mc));
|
||||
return BigDecimalMath.scalePrec(res, mc);
|
||||
} /* BigDecimalValue */
|
||||
|
||||
} /* BigSurd */
|
||||
|
||||
|
@ -5,8 +5,8 @@ import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.warpgate.pi.calculator.Errore;
|
||||
import org.warpgate.pi.calculator.Utils;
|
||||
import org.warp.picalculator.Errore;
|
||||
import org.warp.picalculator.Utils;
|
||||
|
||||
/**
|
||||
* A BigSurdVec represents an algebraic sum or differences of values which each
|
||||
@ -78,7 +78,8 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
/**
|
||||
* Combine terms that can be written as a single surd. This unites for
|
||||
* example the terms sqrt(90) and sqrt(10) to 4*sqrt(10).
|
||||
* @throws Errore
|
||||
*
|
||||
* @throws Errore
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
@ -141,6 +142,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @return 0 or +-1.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(BigSurdVec oth) {
|
||||
BigSurdVec diff;
|
||||
try {
|
||||
@ -158,7 +160,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* equal to or larger than zero.
|
||||
*
|
||||
* @return 0 or +-1.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public int signum() throws Errore {
|
||||
@ -209,12 +211,14 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
else
|
||||
lhs = new BigSurdVec(terms.elementAt(0), terms.elementAt(2));
|
||||
lhs = lhs.sqr();
|
||||
/*
|
||||
* Strange line: this line isn't used, but it's present in this code!
|
||||
/*
|
||||
* Strange line: this line isn't used, but it's present in this
|
||||
* code!
|
||||
*
|
||||
*
|
||||
*
|
||||
BigSurd rhs = new BigSurd(terms.elementAt(offsig).sqr(), Rational.ONE);
|
||||
* BigSurd rhs = new BigSurd(terms.elementAt(offsig).sqr(),
|
||||
* Rational.ONE);
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -304,7 +308,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @param val
|
||||
* The value to be added to this.
|
||||
* @return The new value representing this+val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public BigSurdVec add(final BigSurdVec val) throws Errore {
|
||||
BigSurdVec sum = new BigSurdVec();
|
||||
@ -331,7 +335,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @param val
|
||||
* The value to be added to this.
|
||||
* @return The new value representing this+val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public BigSurdVec add(final BigSurd val) throws Errore {
|
||||
BigSurdVec sum = new BigSurdVec();
|
||||
@ -350,7 +354,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @param val
|
||||
* The value to be subtracted from this.
|
||||
* @return The new value representing this-val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public BigSurdVec subtract(final BigSurdVec val) throws Errore {
|
||||
BigSurdVec sum = new BigSurdVec();
|
||||
@ -370,7 +374,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @param val
|
||||
* The value to be subtracted from this.
|
||||
* @return The new value representing this-val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public BigSurdVec subtract(final BigSurd val) throws Errore {
|
||||
BigSurdVec sum = new BigSurdVec();
|
||||
@ -407,7 +411,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* Compute the square.
|
||||
*
|
||||
* @return this value squared.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigSurdVec sqr() throws Errore {
|
||||
@ -431,7 +435,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @param val
|
||||
* a second number of this type.
|
||||
* @return the product of this with the val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurdVec multiply(final BigSurd val) throws Errore {
|
||||
@ -554,6 +558,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @return the human-readable version in base 10
|
||||
* @since 2012-02-16
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
/*
|
||||
* simple cases with one term forwarded to the BigSurd class
|
||||
@ -597,16 +602,16 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += numerator.toString();
|
||||
s += "*";
|
||||
//s += "("; Radice quadrata. non servono le parentesi.
|
||||
// s += "("; Radice quadrata. non servono le parentesi.
|
||||
}
|
||||
s += "Ⓐ";
|
||||
if (bs.disc.isInteger()) {
|
||||
s += bs.disc.toString();
|
||||
} else {
|
||||
s += "("+bs.disc.toString()+")";
|
||||
s += "(" + bs.disc.toString() + ")";
|
||||
}
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
//s += ")"; Radice quadrata. non servono le parentesi.
|
||||
// s += ")"; Radice quadrata. non servono le parentesi.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,69 +1,71 @@
|
||||
package org.nevec.rjm ;
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
/** Euler numbers
|
||||
* @see <a href="http://oeis.org/A000364">A000364</a> in the OEIS.
|
||||
* @since 2008-10-30
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Euler
|
||||
{
|
||||
/*
|
||||
* The list of all Euler numbers as a vector, n=0,2,4,....
|
||||
*/
|
||||
static protected Vector<BigInteger> a = new Vector<BigInteger>() ;
|
||||
/**
|
||||
* Euler numbers
|
||||
*
|
||||
* @see <a href="http://oeis.org/A000364">A000364</a> in the OEIS.
|
||||
* @since 2008-10-30
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Euler {
|
||||
/*
|
||||
* The list of all Euler numbers as a vector, n=0,2,4,....
|
||||
*/
|
||||
static protected Vector<BigInteger> a = new Vector<BigInteger>();
|
||||
|
||||
/** Ctor(). Fill the hash list initially with E_0 to E_3.
|
||||
*/
|
||||
public Euler()
|
||||
{
|
||||
if ( a.size() == 0 )
|
||||
{
|
||||
a.add(BigInteger.ONE) ;
|
||||
a.add(BigInteger.ONE) ;
|
||||
a.add(new BigInteger("5")) ;
|
||||
a.add(new BigInteger("61")) ;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ctor(). Fill the hash list initially with E_0 to E_3.
|
||||
*/
|
||||
public Euler() {
|
||||
if (a.size() == 0) {
|
||||
a.add(BigInteger.ONE);
|
||||
a.add(BigInteger.ONE);
|
||||
a.add(new BigInteger("5"));
|
||||
a.add(new BigInteger("61"));
|
||||
}
|
||||
}
|
||||
|
||||
/** Compute a coefficient in the internal table.
|
||||
* @param n the zero-based index of the coefficient. n=0 for the E_0 term.
|
||||
*/
|
||||
protected void set(final int n)
|
||||
{
|
||||
while ( n >= a.size())
|
||||
{
|
||||
BigInteger val = BigInteger.ZERO ;
|
||||
boolean sigPos = true;
|
||||
int thisn = a.size() ;
|
||||
for(int i= thisn-1 ; i > 0 ; i--)
|
||||
{
|
||||
BigInteger f = new BigInteger(""+ a.elementAt(i).toString() ) ;
|
||||
f = f.multiply( BigIntegerMath.binomial(2*thisn,2*i) );
|
||||
if ( sigPos )
|
||||
val = val.add(f) ;
|
||||
else
|
||||
val = val.subtract(f) ;
|
||||
sigPos = ! sigPos ;
|
||||
}
|
||||
if ( thisn % 2 ==0 )
|
||||
val = val.subtract(BigInteger.ONE) ;
|
||||
else
|
||||
val = val.add(BigInteger.ONE) ;
|
||||
a.add(val) ;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Compute a coefficient in the internal table.
|
||||
*
|
||||
* @param n
|
||||
* the zero-based index of the coefficient. n=0 for the E_0 term.
|
||||
*/
|
||||
protected void set(final int n) {
|
||||
while (n >= a.size()) {
|
||||
BigInteger val = BigInteger.ZERO;
|
||||
boolean sigPos = true;
|
||||
int thisn = a.size();
|
||||
for (int i = thisn - 1; i > 0; i--) {
|
||||
BigInteger f = new BigInteger("" + a.elementAt(i).toString());
|
||||
f = f.multiply(BigIntegerMath.binomial(2 * thisn, 2 * i));
|
||||
if (sigPos)
|
||||
val = val.add(f);
|
||||
else
|
||||
val = val.subtract(f);
|
||||
sigPos = !sigPos;
|
||||
}
|
||||
if (thisn % 2 == 0)
|
||||
val = val.subtract(BigInteger.ONE);
|
||||
else
|
||||
val = val.add(BigInteger.ONE);
|
||||
a.add(val);
|
||||
}
|
||||
}
|
||||
|
||||
/** The Euler number at the index provided.
|
||||
* @param n the index, non-negative.
|
||||
* @return the E_0=E_1=1 , E_2=5, E_3=61 etc
|
||||
*/
|
||||
public BigInteger at(int n)
|
||||
{
|
||||
set(n) ;
|
||||
return(a.elementAt(n)) ;
|
||||
}
|
||||
/**
|
||||
* The Euler number at the index provided.
|
||||
*
|
||||
* @param n
|
||||
* the index, non-negative.
|
||||
* @return the E_0=E_1=1 , E_2=5, E_3=61 etc
|
||||
*/
|
||||
public BigInteger at(int n) {
|
||||
set(n);
|
||||
return (a.elementAt(n));
|
||||
}
|
||||
|
||||
} /* Euler */
|
||||
|
@ -1,60 +1,64 @@
|
||||
package org.nevec.rjm ;
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/** Euler totient function.
|
||||
* @see <a href="http://oeis.org/A000010">A000010</a> in the OEIS.
|
||||
* @since 2008-10-14
|
||||
* @since 2012-03-04 Adapted to new Ifactor representation.
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class EulerPhi
|
||||
{
|
||||
/** Default constructor.
|
||||
* Does nothing().
|
||||
*/
|
||||
public EulerPhi()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Euler totient function.
|
||||
*
|
||||
* @see <a href="http://oeis.org/A000010">A000010</a> in the OEIS.
|
||||
* @since 2008-10-14
|
||||
* @since 2012-03-04 Adapted to new Ifactor representation.
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class EulerPhi {
|
||||
/**
|
||||
* Default constructor.
|
||||
* Does nothing().
|
||||
*/
|
||||
public EulerPhi() {}
|
||||
|
||||
/** Compute phi(n).
|
||||
* @param n The positive argument of the function.
|
||||
* @return phi(n)
|
||||
*/
|
||||
public BigInteger at(int n)
|
||||
{
|
||||
return at(new BigInteger(""+n) ) ;
|
||||
} /* at */
|
||||
/**
|
||||
* Compute phi(n).
|
||||
*
|
||||
* @param n
|
||||
* The positive argument of the function.
|
||||
* @return phi(n)
|
||||
*/
|
||||
public BigInteger at(int n) {
|
||||
return at(new BigInteger("" + n));
|
||||
} /* at */
|
||||
|
||||
/** Compute phi(n).
|
||||
* @param n The positive argument of the function.
|
||||
* @return phi(n)
|
||||
*/
|
||||
public BigInteger at(BigInteger n)
|
||||
{
|
||||
if ( n.compareTo(BigInteger.ZERO) <= 0 )
|
||||
throw new ArithmeticException("negative argument "+n+ " of EulerPhi") ;
|
||||
Ifactor prFact = new Ifactor(n) ;
|
||||
BigInteger phi = n ;
|
||||
if ( n.compareTo(BigInteger.ONE) > 0 )
|
||||
for(int i=0 ; i < prFact.primeexp.size() ; i += 2)
|
||||
{
|
||||
BigInteger p = new BigInteger(prFact.primeexp.elementAt(i).toString()) ;
|
||||
BigInteger p_1 = p.subtract(BigInteger.ONE) ;
|
||||
phi = phi.multiply(p_1).divide(p) ;
|
||||
}
|
||||
return phi ;
|
||||
} /* at */
|
||||
/**
|
||||
* Compute phi(n).
|
||||
*
|
||||
* @param n
|
||||
* The positive argument of the function.
|
||||
* @return phi(n)
|
||||
*/
|
||||
public BigInteger at(BigInteger n) {
|
||||
if (n.compareTo(BigInteger.ZERO) <= 0)
|
||||
throw new ArithmeticException("negative argument " + n + " of EulerPhi");
|
||||
Ifactor prFact = new Ifactor(n);
|
||||
BigInteger phi = n;
|
||||
if (n.compareTo(BigInteger.ONE) > 0)
|
||||
for (int i = 0; i < prFact.primeexp.size(); i += 2) {
|
||||
BigInteger p = new BigInteger(prFact.primeexp.elementAt(i).toString());
|
||||
BigInteger p_1 = p.subtract(BigInteger.ONE);
|
||||
phi = phi.multiply(p_1).divide(p);
|
||||
}
|
||||
return phi;
|
||||
} /* at */
|
||||
|
||||
/** Test program.
|
||||
* It takes one argument n and prints the value phi(n).<br>
|
||||
* java -cp . org.nevec.rjm.EulerPhi n<br>
|
||||
* @since 2006-08-14
|
||||
*/
|
||||
public static void main(String[] args) throws ArithmeticException
|
||||
{
|
||||
EulerPhi a = new EulerPhi() ;
|
||||
int n = (new Integer(args[0])).intValue() ;
|
||||
System.out.println("phi("+ n + ") = " + a.at(n)) ;
|
||||
}
|
||||
/**
|
||||
* Test program.
|
||||
* It takes one argument n and prints the value phi(n).<br>
|
||||
* java -cp . org.nevec.rjm.EulerPhi n<br>
|
||||
*
|
||||
* @since 2006-08-14
|
||||
*/
|
||||
public static void main(String[] args) throws ArithmeticException {
|
||||
EulerPhi a = new EulerPhi();
|
||||
int n = (new Integer(args[0])).intValue();
|
||||
System.out.println("phi(" + n + ") = " + a.at(n));
|
||||
}
|
||||
} /* EulerPhi */
|
||||
|
@ -1,70 +1,79 @@
|
||||
package org.nevec.rjm ;
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Factorials.
|
||||
*
|
||||
* @since 2006-06-25
|
||||
* @since 2012-02-15 Storage of the values based on Ifactor, not BigInteger.
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Factorial {
|
||||
/**
|
||||
* The list of all factorials as a vector.
|
||||
*/
|
||||
static Vector<Ifactor> a = new Vector<Ifactor>();
|
||||
|
||||
/** Factorials.
|
||||
* @since 2006-06-25
|
||||
* @since 2012-02-15 Storage of the values based on Ifactor, not BigInteger.
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Factorial
|
||||
{
|
||||
/** The list of all factorials as a vector.
|
||||
*/
|
||||
static Vector<Ifactor> a = new Vector<Ifactor>() ;
|
||||
/**
|
||||
* ctor().
|
||||
* Initialize the vector of the factorials with 0!=1 and 1!=1.
|
||||
*/
|
||||
public Factorial() {
|
||||
if (a.size() == 0) {
|
||||
a.add(Ifactor.ONE);
|
||||
a.add(Ifactor.ONE);
|
||||
}
|
||||
} /* ctor */
|
||||
|
||||
/** ctor().
|
||||
* Initialize the vector of the factorials with 0!=1 and 1!=1.
|
||||
*/
|
||||
public Factorial()
|
||||
{
|
||||
if ( a.size() == 0 )
|
||||
{
|
||||
a.add(Ifactor.ONE) ;
|
||||
a.add(Ifactor.ONE) ;
|
||||
}
|
||||
} /* ctor */
|
||||
/**
|
||||
* Compute the factorial of the non-negative integer.
|
||||
*
|
||||
* @param n
|
||||
* the argument to the factorial, non-negative.
|
||||
* @return the factorial of n.
|
||||
*/
|
||||
public BigInteger at(int n) {
|
||||
/*
|
||||
* extend the internal list if needed.
|
||||
*/
|
||||
growto(n);
|
||||
return a.elementAt(n).n;
|
||||
} /* at */
|
||||
|
||||
/** Compute the factorial of the non-negative integer.
|
||||
* @param n the argument to the factorial, non-negative.
|
||||
* @return the factorial of n.
|
||||
*/
|
||||
public BigInteger at(int n)
|
||||
{
|
||||
/* extend the internal list if needed.
|
||||
*/
|
||||
growto(n) ;
|
||||
return a.elementAt(n).n ;
|
||||
} /* at */
|
||||
/**
|
||||
* Compute the factorial of the non-negative integer.
|
||||
*
|
||||
* @param n
|
||||
* the argument to the factorial, non-negative.
|
||||
* @return the factorial of n.
|
||||
*/
|
||||
public Ifactor toIfactor(int n) {
|
||||
/*
|
||||
* extend the internal list if needed.
|
||||
*/
|
||||
growto(n);
|
||||
return a.elementAt(n);
|
||||
} /* at */
|
||||
|
||||
/** Compute the factorial of the non-negative integer.
|
||||
* @param n the argument to the factorial, non-negative.
|
||||
* @return the factorial of n.
|
||||
*/
|
||||
public Ifactor toIfactor(int n)
|
||||
{
|
||||
/* extend the internal list if needed.
|
||||
*/
|
||||
growto(n) ;
|
||||
return a.elementAt(n) ;
|
||||
} /* at */
|
||||
|
||||
/** Extend the internal table to cover up to n!
|
||||
* @param n The maximum factorial to be supported.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
private void growto(int n)
|
||||
{
|
||||
/* extend the internal list if needed. Size to be 2 for n<=1, 3 for n<=2 etc.
|
||||
*/
|
||||
while ( a.size() <=n )
|
||||
{
|
||||
final int lastn = a.size()-1 ;
|
||||
final Ifactor nextn = new Ifactor(lastn+1) ;
|
||||
a.add(a.elementAt(lastn).multiply(nextn) ) ;
|
||||
}
|
||||
} /* growto */
|
||||
/**
|
||||
* Extend the internal table to cover up to n!
|
||||
*
|
||||
* @param n
|
||||
* The maximum factorial to be supported.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
private void growto(int n) {
|
||||
/*
|
||||
* extend the internal list if needed. Size to be 2 for n<=1, 3 for n<=2
|
||||
* etc.
|
||||
*/
|
||||
while (a.size() <= n) {
|
||||
final int lastn = a.size() - 1;
|
||||
final Ifactor nextn = new Ifactor(lastn + 1);
|
||||
a.add(a.elementAt(lastn).multiply(nextn));
|
||||
}
|
||||
} /* growto */
|
||||
|
||||
} /* Factorial */
|
||||
|
@ -1,39 +1,42 @@
|
||||
package org.nevec.rjm ;
|
||||
package org.nevec.rjm;
|
||||
|
||||
/** Harmonic numbers.
|
||||
* H(n) is the sum of the inverses of the integers from 1 to n.
|
||||
* @since 2008-10-19
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Harmonic
|
||||
{
|
||||
/** ctor()
|
||||
* Does nothing.
|
||||
*/
|
||||
public Harmonic()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Harmonic numbers.
|
||||
* H(n) is the sum of the inverses of the integers from 1 to n.
|
||||
*
|
||||
* @since 2008-10-19
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Harmonic {
|
||||
/**
|
||||
* ctor()
|
||||
* Does nothing.
|
||||
*/
|
||||
public Harmonic() {}
|
||||
|
||||
/** The Harmonic number at the index specified
|
||||
* @param n the index, non-negative.
|
||||
* @return the H_1=1 for n=1, H_2=3/2 for n=2 etc.
|
||||
* For values of n less than 1, zero is returned.
|
||||
*/
|
||||
public Rational at(int n)
|
||||
{
|
||||
if ( n < 1)
|
||||
return(new Rational(0,1)) ;
|
||||
else
|
||||
{
|
||||
/* start with 1 as the result
|
||||
*/
|
||||
Rational a = new Rational(1,1) ;
|
||||
/**
|
||||
* The Harmonic number at the index specified
|
||||
*
|
||||
* @param n
|
||||
* the index, non-negative.
|
||||
* @return the H_1=1 for n=1, H_2=3/2 for n=2 etc.
|
||||
* For values of n less than 1, zero is returned.
|
||||
*/
|
||||
public Rational at(int n) {
|
||||
if (n < 1)
|
||||
return (new Rational(0, 1));
|
||||
else {
|
||||
/*
|
||||
* start with 1 as the result
|
||||
*/
|
||||
Rational a = new Rational(1, 1);
|
||||
|
||||
/* add 1/i for i=2..n
|
||||
*/
|
||||
for( int i=2 ; i <=n ; i++)
|
||||
a = a.add(new Rational(1,i)) ;
|
||||
return a ;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* add 1/i for i=2..n
|
||||
*/
|
||||
for (int i = 2; i <= n; i++)
|
||||
a = a.add(new Rational(1, i));
|
||||
return a;
|
||||
}
|
||||
}
|
||||
} /* Harmonic */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,10 +5,8 @@ import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.security.ProviderException;
|
||||
|
||||
import org.warpgate.pi.calculator.Errore;
|
||||
import org.warpgate.pi.calculator.Incognita;
|
||||
import org.warpgate.pi.calculator.Incognite;
|
||||
import org.warpgate.pi.calculator.Utils;
|
||||
import org.warp.picalculator.Errore;
|
||||
import org.warp.picalculator.Incognite;
|
||||
|
||||
/**
|
||||
* Square roots on the real line. These represent numbers which are a product of
|
||||
@ -67,7 +65,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
* the prefactor.
|
||||
* @param b
|
||||
* the discriminant.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public NumeroAvanzato(Rational a, Rational b) {
|
||||
@ -83,7 +81,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
incognitez = new Incognite();
|
||||
try {
|
||||
normalize();
|
||||
normalizeG();
|
||||
normalizeG();
|
||||
} catch (Errore e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -101,7 +99,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
incognitey = y;
|
||||
incognitez = z;
|
||||
try {
|
||||
normalize();
|
||||
normalize();
|
||||
normalizeG();
|
||||
} catch (Errore e) {
|
||||
e.printStackTrace();
|
||||
@ -143,6 +141,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@Override
|
||||
public NumeroAvanzato clone() {
|
||||
Rational fclon = pref.clone();
|
||||
Rational dclon = disc.clone();
|
||||
@ -190,8 +189,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public NumeroAvanzato multiply(final NumeroAvanzato val) {
|
||||
return new NumeroAvanzato(pref.multiply(val.pref), disc.multiply(val.disc), incognitex.multiply(val.incognitex),
|
||||
incognitey.multiply(val.incognitey), incognitez.multiply(val.incognitez));
|
||||
return new NumeroAvanzato(pref.multiply(val.pref), disc.multiply(val.disc), incognitex.multiply(val.incognitex), incognitey.multiply(val.incognitey), incognitez.multiply(val.incognitez));
|
||||
} /* NumeroAvanzato.multiply */
|
||||
|
||||
/**
|
||||
@ -235,7 +233,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
* Compute the square.
|
||||
*
|
||||
* @return this value squared.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public NumeroAvanzato pow2() throws Errore {
|
||||
@ -259,7 +257,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
* @param val
|
||||
* A second number of this type.
|
||||
* @return The value of this/val
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public NumeroAvanzato divide(final NumeroAvanzato val) throws Errore {
|
||||
@ -283,7 +281,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the value of this/val
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public NumeroAvanzato divide(final BigInteger val) throws Errore {
|
||||
@ -298,7 +296,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
* @param val
|
||||
* A second number.
|
||||
* @return The value of this/val
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public NumeroAvanzato divide(int val) throws Errore {
|
||||
@ -340,7 +338,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
* the other constant to compare with
|
||||
* @return -1, 0 or 1 if this number is numerically less than, equal to, or
|
||||
* greater than val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public int signumComparedTo(final NumeroAvanzato val) throws Errore {
|
||||
@ -388,6 +386,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
* @return the human-readable version in base 10
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return toFancyString();
|
||||
@ -396,11 +395,12 @@ public class NumeroAvanzato implements Cloneable {
|
||||
e.printStackTrace();
|
||||
}
|
||||
/*
|
||||
if (disc.compareTo(Rational.ONE) != 0 && disc.compareTo(Rational.ZERO) != 0)
|
||||
return ("(" + pref.toString() + ")*(" + disc.toString() + ")^(1/2)");
|
||||
else
|
||||
return pref.toString();
|
||||
*/
|
||||
* if (disc.compareTo(Rational.ONE) != 0 &&
|
||||
* disc.compareTo(Rational.ZERO) != 0)
|
||||
* return ("(" + pref.toString() + ")*(" + disc.toString() + ")^(1/2)");
|
||||
* else
|
||||
* return pref.toString();
|
||||
*/
|
||||
return "err";
|
||||
} /* NumeroAvanzato.toString */
|
||||
|
||||
@ -435,7 +435,8 @@ public class NumeroAvanzato implements Cloneable {
|
||||
/**
|
||||
* True if the value is integer. Equivalent to the indication whether a
|
||||
* conversion to an integer can be exact.
|
||||
* @param hasBigIntegerVariables
|
||||
*
|
||||
* @param hasBigIntegerVariables
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@ -464,16 +465,16 @@ public class NumeroAvanzato implements Cloneable {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.pref.b.compareTo(new BigInteger("10000")) > 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
} /* NumeroAvanzato.isRational */
|
||||
|
||||
|
||||
public boolean isTooPreciseRational(boolean hasRationalVariables) {
|
||||
if (disc.signum() == 0 || disc.compareTo(new Rational(1, 1)) == 0) {
|
||||
if (incognitex.count() > 0) {
|
||||
@ -483,7 +484,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.pref.b.compareTo(new BigInteger("10000")) > 0) {
|
||||
return true;
|
||||
}
|
||||
@ -494,7 +495,8 @@ public class NumeroAvanzato implements Cloneable {
|
||||
|
||||
/**
|
||||
* Convert to a rational value if possible
|
||||
* @throws Errore
|
||||
*
|
||||
* @throws Errore
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
@ -511,7 +513,7 @@ public class NumeroAvanzato implements Cloneable {
|
||||
else
|
||||
throw new ArithmeticException("Undefined conversion " + toFancyString() + " to Rational.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The sign: 1 if the number is >0, 0 if ==0, -1 if <0
|
||||
*
|
||||
@ -529,7 +531,8 @@ public class NumeroAvanzato implements Cloneable {
|
||||
|
||||
/**
|
||||
* Normalize to squarefree discriminant.
|
||||
* @throws Errore
|
||||
*
|
||||
* @throws Errore
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@ -567,23 +570,23 @@ public class NumeroAvanzato implements Cloneable {
|
||||
}
|
||||
|
||||
disc = new Rational(numC, denC);
|
||||
|
||||
|
||||
if (disc.b.compareTo(BigInteger.ZERO) == 0 || disc.a.compareTo(BigInteger.ZERO) == 0 || pref.a.compareTo(BigInteger.ZERO) == 0) {
|
||||
incognitex = new Incognite();
|
||||
incognitey = new Incognite();
|
||||
}
|
||||
|
||||
|
||||
if (disc.b.compareTo(BigInteger.ZERO) == 0 || pref.b.compareTo(BigInteger.ZERO) == 0) {
|
||||
incognitez = new Incognite();
|
||||
}
|
||||
|
||||
|
||||
if (incognitey.compareTo(incognitez)) {
|
||||
incognitey = new Incognite();
|
||||
incognitez = new Incognite();
|
||||
}
|
||||
|
||||
|
||||
/**/
|
||||
Incognite[] incognitetemp = new Incognite[]{incognitex, incognitey, incognitez};
|
||||
Incognite[] incognitetemp = new Incognite[] { incognitex, incognitey, incognitez };
|
||||
incognitetemp = Incognite.normalizeBigSurdVariables(incognitetemp);
|
||||
incognitex = incognitetemp[0];
|
||||
incognitey = incognitetemp[1];
|
||||
@ -600,7 +603,8 @@ public class NumeroAvanzato implements Cloneable {
|
||||
/**
|
||||
* Normalize to coprime numerator and denominator in prefactor and
|
||||
* discriminant
|
||||
* @throws Errore
|
||||
*
|
||||
* @throws Errore
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
|
@ -6,15 +6,17 @@ import java.math.MathContext;
|
||||
import java.util.Comparator;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.warpgate.pi.calculator.Errore;
|
||||
import org.warpgate.pi.calculator.Incognita;
|
||||
import org.warpgate.pi.calculator.Incognite;
|
||||
import org.warpgate.pi.calculator.Utils;
|
||||
import org.warp.picalculator.Errore;
|
||||
import org.warp.picalculator.Incognite;
|
||||
import org.warp.picalculator.Utils;
|
||||
|
||||
/**
|
||||
* A NumeroAvanzatoVec represents an algebraic sum or differences of values which each
|
||||
* term an instance of NumeroAvanzato. This mainly means that sums or differences of
|
||||
* two NumeroAvanzato (or two NumeroAvanzatoVec) can be represented (exactly) as a NumeroAvanzatoVec.
|
||||
* A NumeroAvanzatoVec represents an algebraic sum or differences of values
|
||||
* which each
|
||||
* term an instance of NumeroAvanzato. This mainly means that sums or
|
||||
* differences of
|
||||
* two NumeroAvanzato (or two NumeroAvanzatoVec) can be represented (exactly) as
|
||||
* a NumeroAvanzatoVec.
|
||||
*
|
||||
* @since 2012-02-15
|
||||
* @author Richard J. Mathar
|
||||
@ -31,7 +33,8 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
public static final NumeroAvanzatoVec ONE = new NumeroAvanzatoVec(NumeroAvanzato.ONE);
|
||||
|
||||
/**
|
||||
* Internal representation: Each term as a single NumeroAvanzato. The value zero is
|
||||
* Internal representation: Each term as a single NumeroAvanzato. The value
|
||||
* zero is
|
||||
* represented by an empty vector.
|
||||
*/
|
||||
Vector<NumeroAvanzato> terms;
|
||||
@ -80,7 +83,8 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
/**
|
||||
* Combine terms that can be written as a single surd. This unites for
|
||||
* example the terms sqrt(90) and sqrt(10) to 4*sqrt(10).
|
||||
* @throws Errore
|
||||
*
|
||||
* @throws Errore
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
@ -129,15 +133,15 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
if (!merged)
|
||||
newter.add(todo);
|
||||
}
|
||||
|
||||
|
||||
newter.sort(new Comparator<NumeroAvanzato>() {
|
||||
@Override
|
||||
public int compare(NumeroAvanzato o1, NumeroAvanzato o2) {
|
||||
int index1 = Incognite.priorità(o1.getIncognitex().sqrt().multiply(o1.getIncognitey()).divide(o1.getIncognitez()));
|
||||
int index2 = Incognite.priorità(o2.getIncognitex().sqrt().multiply(o2.getIncognitey()).divide(o2.getIncognitez()));
|
||||
return index2-index1;
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public int compare(NumeroAvanzato o1, NumeroAvanzato o2) {
|
||||
int index1 = Incognite.priorità(o1.getIncognitex().sqrt().multiply(o1.getIncognitey()).divide(o1.getIncognitez()));
|
||||
int index2 = Incognite.priorità(o2.getIncognitex().sqrt().multiply(o2.getIncognitey()).divide(o2.getIncognitez()));
|
||||
return index2 - index1;
|
||||
}
|
||||
});
|
||||
|
||||
/* overwrite old version */
|
||||
terms = newter;
|
||||
@ -152,6 +156,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
* @return 0 or +-1.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(NumeroAvanzatoVec oth) {
|
||||
NumeroAvanzatoVec diff;
|
||||
try {
|
||||
@ -168,7 +173,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
* equal to or larger than zero.
|
||||
*
|
||||
* @return 0 or +-1.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public int signum() throws Errore {
|
||||
@ -180,7 +185,8 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* if there is one term: forward to the signum function of NumeroAvanzato
|
||||
* if there is one term: forward to the signum function of
|
||||
* NumeroAvanzato
|
||||
*/
|
||||
if (terms.size() == 1)
|
||||
return terms.firstElement().signum();
|
||||
@ -219,12 +225,14 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
else
|
||||
lhs = new NumeroAvanzatoVec(terms.elementAt(0), terms.elementAt(2));
|
||||
lhs = lhs.sqr();
|
||||
/*
|
||||
* Strange line: this line isn't used, but it's present in this code!
|
||||
/*
|
||||
* Strange line: this line isn't used, but it's present in this
|
||||
* code!
|
||||
*
|
||||
*
|
||||
*
|
||||
NumeroAvanzato rhs = new NumeroAvanzato(terms.elementAt(offsig).sqr(), Rational.ONE);
|
||||
* NumeroAvanzato rhs = new
|
||||
* NumeroAvanzato(terms.elementAt(offsig).sqr(), Rational.ONE);
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -317,7 +325,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
* @param val
|
||||
* The value to be added to this.
|
||||
* @return The new value representing this+val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public NumeroAvanzatoVec add(final NumeroAvanzatoVec val) throws Errore {
|
||||
NumeroAvanzatoVec sum = new NumeroAvanzatoVec();
|
||||
@ -344,7 +352,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
* @param val
|
||||
* The value to be added to this.
|
||||
* @return The new value representing this+val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public NumeroAvanzatoVec add(final NumeroAvanzato val) throws Errore {
|
||||
NumeroAvanzatoVec sum = new NumeroAvanzatoVec();
|
||||
@ -363,7 +371,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
* @param val
|
||||
* The value to be subtracted from this.
|
||||
* @return The new value representing this-val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public NumeroAvanzatoVec subtract(final NumeroAvanzatoVec val) throws Errore {
|
||||
NumeroAvanzatoVec sum = new NumeroAvanzatoVec();
|
||||
@ -383,7 +391,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
* @param val
|
||||
* The value to be subtracted from this.
|
||||
* @return The new value representing this-val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public NumeroAvanzatoVec subtract(final NumeroAvanzato val) throws Errore {
|
||||
NumeroAvanzatoVec sum = new NumeroAvanzatoVec();
|
||||
@ -420,7 +428,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
* Compute the square.
|
||||
*
|
||||
* @return this value squared.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public NumeroAvanzatoVec sqr() throws Errore {
|
||||
@ -444,7 +452,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
* @param val
|
||||
* a second number of this type.
|
||||
* @return the product of this with the val.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public NumeroAvanzatoVec multiply(final NumeroAvanzato val) throws Errore {
|
||||
@ -499,7 +507,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
}
|
||||
return val;
|
||||
} /* NumeroAvanzatoVec.isRational */
|
||||
|
||||
|
||||
public boolean isNumeroAvanzato() {
|
||||
return (this.terms.size() <= 1);
|
||||
}
|
||||
@ -549,7 +557,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
public BigInteger toBigInteger(boolean hasBigIntegerVariables) {
|
||||
BigDecimal tmp = BigDecimal.ZERO.setScale(Utils.scale, Utils.scaleMode);
|
||||
if (isBigInteger(hasBigIntegerVariables) == false)
|
||||
throw new ArithmeticException("Undefined conversion " + toString() + " to Rational.");
|
||||
throw new ArithmeticException("Undefined conversion " + toString() + " to BigInteger.");
|
||||
for (NumeroAvanzato s : terms) {
|
||||
tmp = BigDecimalMath.addRound(tmp, s.pref.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)));
|
||||
}
|
||||
@ -569,14 +577,13 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
return tmp;
|
||||
} /* NumeroAvanzato.toBigDecimal */
|
||||
|
||||
|
||||
public NumeroAvanzato toNumeroAvanzato() {
|
||||
if (this.terms.size() == 0) {
|
||||
return NumeroAvanzato.ZERO;
|
||||
}
|
||||
return this.terms.get(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a string in the format (number/denom)*()^(1/2). If the
|
||||
* discriminant equals 1, print just the prefactor.
|
||||
@ -584,25 +591,26 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
* @return the human-readable version in base 10
|
||||
* @since 2012-02-16
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
/*
|
||||
* simple cases with one term forwarded to the NumeroAvanzato class
|
||||
*/
|
||||
return toFancyString();
|
||||
/*
|
||||
if (terms.size() == 0)
|
||||
return new String("0");
|
||||
else {
|
||||
String s = new String();
|
||||
for (int t = 0; t < terms.size(); t++) {
|
||||
NumeroAvanzato bs = terms.elementAt(t);
|
||||
if (bs.signum() > 0)
|
||||
s += "+";
|
||||
s += bs.toString();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
* if (terms.size() == 0)
|
||||
* return new String("0");
|
||||
* else {
|
||||
* String s = new String();
|
||||
* for (int t = 0; t < terms.size(); t++) {
|
||||
* NumeroAvanzato bs = terms.elementAt(t);
|
||||
* if (bs.signum() > 0)
|
||||
* s += "+";
|
||||
* s += bs.toString();
|
||||
* }
|
||||
* return s;
|
||||
* }
|
||||
*/
|
||||
} /* toString */
|
||||
|
||||
public String toFancyString() {
|
||||
@ -613,7 +621,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
NumeroAvanzato bs = terms.elementAt(0).clone();
|
||||
String num = bs.BigDecimalValue(new MathContext(Utils.resultScale, Utils.scaleMode2)).toEngineeringString();
|
||||
if (num.contains("E")) {
|
||||
s += "("+num.replace("E+", "*10^")+")";
|
||||
s += "(" + num.replace("E+", "*10^") + ")";
|
||||
} else {
|
||||
s += num;
|
||||
}
|
||||
@ -624,12 +632,13 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
Incognite incognitedenom = new Incognite();
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
denominator = BigIntegerMath.lcm(denominator, terms.elementAt(i).pref.b);
|
||||
//denominator = denominator.multiply(terms.elementAt(i).pref.b);
|
||||
// denominator =
|
||||
// denominator.multiply(terms.elementAt(i).pref.b);
|
||||
Incognite iz = terms.elementAt(i).getIncognitez();
|
||||
incognitedenom = Incognite.lcm(incognitedenom, iz);
|
||||
}
|
||||
String s = "";
|
||||
|
||||
|
||||
if (denominator.abs().compareTo(new BigInteger("10000")) > 0) {
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
NumeroAvanzato bs = terms.elementAt(i).clone();
|
||||
@ -638,11 +647,11 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
if (bs.signum() > 0) {
|
||||
s += "+";
|
||||
}
|
||||
num = num.replace("E+", "*10^")+")";
|
||||
num = num.replace("E+", "*10^") + ")";
|
||||
if (num.contains("*10^1)")) {
|
||||
num = num.replace("*10^1)", ")");
|
||||
} else {
|
||||
num = "("+num;
|
||||
num = "(" + num;
|
||||
}
|
||||
s += num;
|
||||
} else {
|
||||
@ -655,7 +664,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
if (denominator.compareTo(BigInteger.ONE) != 0 || incognitedenom.count() > 0) {
|
||||
if (terms.size() == 1 && terms.get(0).multiply(denominator).isBigInteger(true) == false) {
|
||||
s += "(";
|
||||
@ -663,12 +672,12 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
}
|
||||
for (int t = 0; t < terms.size(); t++) {
|
||||
NumeroAvanzato bs = terms.elementAt(t).clone();
|
||||
|
||||
|
||||
bs = bs.setIncognitey(bs.getIncognitey().divide(bs.getIncognitez()));
|
||||
bs = bs.setIncognitey(bs.getIncognitey().multiply(incognitedenom));
|
||||
bs = bs.multiply(denominator);
|
||||
bs = bs.setIncognitez(incognitedenom);
|
||||
|
||||
|
||||
bs.pref = new Rational(bs.pref.a, BigInteger.ONE);
|
||||
if (bs.signum() > 0 && t > 0)
|
||||
s += "+";
|
||||
@ -687,7 +696,7 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
} else if (numb.equals("-1")) {
|
||||
s += "-";
|
||||
}
|
||||
s +=incognite;
|
||||
s += incognite;
|
||||
} else if (bs.isRational(true) || bs.isTooPreciseRational(true)) {
|
||||
try {
|
||||
s += bs.toRational(true).toString();
|
||||
@ -706,13 +715,13 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
s += "-";
|
||||
}
|
||||
}
|
||||
//s += "(";
|
||||
// s += "(";
|
||||
}
|
||||
if (bs.disc.isInteger() && bs.getIncognitex().count() == 0) {
|
||||
s += "Ⓐ(";
|
||||
s += bs.disc.toString();
|
||||
s += ")";
|
||||
} else if((bs.disc.toString().equals("1") || bs.disc.toString().equals("-1")) && bs.getIncognitex().count() > 0) {
|
||||
} else if ((bs.disc.toString().equals("1") || bs.disc.toString().equals("-1")) && bs.getIncognitex().count() > 0) {
|
||||
s += "Ⓐ(";
|
||||
if (bs.disc.toString().equals("-1")) {
|
||||
s += "-";
|
||||
@ -720,16 +729,16 @@ public class NumeroAvanzatoVec implements Comparable<NumeroAvanzatoVec> {
|
||||
s += bs.getIncognitex().toString();
|
||||
s += ")";
|
||||
} else {
|
||||
s += "Ⓐ("+bs.disc.toString()+bs.getIncognitex().toString()+")";
|
||||
s += "Ⓐ(" + bs.disc.toString() + bs.getIncognitex().toString() + ")";
|
||||
}
|
||||
if ((numerator.compareTo(BigInteger.ONE) != 0 || bs.getIncognitey().count() > 0) && (bs.disc.compareTo(BigInteger.ONE) != 0 || bs.getIncognitex().count() > 0)) {
|
||||
if (((bs.getIncognitey().count() > 0) || (bs.getIncognitey().count() == 0 && numerator.toString().length() > 0))) {
|
||||
s += bs.getIncognitey().toString();
|
||||
}
|
||||
//s += "(";
|
||||
// s += "(";
|
||||
}
|
||||
if ((numerator.compareTo(BigInteger.ONE) != 0 || bs.getIncognitey().count() > 0) && (bs.disc.compareTo(BigInteger.ONE) != 0 || bs.getIncognitex().count() > 0)) {
|
||||
//s += ")";
|
||||
// s += ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,85 +1,88 @@
|
||||
package org.nevec.rjm ;
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
/** Number of partitions.
|
||||
* @since 2008-10-15
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class PartitionsP
|
||||
{
|
||||
/**
|
||||
* The list of all partitions as a vector.
|
||||
*/
|
||||
static protected Vector<BigInteger> a = new Vector<BigInteger>() ;
|
||||
/**
|
||||
* Number of partitions.
|
||||
*
|
||||
* @since 2008-10-15
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class PartitionsP {
|
||||
/**
|
||||
* The list of all partitions as a vector.
|
||||
*/
|
||||
static protected Vector<BigInteger> a = new Vector<BigInteger>();
|
||||
|
||||
/**
|
||||
* The maximum integer covered by the high end of the list.
|
||||
*/
|
||||
static protected BigInteger nMax =new BigInteger("-1") ;
|
||||
/**
|
||||
* The maximum integer covered by the high end of the list.
|
||||
*/
|
||||
static protected BigInteger nMax = new BigInteger("-1");
|
||||
|
||||
/**
|
||||
* Default constructor initializing a list of partitions up to 7.
|
||||
*/
|
||||
public PartitionsP()
|
||||
{
|
||||
if ( a.size() == 0 )
|
||||
{
|
||||
a.add(new BigInteger(""+1)) ;
|
||||
a.add(new BigInteger(""+1)) ;
|
||||
a.add(new BigInteger(""+2)) ;
|
||||
a.add(new BigInteger(""+3)) ;
|
||||
a.add(new BigInteger(""+5)) ;
|
||||
a.add(new BigInteger(""+7)) ;
|
||||
}
|
||||
nMax = new BigInteger(""+(a.size()-1)) ;
|
||||
} /* ctor */
|
||||
/**
|
||||
* Default constructor initializing a list of partitions up to 7.
|
||||
*/
|
||||
public PartitionsP() {
|
||||
if (a.size() == 0) {
|
||||
a.add(new BigInteger("" + 1));
|
||||
a.add(new BigInteger("" + 1));
|
||||
a.add(new BigInteger("" + 2));
|
||||
a.add(new BigInteger("" + 3));
|
||||
a.add(new BigInteger("" + 5));
|
||||
a.add(new BigInteger("" + 7));
|
||||
}
|
||||
nMax = new BigInteger("" + (a.size() - 1));
|
||||
} /* ctor */
|
||||
|
||||
/** return the number of partitions of i
|
||||
* @param i the zero-based index into the list of partitions
|
||||
* @return the ith partition number. This is 1 if i=0 or 1, 2 if i=2 and so forth.
|
||||
*/
|
||||
public BigInteger at(int i)
|
||||
{
|
||||
/* If the current list is too small, increase in intervals
|
||||
* of 3 until the list has at least i elements.
|
||||
*/
|
||||
while ( i > nMax.intValue() )
|
||||
{
|
||||
growto(nMax.add(new BigInteger(""+3))) ;
|
||||
}
|
||||
return ( a.elementAt(i) ) ;
|
||||
} /* at */
|
||||
/**
|
||||
* return the number of partitions of i
|
||||
*
|
||||
* @param i
|
||||
* the zero-based index into the list of partitions
|
||||
* @return the ith partition number. This is 1 if i=0 or 1, 2 if i=2 and so
|
||||
* forth.
|
||||
*/
|
||||
public BigInteger at(int i) {
|
||||
/*
|
||||
* If the current list is too small, increase in intervals
|
||||
* of 3 until the list has at least i elements.
|
||||
*/
|
||||
while (i > nMax.intValue()) {
|
||||
growto(nMax.add(new BigInteger("" + 3)));
|
||||
}
|
||||
return (a.elementAt(i));
|
||||
} /* at */
|
||||
|
||||
/** extend the list of known partitions up to n
|
||||
* @param n the maximum integer hashed after the call.
|
||||
*/
|
||||
private void growto(BigInteger n)
|
||||
{
|
||||
while( a.size() <= n.intValue() )
|
||||
{
|
||||
BigInteger per = new BigInteger("0") ;
|
||||
BigInteger cursiz = new BigInteger(""+a.size()) ;
|
||||
for(int k=0; k < a.size() ; k++)
|
||||
{
|
||||
BigInteger tmp = a.elementAt(k).multiply(BigIntegerMath.sigma(a.size()-k)) ;
|
||||
per = per.add(tmp) ;
|
||||
}
|
||||
a.add(per.divide(cursiz)) ;
|
||||
}
|
||||
nMax = new BigInteger(""+(a.size()-1)) ;
|
||||
} /* growto */
|
||||
/**
|
||||
* extend the list of known partitions up to n
|
||||
*
|
||||
* @param n
|
||||
* the maximum integer hashed after the call.
|
||||
*/
|
||||
private void growto(BigInteger n) {
|
||||
while (a.size() <= n.intValue()) {
|
||||
BigInteger per = new BigInteger("0");
|
||||
BigInteger cursiz = new BigInteger("" + a.size());
|
||||
for (int k = 0; k < a.size(); k++) {
|
||||
BigInteger tmp = a.elementAt(k).multiply(BigIntegerMath.sigma(a.size() - k));
|
||||
per = per.add(tmp);
|
||||
}
|
||||
a.add(per.divide(cursiz));
|
||||
}
|
||||
nMax = new BigInteger("" + (a.size() - 1));
|
||||
} /* growto */
|
||||
|
||||
/** Test program.
|
||||
* It takes one integer argument n and prints P(n).<br>
|
||||
* java -cp . org.nevec.rjm.PartitionsP n<br>
|
||||
* @since 2008-10-15
|
||||
*/
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
PartitionsP a = new PartitionsP() ;
|
||||
int n = (new Integer(args[0])).intValue() ;
|
||||
System.out.println("P("+ n +")=" + a.at(n)) ;
|
||||
}
|
||||
/**
|
||||
* Test program.
|
||||
* It takes one integer argument n and prints P(n).<br>
|
||||
* java -cp . org.nevec.rjm.PartitionsP n<br>
|
||||
*
|
||||
* @since 2008-10-15
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
PartitionsP a = new PartitionsP();
|
||||
int n = (new Integer(args[0])).intValue();
|
||||
System.out.println("P(" + n + ")=" + a.at(n));
|
||||
}
|
||||
}
|
||||
|
@ -1,279 +1,312 @@
|
||||
package org.nevec.rjm ;
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
/** Prime numbers.
|
||||
* The implementation is a very basic computation of the set of all primes
|
||||
* on demand, growing infinitely without any defined upper limit.
|
||||
* The effects of such scheme are (i) the lookup-times become shorter after
|
||||
* a while as more and more primes have been used and stored. The applications
|
||||
* appear to become faster. (ii) Using the implementation for factorizations
|
||||
* may easily require all available memory and stall finally, because indeed
|
||||
* a dense list of primes with growing upper bound is kept without any hashing or lagging scheme.
|
||||
* @since 2006-08-11
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Prime
|
||||
{
|
||||
/** The list of all numbers as a vector.
|
||||
*/
|
||||
static Vector<BigInteger> a = new Vector<BigInteger>();
|
||||
/**
|
||||
* Prime numbers.
|
||||
* The implementation is a very basic computation of the set of all primes
|
||||
* on demand, growing infinitely without any defined upper limit.
|
||||
* The effects of such scheme are (i) the lookup-times become shorter after
|
||||
* a while as more and more primes have been used and stored. The applications
|
||||
* appear to become faster. (ii) Using the implementation for factorizations
|
||||
* may easily require all available memory and stall finally, because indeed
|
||||
* a dense list of primes with growing upper bound is kept without any hashing
|
||||
* or lagging scheme.
|
||||
*
|
||||
* @since 2006-08-11
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Prime {
|
||||
/**
|
||||
* The list of all numbers as a vector.
|
||||
*/
|
||||
static Vector<BigInteger> a = new Vector<BigInteger>();
|
||||
|
||||
/** The maximum integer covered by the high end of the list.
|
||||
*/
|
||||
static protected BigInteger nMax = new BigInteger("-1");
|
||||
/**
|
||||
* The maximum integer covered by the high end of the list.
|
||||
*/
|
||||
static protected BigInteger nMax = new BigInteger("-1");
|
||||
|
||||
/** Default constructor initializing a list of primes up to 17.
|
||||
* 17 is enough to call the Miller-Rabin tests on the first 7 primes without further
|
||||
* action.
|
||||
*/
|
||||
public Prime()
|
||||
{
|
||||
if ( a.size() == 0 )
|
||||
{
|
||||
a.add(new BigInteger(""+2)) ;
|
||||
a.add(new BigInteger(""+3)) ;
|
||||
a.add(new BigInteger(""+5)) ;
|
||||
a.add(new BigInteger(""+7)) ;
|
||||
a.add(new BigInteger(""+11)) ;
|
||||
a.add(new BigInteger(""+13)) ;
|
||||
a.add(new BigInteger(""+17)) ;
|
||||
}
|
||||
nMax = a.lastElement() ;
|
||||
}
|
||||
/**
|
||||
* Default constructor initializing a list of primes up to 17.
|
||||
* 17 is enough to call the Miller-Rabin tests on the first 7 primes without
|
||||
* further
|
||||
* action.
|
||||
*/
|
||||
public Prime() {
|
||||
if (a.size() == 0) {
|
||||
a.add(new BigInteger("" + 2));
|
||||
a.add(new BigInteger("" + 3));
|
||||
a.add(new BigInteger("" + 5));
|
||||
a.add(new BigInteger("" + 7));
|
||||
a.add(new BigInteger("" + 11));
|
||||
a.add(new BigInteger("" + 13));
|
||||
a.add(new BigInteger("" + 17));
|
||||
}
|
||||
nMax = a.lastElement();
|
||||
}
|
||||
|
||||
/** Test if a number is a prime.
|
||||
* @param n the integer to be tested for primality
|
||||
* @return true if prime, false if not
|
||||
*/
|
||||
public boolean contains(BigInteger n)
|
||||
{
|
||||
/* not documented
|
||||
* return ( n.isProbablePrime() ) ;
|
||||
*/
|
||||
switch ( millerRabin(n) )
|
||||
{
|
||||
case -1:
|
||||
return false ;
|
||||
case 1:
|
||||
return true ;
|
||||
}
|
||||
growto(n) ;
|
||||
return( a.contains(n) ) ;
|
||||
}
|
||||
/**
|
||||
* Test if a number is a prime.
|
||||
*
|
||||
* @param n
|
||||
* the integer to be tested for primality
|
||||
* @return true if prime, false if not
|
||||
*/
|
||||
public boolean contains(BigInteger n) {
|
||||
/*
|
||||
* not documented
|
||||
* return ( n.isProbablePrime() ) ;
|
||||
*/
|
||||
switch (millerRabin(n)) {
|
||||
case -1:
|
||||
return false;
|
||||
case 1:
|
||||
return true;
|
||||
}
|
||||
growto(n);
|
||||
return (a.contains(n));
|
||||
}
|
||||
|
||||
/** Test whether a number n is a strong pseudoprime to base a.
|
||||
* @param n the integer to be tested for primality
|
||||
* @param a the base
|
||||
* @return true if the test is passed, so n may be a prime.
|
||||
* false if the test is not passed, so n is not a prime.
|
||||
* @since 2010-02-25
|
||||
*/
|
||||
public boolean isSPP(final BigInteger n, final BigInteger a)
|
||||
{
|
||||
final BigInteger two = new BigInteger(""+2) ;
|
||||
/**
|
||||
* Test whether a number n is a strong pseudoprime to base a.
|
||||
*
|
||||
* @param n
|
||||
* the integer to be tested for primality
|
||||
* @param a
|
||||
* the base
|
||||
* @return true if the test is passed, so n may be a prime.
|
||||
* false if the test is not passed, so n is not a prime.
|
||||
* @since 2010-02-25
|
||||
*/
|
||||
public boolean isSPP(final BigInteger n, final BigInteger a) {
|
||||
final BigInteger two = new BigInteger("" + 2);
|
||||
|
||||
/*
|
||||
* numbers less than 2 are not prime
|
||||
*/
|
||||
if (n.compareTo(two) == -1)
|
||||
return false;
|
||||
/*
|
||||
* 2 is prime
|
||||
*/
|
||||
else if (n.compareTo(two) == 0)
|
||||
return true;
|
||||
/*
|
||||
* even numbers >2 are not prime
|
||||
*/
|
||||
else if (n.remainder(two).compareTo(BigInteger.ZERO) == 0)
|
||||
return false;
|
||||
else {
|
||||
/*
|
||||
* q= n- 1 = d *2^s with d odd
|
||||
*/
|
||||
final BigInteger q = n.subtract(BigInteger.ONE);
|
||||
int s = q.getLowestSetBit();
|
||||
BigInteger d = q.shiftRight(s);
|
||||
|
||||
/* numbers less than 2 are not prime
|
||||
*/
|
||||
if ( n.compareTo(two) == -1 )
|
||||
return false ;
|
||||
/* 2 is prime
|
||||
*/
|
||||
else if ( n.compareTo(two) == 0 )
|
||||
return true ;
|
||||
/* even numbers >2 are not prime
|
||||
*/
|
||||
else if ( n.remainder(two).compareTo(BigInteger.ZERO) == 0 )
|
||||
return false ;
|
||||
else
|
||||
{
|
||||
/* q= n- 1 = d *2^s with d odd
|
||||
*/
|
||||
final BigInteger q = n.subtract(BigInteger.ONE) ;
|
||||
int s = q.getLowestSetBit() ;
|
||||
BigInteger d = q.shiftRight(s) ;
|
||||
/*
|
||||
* test whether a^d = 1 (mod n)
|
||||
*/
|
||||
if (a.modPow(d, n).compareTo(BigInteger.ONE) == 0)
|
||||
return true;
|
||||
|
||||
/* test whether a^d = 1 (mod n)
|
||||
*/
|
||||
if ( a.modPow(d,n).compareTo(BigInteger.ONE) == 0 )
|
||||
return true ;
|
||||
/*
|
||||
* test whether a^(d*2^r) = -1 (mod n), 0<=r<s
|
||||
*/
|
||||
for (int r = 0; r < s; r++) {
|
||||
if (a.modPow(d.shiftLeft(r), n).compareTo(q) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* test whether a^(d*2^r) = -1 (mod n), 0<=r<s
|
||||
*/
|
||||
for(int r=0; r < s ; r++)
|
||||
{
|
||||
if ( a.modPow(d.shiftLeft(r),n).compareTo(q) == 0 )
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Miller-Rabin primality tests.
|
||||
*
|
||||
* @param n
|
||||
* The prime candidate
|
||||
* @return -1 if n is a composite, 1 if it is a prime, 0 if it may be a
|
||||
* prime.
|
||||
* @since 2010-02-25
|
||||
*/
|
||||
public int millerRabin(final BigInteger n) {
|
||||
/*
|
||||
* list of limiting numbers which fail tests on k primes, A014233 in the
|
||||
* OEIS
|
||||
*/
|
||||
final String[] mr = { "2047", "1373653", "25326001", "3215031751", "2152302898747", "3474749660383", "341550071728321" };
|
||||
int mrLim = 0;
|
||||
while (mrLim < mr.length) {
|
||||
int l = n.compareTo(new BigInteger(mr[mrLim]));
|
||||
if (l < 0)
|
||||
break;
|
||||
/*
|
||||
* if one of the pseudo-primes: this is a composite
|
||||
*/
|
||||
else if (l == 0)
|
||||
return -1;
|
||||
mrLim++;
|
||||
}
|
||||
/*
|
||||
* cannot test candidates larger than the last in the mr list
|
||||
*/
|
||||
if (mrLim == mr.length)
|
||||
return 0;
|
||||
|
||||
/** Miller-Rabin primality tests.
|
||||
* @param n The prime candidate
|
||||
* @return -1 if n is a composite, 1 if it is a prime, 0 if it may be a prime.
|
||||
* @since 2010-02-25
|
||||
*/
|
||||
public int millerRabin(final BigInteger n)
|
||||
{
|
||||
/* list of limiting numbers which fail tests on k primes, A014233 in the OEIS
|
||||
*/
|
||||
final String[] mr ={"2047", "1373653", "25326001", "3215031751", "2152302898747", "3474749660383",
|
||||
"341550071728321"} ;
|
||||
int mrLim = 0 ;
|
||||
while( mrLim < mr.length )
|
||||
{
|
||||
int l = n.compareTo(new BigInteger(mr[mrLim])) ;
|
||||
if ( l < 0 )
|
||||
break;
|
||||
/* if one of the pseudo-primes: this is a composite
|
||||
*/
|
||||
else if ( l == 0 )
|
||||
return -1 ;
|
||||
mrLim++ ;
|
||||
}
|
||||
/* cannot test candidates larger than the last in the mr list
|
||||
*/
|
||||
if ( mrLim == mr.length)
|
||||
return 0;
|
||||
/*
|
||||
* test the bases prime(1), prime(2) up to prime(mrLim+1)
|
||||
*/
|
||||
for (int p = 0; p <= mrLim; p++)
|
||||
if (isSPP(n, at(p)) == false)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* test the bases prime(1), prime(2) up to prime(mrLim+1)
|
||||
*/
|
||||
for(int p =0 ; p <= mrLim ; p++)
|
||||
if ( isSPP(n, at(p)) == false )
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
/**
|
||||
* return the ithprime
|
||||
*
|
||||
* @param i
|
||||
* the zero-based index into the list of primes
|
||||
* @return the ith prime. This is 2 if i=0, 3 if i=1 and so forth.
|
||||
*/
|
||||
public BigInteger at(int i) {
|
||||
/*
|
||||
* If the current list is too small, increase in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
while (i >= a.size()) {
|
||||
growto(nMax.add(new BigInteger("" + 5)));
|
||||
}
|
||||
return (a.elementAt(i));
|
||||
}
|
||||
|
||||
/** return the ithprime
|
||||
* @param i the zero-based index into the list of primes
|
||||
* @return the ith prime. This is 2 if i=0, 3 if i=1 and so forth.
|
||||
*/
|
||||
public BigInteger at(int i)
|
||||
{
|
||||
/* If the current list is too small, increase in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
while ( i >= a.size() )
|
||||
{
|
||||
growto(nMax.add(new BigInteger(""+5))) ;
|
||||
}
|
||||
return ( a.elementAt(i) ) ;
|
||||
}
|
||||
/**
|
||||
* return the count of primes <= n
|
||||
*
|
||||
* @param n
|
||||
* the upper limit of the scan
|
||||
* @return the ith prime. This is 2 if i=0, 3 if i=1 and so forth.
|
||||
*/
|
||||
public BigInteger pi(BigInteger n) {
|
||||
/*
|
||||
* If the current list is too small, increase in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
growto(n);
|
||||
BigInteger r = new BigInteger("0");
|
||||
for (int i = 0; i < a.size(); i++)
|
||||
if (a.elementAt(i).compareTo(n) <= 0)
|
||||
r = r.add(BigInteger.ONE);
|
||||
return r;
|
||||
}
|
||||
|
||||
/** return the count of primes <= n
|
||||
* @param n the upper limit of the scan
|
||||
* @return the ith prime. This is 2 if i=0, 3 if i=1 and so forth.
|
||||
*/
|
||||
public BigInteger pi(BigInteger n)
|
||||
{
|
||||
/* If the current list is too small, increase in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
growto(n) ;
|
||||
BigInteger r = new BigInteger("0") ;
|
||||
for(int i=0 ; i<a.size() ; i++)
|
||||
if ( a.elementAt(i).compareTo(n) <= 0 )
|
||||
r = r.add(BigInteger.ONE) ;
|
||||
return r ;
|
||||
}
|
||||
/**
|
||||
* return the smallest prime larger than n
|
||||
*
|
||||
* @param n
|
||||
* lower limit of the search
|
||||
* @return the next larger prime.
|
||||
* @since 2008-10-16
|
||||
*/
|
||||
public BigInteger nextprime(BigInteger n) {
|
||||
/* if n <=1, return 2 */
|
||||
if (n.compareTo(BigInteger.ONE) <= 0)
|
||||
return (a.elementAt(0));
|
||||
|
||||
/** return the smallest prime larger than n
|
||||
* @param n lower limit of the search
|
||||
* @return the next larger prime.
|
||||
* @since 2008-10-16
|
||||
*/
|
||||
public BigInteger nextprime(BigInteger n)
|
||||
{
|
||||
/* if n <=1, return 2 */
|
||||
if ( n.compareTo(BigInteger.ONE) <= 0)
|
||||
return ( a.elementAt(0) ) ;
|
||||
/*
|
||||
* If the currently largest element in the list is too small, increase
|
||||
* in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
while (a.lastElement().compareTo(n) <= 0) {
|
||||
growto(nMax.add(new BigInteger("" + 5)));
|
||||
}
|
||||
for (int i = 0; i < a.size(); i++)
|
||||
if (a.elementAt(i).compareTo(n) == 1)
|
||||
return (a.elementAt(i));
|
||||
return (a.lastElement());
|
||||
}
|
||||
|
||||
/* If the currently largest element in the list is too small, increase in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
while ( a.lastElement().compareTo(n) <= 0)
|
||||
{
|
||||
growto(nMax.add(new BigInteger(""+5))) ;
|
||||
}
|
||||
for(int i=0 ; i < a.size() ; i++)
|
||||
if ( a.elementAt(i).compareTo(n) == 1)
|
||||
return ( a.elementAt(i) ) ;
|
||||
return ( a.lastElement() ) ;
|
||||
}
|
||||
/**
|
||||
* return the largest prime smaller than n
|
||||
*
|
||||
* @param n
|
||||
* upper limit of the search
|
||||
* @return the next smaller prime.
|
||||
* @since 2008-10-17
|
||||
*/
|
||||
public BigInteger prevprime(BigInteger n) {
|
||||
/* if n <=2, return 0 */
|
||||
if (n.compareTo(BigInteger.ONE) <= 0)
|
||||
return BigInteger.ZERO;
|
||||
|
||||
/** return the largest prime smaller than n
|
||||
* @param n upper limit of the search
|
||||
* @return the next smaller prime.
|
||||
* @since 2008-10-17
|
||||
*/
|
||||
public BigInteger prevprime(BigInteger n)
|
||||
{
|
||||
/* if n <=2, return 0 */
|
||||
if ( n.compareTo(BigInteger.ONE) <= 0)
|
||||
return BigInteger.ZERO ;
|
||||
/*
|
||||
* If the currently largest element in the list is too small, increase
|
||||
* in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
while (a.lastElement().compareTo(n) < 0)
|
||||
growto(nMax.add(new BigInteger("" + 5)));
|
||||
|
||||
/* If the currently largest element in the list is too small, increase in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
while ( a.lastElement().compareTo(n) < 0)
|
||||
growto(nMax.add(new BigInteger(""+5))) ;
|
||||
for (int i = 0; i < a.size(); i++)
|
||||
if (a.elementAt(i).compareTo(n) >= 0)
|
||||
return (a.elementAt(i - 1));
|
||||
return (a.lastElement());
|
||||
}
|
||||
|
||||
for(int i=0 ; i < a.size() ; i++)
|
||||
if ( a.elementAt(i).compareTo(n) >= 0)
|
||||
return ( a.elementAt(i-1) ) ;
|
||||
return ( a.lastElement() ) ;
|
||||
}
|
||||
/**
|
||||
* extend the list of known primes up to n
|
||||
*
|
||||
* @param n
|
||||
* the maximum integer known to be prime or not prime after the
|
||||
* call.
|
||||
*/
|
||||
protected void growto(BigInteger n) {
|
||||
while (nMax.compareTo(n) == -1) {
|
||||
nMax = nMax.add(BigInteger.ONE);
|
||||
boolean isp = true;
|
||||
for (int p = 0; p < a.size(); p++) {
|
||||
/*
|
||||
* Test the list of known primes only up to sqrt(n)
|
||||
*/
|
||||
if (a.get(p).multiply(a.get(p)).compareTo(nMax) == 1)
|
||||
break;
|
||||
|
||||
/** extend the list of known primes up to n
|
||||
* @param n the maximum integer known to be prime or not prime after the call.
|
||||
*/
|
||||
protected void growto(BigInteger n)
|
||||
{
|
||||
while( nMax.compareTo(n) == -1)
|
||||
{
|
||||
nMax = nMax.add(BigInteger.ONE) ;
|
||||
boolean isp = true ;
|
||||
for(int p=0; p < a.size() ; p++)
|
||||
{
|
||||
/*
|
||||
* Test the list of known primes only up to sqrt(n)
|
||||
*/
|
||||
if ( a.get(p).multiply(a.get(p)).compareTo(nMax) == 1 )
|
||||
break ;
|
||||
/*
|
||||
* The next case means that the p'th number in the list of known
|
||||
* primes divides
|
||||
* nMax and nMax cannot be a prime.
|
||||
*/
|
||||
if (nMax.remainder(a.get(p)).compareTo(BigInteger.ZERO) == 0) {
|
||||
isp = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isp)
|
||||
a.add(nMax);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The next case means that the p'th number in the list of known primes divides
|
||||
* nMax and nMax cannot be a prime.
|
||||
*/
|
||||
if ( nMax.remainder(a.get(p)).compareTo(BigInteger.ZERO) == 0 )
|
||||
{
|
||||
isp = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if( isp )
|
||||
a.add(nMax) ;
|
||||
}
|
||||
}
|
||||
/** Test program.
|
||||
* Usage: java -cp . org.nevec.rjm.Prime n<br>
|
||||
* This takes a single argument (n) and prints prime(n), the previous and next prime, and pi(n).
|
||||
* @since 2006-08-14
|
||||
*/
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
Prime a = new Prime() ;
|
||||
int n = (new Integer(args[0])).intValue() ;
|
||||
if ( n >= 1 )
|
||||
{
|
||||
if ( n >= 2)
|
||||
System.out.println("prime("+(n-1)+") = " + a.at(n-1)) ;
|
||||
System.out.println("prime("+n+") = " + a.at(n)) ;
|
||||
System.out.println("prime("+(n+1)+") = " + a.at(n+1)) ;
|
||||
System.out.println("pi(" + n +") = " + a.pi(new BigInteger(""+n) )) ;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Test program.
|
||||
* Usage: java -cp . org.nevec.rjm.Prime n<br>
|
||||
* This takes a single argument (n) and prints prime(n), the previous and
|
||||
* next prime, and pi(n).
|
||||
*
|
||||
* @since 2006-08-14
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
Prime a = new Prime();
|
||||
int n = (new Integer(args[0])).intValue();
|
||||
if (n >= 1) {
|
||||
if (n >= 2)
|
||||
System.out.println("prime(" + (n - 1) + ") = " + a.at(n - 1));
|
||||
System.out.println("prime(" + n + ") = " + a.at(n));
|
||||
System.out.println("prime(" + (n + 1) + ") = " + a.at(n + 1));
|
||||
System.out.println("pi(" + n + ") = " + a.pi(new BigInteger("" + n)));
|
||||
}
|
||||
}
|
||||
} /* Prime */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,8 +5,8 @@ import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import org.warpgate.pi.calculator.Errore;
|
||||
import org.warpgate.pi.calculator.Errori;
|
||||
import org.warp.picalculator.Errore;
|
||||
import org.warp.picalculator.Errori;
|
||||
|
||||
/**
|
||||
* Fractions (rational numbers). They are divisions of two BigInteger numbers,
|
||||
@ -153,6 +153,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
*
|
||||
* @since 2008-11-07
|
||||
*/
|
||||
@Override
|
||||
public Rational clone() {
|
||||
/*
|
||||
* protected access means this does not work return new
|
||||
@ -231,7 +232,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* the exponent.
|
||||
* @return this value raised to the power given by the exponent. If the
|
||||
* exponent is 0, the value 1 is returned.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
public Rational pow(BigInteger exponent) throws Errore {
|
||||
@ -253,7 +254,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* third root etc
|
||||
* @return this value raised to the inverse power given by the root
|
||||
* argument, this^(1/r).
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
public Rational root(BigInteger r) throws Errore {
|
||||
@ -293,7 +294,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* The exponent.
|
||||
* @return This value raised to the power given by the exponent. If the
|
||||
* exponent is 0, the value 1 is returned.
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
public Rational pow(Rational exponent) throws Errore {
|
||||
@ -314,7 +315,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @param val
|
||||
* A second rational number.
|
||||
* @return The value of this/val
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public Rational divide(final Rational val) throws Errore {
|
||||
if (val.compareTo(Rational.ZERO) == 0)
|
||||
@ -334,7 +335,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the value of this/val
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public Rational divide(BigInteger val) throws Errore {
|
||||
if (val.compareTo(BigInteger.ZERO) == 0)
|
||||
@ -349,7 +350,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @param val
|
||||
* A second number.
|
||||
* @return The value of this/val
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public Rational divide(int val) throws Errore {
|
||||
if (val == 0)
|
||||
@ -451,7 +452,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return the binomial coefficient.
|
||||
* @since 2006-06-27
|
||||
* @author Richard J. Mathar
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public static Rational binomial(Rational n, BigInteger m) throws Errore {
|
||||
if (m.compareTo(BigInteger.ZERO) == 0)
|
||||
@ -473,7 +474,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return the binomial coefficient.
|
||||
* @since 2009-05-19
|
||||
* @author Richard J. Mathar
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public static Rational binomial(Rational n, int m) throws Errore {
|
||||
if (m == 0)
|
||||
@ -495,7 +496,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return Gamma(n+k+1/2)/k!/GAMMA(n-k+1/2)
|
||||
* @since 2010-07-18
|
||||
* @author Richard J. Mathar
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
public static Rational hankelSymb(Rational n, int k) throws Errore {
|
||||
if (k == 0)
|
||||
@ -593,6 +594,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return -1, 0 or 1 if this number is numerically less than, equal to, or
|
||||
* greater than val.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final Rational val) {
|
||||
/*
|
||||
* Since we have always kept the denominators positive, simple
|
||||
@ -622,6 +624,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
*
|
||||
* @return the human-readable version in base 10
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (b.compareTo(BigInteger.ONE) != 0)
|
||||
return (a.toString() + "/" + b.toString());
|
||||
@ -788,7 +791,8 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
|
||||
/**
|
||||
* Conversion to an integer value, if this can be done exactly.
|
||||
* @throws Errore
|
||||
*
|
||||
* @throws Errore
|
||||
*
|
||||
* @since 2011-02-13
|
||||
*/
|
||||
@ -800,7 +804,8 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
|
||||
/**
|
||||
* Conversion to a BigInteger value, if this can be done exactly.
|
||||
* @throws Errore
|
||||
*
|
||||
* @throws Errore
|
||||
*
|
||||
* @since 2012-03-02
|
||||
*/
|
||||
@ -817,8 +822,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since 2010-05-26
|
||||
*/
|
||||
public boolean isIntegerFrac() {
|
||||
return (a.compareTo(MAX_INT) <= 0 && a.compareTo(MIN_INT) >= 0 && b.compareTo(MAX_INT) <= 0
|
||||
&& b.compareTo(MIN_INT) >= 0);
|
||||
return (a.compareTo(MAX_INT) <= 0 && a.compareTo(MIN_INT) >= 0 && b.compareTo(MAX_INT) <= 0 && b.compareTo(MIN_INT) >= 0);
|
||||
} /* Rational.isIntegerFrac */
|
||||
|
||||
/**
|
||||
|
@ -3,7 +3,7 @@ package org.nevec.rjm;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.warpgate.pi.calculator.Errore;
|
||||
import org.warp.picalculator.Errore;
|
||||
|
||||
/**
|
||||
* Exact representations of Wigner 3jm and 3nj values of half-integer arguments.
|
||||
@ -32,7 +32,7 @@ public class Wigner3j {
|
||||
*
|
||||
* @since 2011-02-15
|
||||
* @author Richard J. Mathar
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
static public void main(String args[]) throws Errore {
|
||||
if (args[0].compareTo("6j") == 0) {
|
||||
@ -105,7 +105,7 @@ public class Wigner3j {
|
||||
* inequalities is violated or some parameters are out of range.
|
||||
* @since 2011-02-13
|
||||
* @author Richard J. Mathar
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
static public BigSurd wigner3jm(int j1, int j2, int j3, int m1, int m2, int m3) throws Errore {
|
||||
Rational J1 = new Rational(j1, 2);
|
||||
@ -140,7 +140,7 @@ public class Wigner3j {
|
||||
* @since 2011-02-13
|
||||
* @since 2012-02-15 Upgraded return value to BigSurdVec
|
||||
* @author Richard J. Mathar
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
static public BigSurdVec wigner3j(String m1, String t1, String t2, String j) throws Errore {
|
||||
/*
|
||||
@ -270,9 +270,10 @@ public class Wigner3j {
|
||||
* @since 2011-02-13
|
||||
* @since 2012-02-15 Upgraded to return BigSurdVec
|
||||
* @author Richard J. Mathar
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
static private BigSurdVec wigner3j(final int[] tvec, final Rational[] J, final Rational[] M, final int[] triadidx) throws Errore {
|
||||
static private BigSurdVec wigner3j(final int[] tvec, final Rational[] J, final Rational[] M, final int[] triadidx)
|
||||
throws Errore {
|
||||
/*
|
||||
* The result of the computation. The sum over all m-combinations of the
|
||||
* triads.
|
||||
@ -479,9 +480,10 @@ public class Wigner3j {
|
||||
* inequalities is violated or some parameters are out of range.
|
||||
* @since 2011-02-13
|
||||
* @author Richard J. Mathar
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
*/
|
||||
static protected BigSurd wigner3jm(Rational j1, Rational j2, Rational j3, Rational m1, Rational m2, Rational m3) throws Errore {
|
||||
static protected BigSurd wigner3jm(Rational j1, Rational j2, Rational j3, Rational m1, Rational m2, Rational m3)
|
||||
throws Errore {
|
||||
/*
|
||||
* Check that m1+m2+m3 = 0
|
||||
*/
|
||||
@ -549,8 +551,7 @@ public class Wigner3j {
|
||||
Factorial f = new Factorial();
|
||||
Rational sumk = new Rational();
|
||||
while (true) {
|
||||
BigInteger d = f.at(k).multiply(f.at(j1j2jk)).multiply(f.at(j1m1k)).multiply(f.at(j2m2k))
|
||||
.multiply(f.at(jj2m1k)).multiply(f.at(jj1m2k));
|
||||
BigInteger d = f.at(k).multiply(f.at(j1j2jk)).multiply(f.at(j1m1k)).multiply(f.at(j2m2k)).multiply(f.at(jj2m1k)).multiply(f.at(jj1m2k));
|
||||
if (k % 2 == 0)
|
||||
sumk = sumk.add(new Rational(BigInteger.ONE, d));
|
||||
else
|
||||
|
@ -16,7 +16,7 @@ import javax.swing.JList;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import org.warpgate.pi.calculator.Errore;
|
||||
import org.warp.picalculator.Errore;
|
||||
|
||||
/**
|
||||
* An interactive interface to the Wigner3j class. The GUI allows to preselect
|
||||
@ -41,8 +41,7 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
|
||||
JButton sear;
|
||||
JList<?> searJ;
|
||||
String[] searOpt = { "6j", "9j", "12j 1st", "12j 2nd (not symm)", "15j 1st", "15j 2nd", "15j 3rd", "15j 4th",
|
||||
"15j 5th" };
|
||||
String[] searOpt = { "6j", "9j", "12j 1st", "12j 2nd (not symm)", "15j 1st", "15j 2nd", "15j 3rd", "15j 4th", "15j 5th" };
|
||||
|
||||
/**
|
||||
* Field with the triads inputs
|
||||
@ -135,7 +134,7 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
} /* init */
|
||||
|
||||
/**
|
||||
* @throws Errore
|
||||
* @throws Errore
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public void compute() throws Errore {
|
||||
@ -201,6 +200,7 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
* the information on which button had been pressed in the GUI
|
||||
* @since 2011-02-15
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String lin = e.getActionCommand();
|
||||
/*
|
||||
@ -226,99 +226,96 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
* selected in the Menu
|
||||
* @since 2011-02-18
|
||||
*/
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
switch (searJ.getMinSelectionIndex()) {
|
||||
case 0:
|
||||
inpGtria.setText("6\n");
|
||||
inpGtria.append("1 2 -3 -1 5 6\n");
|
||||
inpGtria.append("4 -5 3 -4 -2 -6");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 1:
|
||||
/*
|
||||
* Yutsis Figure 18.1 index map. j1=1, j2=2, j3=3 k1=4, k2=5, k3=6
|
||||
* l1=7, l2=8, l3=9
|
||||
*/
|
||||
inpGtria.setText("9\n");
|
||||
inpGtria.append("1 3 2 4 6 5 7 9 8 # (j1 j3 j2) (k1 k3 k2) (l1 l3 l2)\n");
|
||||
inpGtria.append("-2 -8 -5 -6 -3 -9 -7 -4 -1 # (j2 l2 k2) (k3 j3 l3) (l1 k1 j1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 2:
|
||||
/*
|
||||
* Yutsis Figure 19.1 and 19.2, index map, including the sign
|
||||
* reveral of the l. Assume input order j1..j4, l1..l4, k1..k4.
|
||||
* j1=1, j2=2, j3=3, j4=4 l1=5, l2=6, l3=7, l4=8 k1=9, k2=10, k3=11,
|
||||
* k4=12
|
||||
*/
|
||||
inpGtria.setText("12\n");
|
||||
inpGtria.append("1 12 -8 -1 5 -2 2 6 -3 3 7 -4 # (j1 k4 l4) (j1 l1 j2) (j2 l2 j3) (j3 l3 j4)\n");
|
||||
inpGtria.append("4 8 -9 9 -5 -10 10 -6 -11 11 -7 -12 # (j4 l4 k1) (k1 l1 k2) (k2 l2 k3) (k3 l3 k4)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 3:
|
||||
inpGtria.setText("12\n");
|
||||
inpGtria.append("1 5 9 -9 -2 -7 2 11 8 -8 -12 -4 # (j1 l1 k1) (k1 j2 l3 ) (j2 k3 l4) (l4 k4 j4)\n");
|
||||
inpGtria.append("4 7 10 -10 -3 -5 3 6 12 -6 -11 -1 # (j4 l3 k2) (k2 j3 l1) (j3 l2 k4) (l2 k3 j1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 4:
|
||||
/*
|
||||
* Yutsis Figure 20.2 to 20.3, index map. j1=1, j2=2, j3=3, j4=4,
|
||||
* j5=5 l1=6, l2=7, l3=8, l4=9, l5=10 k1=11, k2=12, k3=13, k4=14,
|
||||
* k5=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append(
|
||||
"1 -6 2 -2 -7 3 -3 -8 4 -4 -9 5 -5 -10 11 # (j1 l1 j2)(j2 l2 j3)(j3 l3 j4)(j4 l4 j5)(j5 l5 k1)\n");
|
||||
inpGtria.append(
|
||||
"-11 6 12 -12 7 13 -13 8 14 -14 9 15 -15 10 -1 # (k1 l1 k2)(k2 l2 k3)(k3 l3 k4)(k4 l4 k5)(k5 l5 j1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 5:
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append(
|
||||
"-1 -6 2 -2 -7 3 -3 -8 4 -4 -9 5 1 -5 -10 # (j1 l1 j2)(j2 l2 j3)(j3 l3 j4)(j4 l4 j5)(j1 j5 l5)\n");
|
||||
inpGtria.append(
|
||||
"11 -15 10 9 15 -14 8 14 -13 7 13 -12 6 12 -11 # (k1 k5 l5)(l4 k5 k4)(l3 k4 k3)(l2 k3 k2)(l1 k2 k1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 6:
|
||||
/*
|
||||
* Yutsis Figure 20.4a, index map. k1=1, k1'=2, k=3, k'=4, k2=5,
|
||||
* k2'=6 p1=7, p=8, p2=9, j1=10, j1'=11 j=12 j'=13 j2=14 j2'=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append(
|
||||
"-13 -12 -8 12 14 10 -10 -1 7 -7 -11 -2 2 4 6 # (j' j p)(j j2 j1)(j1 k1 p1)(p1 j1' k1')(k1' k' k2')\n");
|
||||
inpGtria.append(
|
||||
"-4 -3 8 1 3 5 -14 -5 9 -15 -6 -9 15 11 13 # (k' k p)(k1 k k2)(j2 k2 p2)(j2' k2' p2)(j2' j1' j')");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 7:
|
||||
/*
|
||||
* Yutsis Figure 20.5a, index map. j1=1, k1=2 s1=3 k1'=4 j1'=5 p=6
|
||||
* l=7 s=8 l'=9 p'=10 j2=11 k2=12 s2=13 k2'=14 j2'=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append(
|
||||
"-14 -12 -8 12 11 -10 -11 13 -7 7 -1 3 2 1 6 # (k2' k2 s)(k2 j2 p')(j2 s2 l)(l j1 s1)(k1 j1 p)\n");
|
||||
inpGtria.append(
|
||||
"-4 -2 8 10 4 5 9 -5 -3 -13 -9 -15 15 -6 14 # (k1' k1 s)(p' k1' j1')(l' j1' s1)(s2 l' j2')(j2' p k2')");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 8:
|
||||
/*
|
||||
* Yutsis Figure 20.6, index map. k1=1 k1'=2 j1=3 l1=4 l1'=5 k2=6
|
||||
* k2'=7 j2=8 l2=9 l2'=10 k3=11 k3'=12 j3=13 l3=14 l3'=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append(
|
||||
"-15 1 -7 -4 -11 7 5 4 -3 -12 -5 6 12 -9 -1 # (l3' k1 k2')(l1 k3 k2')(l1' l1 j1)(k3' l1' k2)(k3' l2 k1)\n");
|
||||
inpGtria.append(
|
||||
"9 -8 10 -10 11 -2 -14 -6 2 14 -13 15 3 8 13 # (l2 j2 l2')(l2' k3 k1')(l3 k2 k1')(l3 j3 l3')(j1 j2 j3)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 0:
|
||||
inpGtria.setText("6\n");
|
||||
inpGtria.append("1 2 -3 -1 5 6\n");
|
||||
inpGtria.append("4 -5 3 -4 -2 -6");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 1:
|
||||
/*
|
||||
* Yutsis Figure 18.1 index map. j1=1, j2=2, j3=3 k1=4, k2=5,
|
||||
* k3=6
|
||||
* l1=7, l2=8, l3=9
|
||||
*/
|
||||
inpGtria.setText("9\n");
|
||||
inpGtria.append("1 3 2 4 6 5 7 9 8 # (j1 j3 j2) (k1 k3 k2) (l1 l3 l2)\n");
|
||||
inpGtria.append("-2 -8 -5 -6 -3 -9 -7 -4 -1 # (j2 l2 k2) (k3 j3 l3) (l1 k1 j1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 2:
|
||||
/*
|
||||
* Yutsis Figure 19.1 and 19.2, index map, including the sign
|
||||
* reveral of the l. Assume input order j1..j4, l1..l4, k1..k4.
|
||||
* j1=1, j2=2, j3=3, j4=4 l1=5, l2=6, l3=7, l4=8 k1=9, k2=10,
|
||||
* k3=11,
|
||||
* k4=12
|
||||
*/
|
||||
inpGtria.setText("12\n");
|
||||
inpGtria.append("1 12 -8 -1 5 -2 2 6 -3 3 7 -4 # (j1 k4 l4) (j1 l1 j2) (j2 l2 j3) (j3 l3 j4)\n");
|
||||
inpGtria.append("4 8 -9 9 -5 -10 10 -6 -11 11 -7 -12 # (j4 l4 k1) (k1 l1 k2) (k2 l2 k3) (k3 l3 k4)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 3:
|
||||
inpGtria.setText("12\n");
|
||||
inpGtria.append("1 5 9 -9 -2 -7 2 11 8 -8 -12 -4 # (j1 l1 k1) (k1 j2 l3 ) (j2 k3 l4) (l4 k4 j4)\n");
|
||||
inpGtria.append("4 7 10 -10 -3 -5 3 6 12 -6 -11 -1 # (j4 l3 k2) (k2 j3 l1) (j3 l2 k4) (l2 k3 j1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 4:
|
||||
/*
|
||||
* Yutsis Figure 20.2 to 20.3, index map. j1=1, j2=2, j3=3,
|
||||
* j4=4,
|
||||
* j5=5 l1=6, l2=7, l3=8, l4=9, l5=10 k1=11, k2=12, k3=13,
|
||||
* k4=14,
|
||||
* k5=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("1 -6 2 -2 -7 3 -3 -8 4 -4 -9 5 -5 -10 11 # (j1 l1 j2)(j2 l2 j3)(j3 l3 j4)(j4 l4 j5)(j5 l5 k1)\n");
|
||||
inpGtria.append("-11 6 12 -12 7 13 -13 8 14 -14 9 15 -15 10 -1 # (k1 l1 k2)(k2 l2 k3)(k3 l3 k4)(k4 l4 k5)(k5 l5 j1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 5:
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("-1 -6 2 -2 -7 3 -3 -8 4 -4 -9 5 1 -5 -10 # (j1 l1 j2)(j2 l2 j3)(j3 l3 j4)(j4 l4 j5)(j1 j5 l5)\n");
|
||||
inpGtria.append("11 -15 10 9 15 -14 8 14 -13 7 13 -12 6 12 -11 # (k1 k5 l5)(l4 k5 k4)(l3 k4 k3)(l2 k3 k2)(l1 k2 k1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 6:
|
||||
/*
|
||||
* Yutsis Figure 20.4a, index map. k1=1, k1'=2, k=3, k'=4, k2=5,
|
||||
* k2'=6 p1=7, p=8, p2=9, j1=10, j1'=11 j=12 j'=13 j2=14 j2'=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("-13 -12 -8 12 14 10 -10 -1 7 -7 -11 -2 2 4 6 # (j' j p)(j j2 j1)(j1 k1 p1)(p1 j1' k1')(k1' k' k2')\n");
|
||||
inpGtria.append("-4 -3 8 1 3 5 -14 -5 9 -15 -6 -9 15 11 13 # (k' k p)(k1 k k2)(j2 k2 p2)(j2' k2' p2)(j2' j1' j')");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 7:
|
||||
/*
|
||||
* Yutsis Figure 20.5a, index map. j1=1, k1=2 s1=3 k1'=4 j1'=5
|
||||
* p=6
|
||||
* l=7 s=8 l'=9 p'=10 j2=11 k2=12 s2=13 k2'=14 j2'=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("-14 -12 -8 12 11 -10 -11 13 -7 7 -1 3 2 1 6 # (k2' k2 s)(k2 j2 p')(j2 s2 l)(l j1 s1)(k1 j1 p)\n");
|
||||
inpGtria.append("-4 -2 8 10 4 5 9 -5 -3 -13 -9 -15 15 -6 14 # (k1' k1 s)(p' k1' j1')(l' j1' s1)(s2 l' j2')(j2' p k2')");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 8:
|
||||
/*
|
||||
* Yutsis Figure 20.6, index map. k1=1 k1'=2 j1=3 l1=4 l1'=5
|
||||
* k2=6
|
||||
* k2'=7 j2=8 l2=9 l2'=10 k3=11 k3'=12 j3=13 l3=14 l3'=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("-15 1 -7 -4 -11 7 5 4 -3 -12 -5 6 12 -9 -1 # (l3' k1 k2')(l1 k3 k2')(l1' l1 j1)(k3' l1' k2)(k3' l2 k1)\n");
|
||||
inpGtria.append("9 -8 10 -10 11 -2 -14 -6 2 14 -13 15 3 8 13 # (l2 j2 l2')(l2' k3 k1')(l3 k2 k1')(l3 j3 l3')(j1 j2 j3)");
|
||||
outG.setText("");
|
||||
break;
|
||||
}
|
||||
} /* valueChanged */
|
||||
|
||||
|
529
src/org/warp/device/Keyboard.java
Normal file
529
src/org/warp/device/Keyboard.java
Normal file
@ -0,0 +1,529 @@
|
||||
package org.warp.device;
|
||||
|
||||
import org.warp.engine.Display;
|
||||
import org.warp.engine.Screen;
|
||||
import org.warp.picalculator.Calculator;
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.device.chip.ParallelToSerial;
|
||||
import org.warp.picalculator.device.chip.SerialToParallel;
|
||||
import org.warp.picalculator.screens.MarioScreen;
|
||||
|
||||
import com.pi4j.wiringpi.Gpio;
|
||||
|
||||
public class Keyboard {
|
||||
public static volatile boolean alpha = false;
|
||||
public static volatile boolean shift = false;
|
||||
|
||||
//From Serial
|
||||
private static final int RCK_pin = 35;
|
||||
private static final int SCK_and_CLK_pin = 38;
|
||||
private static final int SER_pin = 36;
|
||||
|
||||
//To Serial
|
||||
private static final int SH_LD_pin = 37;
|
||||
private static final int QH_pin = 40;
|
||||
private static final int CLK_INH_pin = 33;
|
||||
|
||||
private static boolean[][] precedentStates = new boolean[8][8];
|
||||
|
||||
public static void startKeyboard() {
|
||||
if (Utils.debugOn == false) {
|
||||
Gpio.pinMode(CLK_INH_pin, Gpio.OUTPUT);
|
||||
Gpio.pinMode(RCK_pin, Gpio.OUTPUT);
|
||||
Gpio.pinMode(SER_pin, Gpio.OUTPUT);
|
||||
Gpio.pinMode(SH_LD_pin, Gpio.OUTPUT);
|
||||
Gpio.pinMode(SCK_and_CLK_pin, Gpio.OUTPUT);
|
||||
Gpio.pinMode(QH_pin, Gpio.INPUT);
|
||||
|
||||
Gpio.digitalWrite(CLK_INH_pin, false);
|
||||
Gpio.digitalWrite(RCK_pin, false);
|
||||
Gpio.digitalWrite(SER_pin, false);
|
||||
Gpio.digitalWrite(SH_LD_pin, false);
|
||||
Gpio.digitalWrite(SCK_and_CLK_pin, false);
|
||||
Gpio.digitalWrite(QH_pin, false);
|
||||
Thread kt = new Thread(()->{
|
||||
SerialToParallel chip1 = new SerialToParallel(RCK_pin, SCK_and_CLK_pin /*SCK*/, SER_pin);
|
||||
ParallelToSerial chip2 = new ParallelToSerial(SH_LD_pin, CLK_INH_pin, QH_pin, SCK_and_CLK_pin/*CLK*/);
|
||||
while(true) {
|
||||
boolean[] data;
|
||||
for (int col = 0; col < 8; col++) {
|
||||
data = new boolean[8];
|
||||
data[col] = true;
|
||||
chip1.write(data);
|
||||
|
||||
data = new boolean[8];
|
||||
data = chip2.read();
|
||||
|
||||
for (int row = 0; row < 8; row++) {
|
||||
if (data[row] == true && precedentStates[row][col] == false) {
|
||||
System.out.println("Pressed button at "+(row+1) +", "+(col+1));
|
||||
keyPressedRaw(row+1, col+1);
|
||||
} else if (data[row] == false && precedentStates[row][col] == true) {
|
||||
keyReleasedRaw(row+1, col+1);
|
||||
}
|
||||
precedentStates[row][col] = data[row];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
kt.setName("Keyboard thread");
|
||||
kt.setPriority(Thread.MIN_PRIORITY);
|
||||
kt.setDaemon(true);
|
||||
kt.start();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isKeyDown(int row, int col) {
|
||||
return precedentStates[row][col];
|
||||
}
|
||||
|
||||
private static void keyReleasedRaw(int row, int col) {
|
||||
if (row == 1 && col == 1) {
|
||||
keyReleased(Key.BRIGHTNESS_CYCLE);
|
||||
}
|
||||
}
|
||||
|
||||
private static void keyPressedRaw(int row, int col) {
|
||||
if (row == 1 && col == 1) {
|
||||
keyPressed(Key.SHIFT);
|
||||
} else if (row == 1 && col == 2) {
|
||||
keyPressed(Key.ALPHA);
|
||||
} else if (row == 1 && col == 7) {
|
||||
if (shift) {
|
||||
keyPressed(Key.BRIGHTNESS_CYCLE_REVERSE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.BRIGHTNESS_CYCLE);
|
||||
}
|
||||
} else if (row == 1 && col == 8) {
|
||||
if (shift) {
|
||||
keyPressed(Key.SIMPLIFY);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.SOLVE);
|
||||
}
|
||||
} else if (row == 2 && col == 8) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.DRG_CYCLE);
|
||||
} else {
|
||||
keyPressed(Key.NONE);
|
||||
}
|
||||
} else if (row == 3 && col == 2) {
|
||||
if (shift) {
|
||||
keyPressed(Key.ROOT);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.SQRT);
|
||||
}
|
||||
} else if (row == 4 && col == 8) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.DOT);
|
||||
}
|
||||
} else if (row == 5 && col == 8) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM0);
|
||||
}
|
||||
} else if (row == 8 && col == 1) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM1);
|
||||
}
|
||||
} else if (row == 8 && col == 2) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM2);
|
||||
}
|
||||
} else if (row == 8 && col == 3) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM3);
|
||||
}
|
||||
} else if (row == 7 && col == 1) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM4);
|
||||
}
|
||||
} else if (row == 7 && col == 2) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM5);
|
||||
}
|
||||
} else if (row == 7 && col == 3) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM6);
|
||||
}
|
||||
} else if (row == 6 && col == 1) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM7);
|
||||
}
|
||||
} else if (row == 6 && col == 2) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM8);
|
||||
}
|
||||
} else if (row == 6 && col == 3) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.NUM9);
|
||||
}
|
||||
} else if (row == 8 && col == 4) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.PLUS);
|
||||
}
|
||||
} else if (row == 8 && col == 5) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.MINUS);
|
||||
}
|
||||
} else if (row == 7 && col == 4) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.MULTIPLY);
|
||||
}
|
||||
} else if (row == 7 && col == 5) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.DIVIDE);
|
||||
}
|
||||
} else if (row == 6 && col == 4) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.DELETE);
|
||||
}
|
||||
} else if (row == 6 && col == 5) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.RESET);
|
||||
}
|
||||
} else if (row == 1 && col == 4) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.UP);
|
||||
}
|
||||
} else if (row == 2 && col == 3) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.LEFT);
|
||||
}
|
||||
} else if (row ==2 && col == 5) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.RIGHT);
|
||||
}
|
||||
} else if (row == 3 && col == 4) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.DOWN);
|
||||
}
|
||||
} else if (row == 4 && col == 3) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.POWER_OF_2);
|
||||
}
|
||||
} else if (row == 4 && col == 4) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.POWER_OF_x);
|
||||
}
|
||||
} else if (row == 5 && col == 3) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.PARENTHESIS_OPEN);
|
||||
}
|
||||
} else if (row == 5 && col == 4) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.PARENTHESIS_CLOSE);
|
||||
}
|
||||
} else if (row == 2 && col == 1) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
keyPressed(Key.EQUAL);
|
||||
}
|
||||
} else if (row == 2 && col == 6) {
|
||||
System.out.println("PREMUTO <");
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
System.out.println("PREMUTO <");
|
||||
keyPressed(Key.HISTORY_BACK);
|
||||
}
|
||||
} else if (row == 2 && col == 7) {
|
||||
System.out.println("PREMUTO >");
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
keyPressed(Key.NONE);
|
||||
} else {
|
||||
System.out.println("PREMUTO >");
|
||||
keyPressed(Key.HISTORY_FORWARD);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
public static void stopKeyboard() {
|
||||
if (Utils.debugOn == false) {
|
||||
Gpio.digitalWrite(33, false);
|
||||
Gpio.digitalWrite(35, false);
|
||||
Gpio.digitalWrite(36, false);
|
||||
Gpio.digitalWrite(37, false);
|
||||
Gpio.digitalWrite(38, false);
|
||||
Gpio.digitalWrite(40, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void keyPressed(Key k) {
|
||||
if (Main.d != null) {
|
||||
Screen scr = Main.d.getScreen();
|
||||
boolean refresh = false;
|
||||
if(scr != null && scr.initialized && scr.keyPressed(k)) {
|
||||
refresh = true;
|
||||
} else {
|
||||
switch (k) {
|
||||
case POWER:
|
||||
Display.destroy();
|
||||
break;
|
||||
case NONE:
|
||||
break;
|
||||
case debug_DEG:
|
||||
if (Calculator.angleMode.equals("deg") == false) {
|
||||
refresh = true;
|
||||
}
|
||||
Calculator.angleMode = "deg";
|
||||
break;
|
||||
case debug_RAD:
|
||||
if (Calculator.angleMode.equals("rad") == false) {
|
||||
refresh = true;
|
||||
}
|
||||
Calculator.angleMode = "rad";
|
||||
break;
|
||||
case debug_GRA:
|
||||
if (Calculator.angleMode.equals("gra") == false) {
|
||||
refresh = true;
|
||||
}
|
||||
Calculator.angleMode = "gra";
|
||||
break;
|
||||
case DRG_CYCLE:
|
||||
if (Calculator.angleMode.equals("deg") == true) {
|
||||
Calculator.angleMode = "rad";
|
||||
} else if (Calculator.angleMode.equals("rad") == true) {
|
||||
Calculator.angleMode = "gra";
|
||||
} else {
|
||||
Calculator.angleMode = "deg";
|
||||
}
|
||||
refresh = true;
|
||||
break;
|
||||
case LETTER_X:
|
||||
letterPressed('X');
|
||||
break;
|
||||
case BRIGHTNESS_CYCLE:
|
||||
PIDisplay.cycleBrightness(false);
|
||||
refresh = true;
|
||||
break;
|
||||
case BRIGHTNESS_CYCLE_REVERSE:
|
||||
PIDisplay.INSTANCE.setScreen(new MarioScreen()); //TODO: rimuovere: prova
|
||||
PIDisplay.cycleBrightness(true);
|
||||
refresh = true;
|
||||
break;
|
||||
case HISTORY_BACK:
|
||||
PIDisplay.INSTANCE.goBack();
|
||||
refresh = true;
|
||||
break;
|
||||
case HISTORY_FORWARD:
|
||||
PIDisplay.INSTANCE.goForward();
|
||||
refresh = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (k) {
|
||||
case SHIFT:
|
||||
Keyboard.shift = !Keyboard.shift;
|
||||
refresh = true;
|
||||
break;
|
||||
case ALPHA:
|
||||
Keyboard.alpha = !Keyboard.alpha;
|
||||
refresh = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (k != Key.SHIFT && Keyboard.shift) {
|
||||
Keyboard.shift = false;
|
||||
refresh = true;
|
||||
} else if (k != Key.ALPHA && Keyboard.alpha) {
|
||||
Keyboard.alpha = false;
|
||||
refresh = true;
|
||||
}
|
||||
if (refresh) {
|
||||
Display.refresh(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void letterPressed(char L) {
|
||||
|
||||
}
|
||||
|
||||
public static void keyReleased(Key k) {
|
||||
boolean refresh = false;
|
||||
if (Main.d != null) {
|
||||
Screen scr = Main.d.getScreen();
|
||||
if(scr != null && scr.initialized && scr.keyReleased(k)) {
|
||||
refresh = true;
|
||||
} else {
|
||||
switch (k) {
|
||||
case NONE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (refresh) {
|
||||
Display.refresh(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Key {
|
||||
POWER, debug_DEG, debug_RAD, debug_GRA, SHIFT, ALPHA, NONE, HISTORY_BACK, HISTORY_FORWARD, DRG_CYCLE, LETTER_X, SIMPLIFY, SOLVE, BRIGHTNESS_CYCLE, BRIGHTNESS_CYCLE_REVERSE, DOT, NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7, NUM8, NUM9, PARENTHESIS_OPEN, PARENTHESIS_CLOSE, PLUS, MINUS, MULTIPLY, DIVIDE, EQUAL, DELETE, RESET, LEFT, RIGHT, UP, DOWN, OK, debug1, debug2, debug3, debug4, debug5, SQRT, ROOT, POWER_OF_2, POWER_OF_x
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|1,1---|1,2---|------|1,4---|------|------|1,7---|
|
||||
|SHIFT |ALPHA |------| ^ |------|------|+BRIGH|
|
||||
|SHIFT |ALPHA |------| |------|------|-BRIGH|
|
||||
|SHIFT |ALPHA |------| |------|------| |
|
||||
|2,1---|2,2---|2,3---|2,4---|2,5---|2,6---|2,7---|
|
||||
| = | | < | OK | > | Back | Fwd |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
|3,1---|3,2---|------|3,4---|------|3,6---|3,7---|
|
||||
| | SQRT |------| v |------| | |
|
||||
| | ROOT |------| |------| | |
|
||||
| | |------| |------| | |
|
||||
|4,1---|4,2---|4,3---|4,4---|4,5---|4,6---|4,7---|
|
||||
| | | POW 2| POW x| | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
|5,1---|5,2---|5,3---|5,4---|5,5---|5,6---|5,7---|
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
|6,1---|6,2---|6,3---|6,4---|6,5---|6,6---|6,7---|
|
||||
| 7 | 8 | 9 | DEL | RESET |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
|7,1---|7,2---|7,3---|7,4---|7,5-----------------|
|
||||
| 4 | 5 | 6 | * | / |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
|8,1---|8,2---|8,3---|8,4---|8,5-----------------|
|
||||
| 1 | 2 | 3 | + | - |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
|5,8---|4,8---|3,8---|2,8---|1,8-----------------|
|
||||
| 0 | . | | | SOLVE |
|
||||
| | | | | SIMPLIFY |
|
||||
| | | |DRGCYCL| |
|
||||
|------|------|------|------|--------------------|
|
||||
|
||||
|
||||
*/
|
472
src/org/warp/device/PIDisplay.java
Normal file
472
src/org/warp/device/PIDisplay.java
Normal file
@ -0,0 +1,472 @@
|
||||
package org.warp.device;
|
||||
|
||||
import static org.warp.engine.Display.Render.getMatrixOfImage;
|
||||
import static org.warp.engine.Display.Render.glClear;
|
||||
import static org.warp.engine.Display.Render.glColor3f;
|
||||
import static org.warp.engine.Display.Render.glColor4f;
|
||||
import static org.warp.engine.Display.Render.glDrawLine;
|
||||
import static org.warp.engine.Display.Render.glDrawSkin;
|
||||
import static org.warp.engine.Display.Render.glDrawStringCenter;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
import static org.warp.engine.Display.Render.glDrawStringRight;
|
||||
import static org.warp.engine.Display.Render.setFont;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.warp.engine.Display;
|
||||
import org.warp.engine.Display.Startable;
|
||||
import org.warp.engine.RAWFont;
|
||||
import org.warp.engine.Screen;
|
||||
import org.warp.picalculator.Calculator;
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.Utils;
|
||||
|
||||
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;
|
||||
|
||||
private int[] skin;
|
||||
private int[] skinSize;
|
||||
public static RAWFont[] fonts = new RAWFont[2];
|
||||
|
||||
public static boolean loading = true;
|
||||
public static String error = null;
|
||||
public String[] errorStackTrace = null;
|
||||
public final int[] glyphsHeight = new int[] { 9, 6 };
|
||||
public float loadingTextTranslation = 0.0f;
|
||||
public boolean loadingTextTranslationTopToBottom = true;
|
||||
|
||||
public static Screen screen;
|
||||
public static String displayDebugString = "";
|
||||
|
||||
public PIDisplay(Screen screen) {
|
||||
setScreen(screen);
|
||||
INSTANCE = this;
|
||||
}
|
||||
/*
|
||||
* private void load_skin() {
|
||||
* try {
|
||||
* skin_tex = glGenTextures();
|
||||
* glBindTexture(GL_TEXTURE_2D, skin_tex);
|
||||
* glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
*
|
||||
* InputStream in = new FileInputStream("skin.png");
|
||||
* PNGDecoder decoder = new PNGDecoder(in);
|
||||
*
|
||||
* System.out.println("width="+decoder.getWidth());
|
||||
* System.out.println("height="+decoder.getHeight());
|
||||
*
|
||||
* ByteBuffer buf =
|
||||
* ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight());
|
||||
* decoder.decode(buf, decoder.getWidth()*4, Format.RGBA);
|
||||
* buf.flip();
|
||||
*
|
||||
* skin = buf;
|
||||
* skin_w = decoder.getWidth();
|
||||
* skin_h = decoder.getHeight();
|
||||
* glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, skin_w,
|
||||
* skin_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, skin);
|
||||
* } catch (IOException ex) {
|
||||
* ex.printStackTrace();
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
public void setScreen(Screen screen) {
|
||||
if (screen.initialized == false) {
|
||||
if (screen.canBeInHistory) {
|
||||
Calculator.currentSession = 0;
|
||||
for (int i = Calculator.sessions.length - 1; i >= 1; i--) {
|
||||
Calculator.sessions[i] = Calculator.sessions[i - 1];
|
||||
}
|
||||
Calculator.sessions[0] = screen;
|
||||
} else {
|
||||
Calculator.currentSession = -1;
|
||||
}
|
||||
}
|
||||
screen.d = this;
|
||||
try {
|
||||
screen.create();
|
||||
PIDisplay.screen = screen;
|
||||
if (initialized == true && screen.initialized == false) {
|
||||
screen.initialize();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canGoBack() {
|
||||
if (Calculator.currentSession == -1) {
|
||||
return Calculator.sessions[0] != null;
|
||||
}
|
||||
if (PIDisplay.screen != Calculator.sessions[Calculator.currentSession]) {
|
||||
|
||||
} else if (Calculator.currentSession + 1 < Calculator.sessions.length) {
|
||||
if (Calculator.sessions[Calculator.currentSession + 1] != null) {
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (Calculator.sessions[Calculator.currentSession] != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void goBack() {
|
||||
if (canGoBack()) {
|
||||
if (Calculator.currentSession >= 0 && PIDisplay.screen != Calculator.sessions[Calculator.currentSession]) {
|
||||
} else {
|
||||
Calculator.currentSession += 1;
|
||||
}
|
||||
PIDisplay.screen = Calculator.sessions[Calculator.currentSession];
|
||||
Utils.debug.println("Current session: " + Calculator.currentSession);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canGoForward() {
|
||||
if (Calculator.currentSession <= 0) { // -1 e 0
|
||||
return false;
|
||||
}
|
||||
if (PIDisplay.screen != Calculator.sessions[Calculator.currentSession]) {
|
||||
|
||||
} else if (Calculator.currentSession > 0) {
|
||||
if (Calculator.sessions[Calculator.currentSession - 1] != null) {
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (Calculator.sessions[Calculator.currentSession] != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void goForward() {
|
||||
if (canGoForward()) {
|
||||
if (PIDisplay.screen != Calculator.sessions[Calculator.currentSession]) {
|
||||
|
||||
} else {
|
||||
Calculator.currentSession -= 1;
|
||||
}
|
||||
PIDisplay.screen = Calculator.sessions[Calculator.currentSession];
|
||||
}
|
||||
}
|
||||
|
||||
public Screen getScreen() {
|
||||
return PIDisplay.screen;
|
||||
}
|
||||
|
||||
private void load_skin() throws IOException {
|
||||
BufferedImage img = ImageIO.read(Main.instance.getClass().getResource("/skin.png"));
|
||||
skin = getMatrixOfImage(img);
|
||||
skinSize = new int[] { img.getWidth(), img.getHeight() };
|
||||
}
|
||||
|
||||
private void load_fonts() {
|
||||
fonts[0] = new RAWFont();
|
||||
fonts[0].create("big");
|
||||
fonts[1] = new RAWFont();
|
||||
fonts[1].create("small");
|
||||
setFont(fonts[0]);
|
||||
}
|
||||
|
||||
private void draw_init() {
|
||||
glClear();
|
||||
}
|
||||
|
||||
public void drawSkinPart(int x, int y, int sx1, int sy1, int sx2, int sy2) {
|
||||
glDrawSkin(skinSize[0], skin, x, y, sx1, sy1, sx2, sy2, false);
|
||||
}
|
||||
|
||||
private void draw_status() {
|
||||
glColor3f(0, 0, 0);
|
||||
glDrawLine(0, 20, Main.screenSize[0]-1, 20);
|
||||
glColor3f(0, 0, 0);
|
||||
if (Keyboard.shift) {
|
||||
drawSkinPart(2 + 18 * 0, 2, 16 * 2, 16 * 0, 16 + 16 * 2, 16 + 16 * 0);
|
||||
} else {
|
||||
drawSkinPart(2 + 18 * 0, 2, 16 * 3, 16 * 0, 16 + 16 * 3, 16 + 16 * 0);
|
||||
}
|
||||
if (Keyboard.alpha) {
|
||||
drawSkinPart(2 + 18 * 1, 2, 16 * 0, 16 * 0, 16 + 16 * 0, 16 + 16 * 0);
|
||||
} else {
|
||||
drawSkinPart(2 + 18 * 1, 2, 16 * 1, 16 * 0, 16 + 16 * 1, 16 + 16 * 0);
|
||||
}
|
||||
if (Calculator.angleMode == "deg") {
|
||||
drawSkinPart(8 + 18 * 2, 2, 16 * 4, 16 * 0, 16 + 16 * 4, 16 + 16 * 0);
|
||||
drawSkinPart(8 + 18 * 3, 2, 16 * 7, 16 * 0, 16 + 16 * 7, 16 + 16 * 0);
|
||||
drawSkinPart(8 + 18 * 4, 2, 16 * 9, 16 * 0, 16 + 16 * 9, 16 + 16 * 0);
|
||||
} else if (Calculator.angleMode == "rad") {
|
||||
drawSkinPart(8 + 18 * 2, 2, 16 * 5, 16 * 0, 16 + 16 * 5, 16 + 16 * 0);
|
||||
drawSkinPart(8 + 18 * 3, 2, 16 * 6, 16 * 0, 16 + 16 * 6, 16 + 16 * 0);
|
||||
drawSkinPart(8 + 18 * 4, 2, 16 * 9, 16 * 0, 16 + 16 * 9, 16 + 16 * 0);
|
||||
} else if (Calculator.angleMode == "gra") {
|
||||
drawSkinPart(8 + 18 * 2, 2, 16 * 5, 16 * 0, 16 + 16 * 5, 16 + 16 * 0);
|
||||
drawSkinPart(8 + 18 * 3, 2, 16 * 7, 16 * 0, 16 + 16 * 7, 16 + 16 * 0);
|
||||
drawSkinPart(8 + 18 * 4, 2, 16 * 8, 16 * 0, 16 + 16 * 8, 16 + 16 * 0);
|
||||
} else {
|
||||
drawSkinPart(8 + 18 * 2, 2, 16 * 5, 16 * 0, 16 + 16 * 5, 16 + 16 * 0);
|
||||
drawSkinPart(8 + 18 * 3, 2, 16 * 7, 16 * 0, 16 + 16 * 7, 16 + 16 * 0);
|
||||
drawSkinPart(8 + 18 * 4, 2, 16 * 9, 16 * 0, 16 + 16 * 9, 16 + 16 * 0);
|
||||
}
|
||||
|
||||
int padding = 2;
|
||||
|
||||
int brightness = (int) (Math.ceil(PIDisplay.brightness * 4));
|
||||
if (brightness <= 1) {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 10, 16 * 0, 16 + 16 * 10, 16 + 16 * 0);
|
||||
} else if (brightness == 2) {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 11, 16 * 0, 16 + 16 * 11, 16 + 16 * 0);
|
||||
} else if (brightness == 3) {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 12, 16 * 0, 16 + 16 * 12, 16 + 16 * 0);
|
||||
} else if (brightness >= 4) {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 13, 16 * 0, 16 + 16 * 13, 16 + 16 * 0);
|
||||
} else {
|
||||
Utils.debug.println("Brightness error");
|
||||
}
|
||||
|
||||
padding += 18 + 6;
|
||||
|
||||
boolean canGoBack = canGoBack();
|
||||
boolean canGoForward = canGoForward();
|
||||
|
||||
if (Calculator.haxMode) {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 18, 16 * 0, 16 + 16 * 18, 16 + 16 * 0);
|
||||
padding += 18 + 6;
|
||||
}
|
||||
|
||||
if (canGoBack && canGoForward) {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 14, 16 * 0, 16 + 16 * 14, 16 + 16 * 0);
|
||||
} else if (canGoBack) {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 15, 16 * 0, 16 + 16 * 15, 16 + 16 * 0);
|
||||
} else if (canGoForward) {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 16, 16 * 0, 16 + 16 * 16, 16 + 16 * 0);
|
||||
} else {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 17, 16 * 0, 16 + 16 * 17, 16 + 16 * 0);
|
||||
}
|
||||
|
||||
padding += 18;
|
||||
|
||||
}
|
||||
|
||||
private void draw_screen() {
|
||||
screen.render();
|
||||
}
|
||||
|
||||
private void draw_bottom() {
|
||||
glDrawStringLeft(2, 90, displayDebugString);
|
||||
}
|
||||
|
||||
private void draw_world() {
|
||||
glColor3f(255, 255, 255);
|
||||
|
||||
if (error != null) {
|
||||
setFont(fonts[1]);
|
||||
glColor3f(129, 28, 22);
|
||||
glDrawStringRight(Main.screenSize[0] - 2, Main.screenSize[1]- this.glyphsHeight[1] - 2, "ANDREA CAVALLI'S CALCULATOR");
|
||||
glColor3f(149, 32, 26);
|
||||
glDrawStringCenter((Main.screenSize[0] / 2), 22, error);
|
||||
glColor3f(164, 34, 28);
|
||||
int i = 22;
|
||||
for (String stackPart : errorStackTrace) {
|
||||
glDrawStringLeft(2, 22 + i, stackPart);
|
||||
i += 11;
|
||||
}
|
||||
setFont(fonts[0]);
|
||||
glColor3f(129, 28, 22);
|
||||
glDrawStringCenter((Main.screenSize[0] / 2), 11, "UNEXPECTED EXCEPTION");
|
||||
} else if (loading) {
|
||||
setFont(fonts[0]);
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDrawStringCenter((Main.screenSize[0] / 2) - 1,(int) ((Main.screenSize[1]/ 2) - 25 + loadingTextTranslation), "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDrawStringCenter((Main.screenSize[0] / 2) + 1,(int) ((Main.screenSize[1]/ 2) - 25 + loadingTextTranslation), "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1]/ 2) - 25 - 1 + loadingTextTranslation), "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1]/ 2) - 25 + 1 + loadingTextTranslation), "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(1.0f, 0.5f, 0.0f, 1.0f);
|
||||
glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1]/ 2) - 25 + loadingTextTranslation), "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(0.0f, 0.0f, 0.0f, 0.75f);
|
||||
glDrawStringCenter((Main.screenSize[0] / 2), (Main.screenSize[1]/ 2) + 11, "LOADING");
|
||||
setFont(fonts[1]);
|
||||
colore(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
glDrawStringCenter((Main.screenSize[0] / 2), (Main.screenSize[1]/ 2) + 22, "PLEASE WAIT...");
|
||||
} else {
|
||||
draw_status();
|
||||
draw_screen();
|
||||
draw_bottom();
|
||||
}
|
||||
}
|
||||
|
||||
private void draw() {
|
||||
draw_init();
|
||||
draw_world();
|
||||
}
|
||||
|
||||
private long precTime = -1;
|
||||
|
||||
private void refresh(boolean forced) {
|
||||
float dt = 0;
|
||||
long newtime = System.nanoTime();
|
||||
if (precTime == -1) {
|
||||
dt = 0;
|
||||
} else {
|
||||
dt = (float) ((newtime - precTime) / 1000000000d);
|
||||
if (dt < 0.03 && !forced) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
precTime = newtime;
|
||||
/*
|
||||
* Calcoli
|
||||
*/
|
||||
checkDisplayResized();
|
||||
|
||||
if (loading) {
|
||||
if (loadingTextTranslation >= 10.0f) {
|
||||
loadingTextTranslation = 10.0f;
|
||||
loadingTextTranslationTopToBottom = false;
|
||||
} else if (loadingTextTranslation <= -10.0f) {
|
||||
loadingTextTranslation = -10.0f;
|
||||
loadingTextTranslationTopToBottom = true;
|
||||
}
|
||||
|
||||
if (loadingTextTranslationTopToBottom) {
|
||||
loadingTextTranslation += dt * 15;
|
||||
} else {
|
||||
loadingTextTranslation -= dt * 15;
|
||||
}
|
||||
}
|
||||
|
||||
screen.beforeRender(dt);
|
||||
|
||||
if(forced==true || screen.mustBeRefreshed() || loading) {
|
||||
draw();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private volatile Startable refresh = new Startable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PIDisplay.this.refresh(this.force);
|
||||
}
|
||||
};
|
||||
|
||||
private void checkDisplayResized() {
|
||||
if (Display.wasResized()) {
|
||||
Main.screenSize[0] = Display.getWidth();
|
||||
Main.screenSize[1]= Display.getHeight();
|
||||
}
|
||||
};
|
||||
|
||||
private void createWindow(String title) {
|
||||
Display.setTitle(title);
|
||||
Display.setResizable(false);
|
||||
Display.setDisplayMode(Main.screenSize[0], Main.screenSize[1]);
|
||||
Display.create();
|
||||
}
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
public void run(String title) {
|
||||
try {
|
||||
createWindow(title);
|
||||
load_skin();
|
||||
load_fonts();
|
||||
|
||||
initialized = true;
|
||||
|
||||
try {
|
||||
screen.initialize();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
Display.start(this.refresh);
|
||||
|
||||
Main.instance.afterStart();
|
||||
|
||||
double extratime = 0;
|
||||
while (Display.initialized()) {
|
||||
long start = System.nanoTime();
|
||||
Display.refresh(false);
|
||||
long end = System.nanoTime();
|
||||
double delta = (end - start) / 1000000000;
|
||||
int deltaInt = (int) Math.floor(delta);
|
||||
int extraTimeInt = (int) Math.floor(extratime);
|
||||
if (extraTimeInt + deltaInt < 50) {
|
||||
Thread.sleep(50 - (extraTimeInt + deltaInt));
|
||||
extratime = 0;
|
||||
} else {
|
||||
extratime += delta - 50d;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
public static void changeBrightness(float change) {
|
||||
setBrightness(brightness + change);
|
||||
}
|
||||
|
||||
public static void setBrightness(float newval) {
|
||||
if (newval >= 0.1 && newval <= 1) {
|
||||
brightness = newval;
|
||||
if (Utils.debugOn == false) {
|
||||
Gpio.pwmWrite(12, (int) Math.ceil(brightness*1024));
|
||||
// SoftPwm.softPwmWrite(12, (int)(Math.ceil(brightness*10)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void cycleBrightness(boolean reverse) {
|
||||
final float step = reverse?-0.1f:0.1f;
|
||||
if (brightness + step > 1f) {
|
||||
setBrightness(0.1f);
|
||||
} else if (brightness + step < 0.1f) {
|
||||
setBrightness(1.0f);
|
||||
} else {
|
||||
changeBrightness(step);
|
||||
}
|
||||
}
|
||||
|
||||
public static float getBrightness() {
|
||||
return brightness;
|
||||
}
|
||||
|
||||
public float[] colore = new float[] { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
|
||||
public void colore(float f1, float f2, float f3, float f4) {
|
||||
colore = new float[] { f1, f2, f3, f4 };
|
||||
glColor4f((int) (f1 * 255), (int) (f2 * 255), (int) (f3 * 255), (int) (f4 * 255));
|
||||
}
|
||||
}
|
402
src/org/warp/device/PIFrame.java
Normal file
402
src/org/warp/device/PIFrame.java
Normal file
@ -0,0 +1,402 @@
|
||||
package org.warp.device;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.warp.device.Keyboard.Key;
|
||||
import org.warp.engine.Display;
|
||||
|
||||
public class PIFrame extends JFrame {
|
||||
private static final long serialVersionUID = 2945898937634075491L;
|
||||
public CustomCanvas c;
|
||||
public boolean wasResized = false;
|
||||
|
||||
public PIFrame() {
|
||||
c = new CustomCanvas();
|
||||
c.setDoubleBuffered(true);
|
||||
this.add(c);
|
||||
this.setExtendedState(Frame.MAXIMIZED_BOTH);
|
||||
Toolkit.getDefaultToolkit().setDynamicLayout(false);
|
||||
// Transparent 16 x 16 pixel cursor image.
|
||||
BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
// Create a new blank cursor.
|
||||
Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");
|
||||
|
||||
// Set the blank cursor to the JFrame.
|
||||
getContentPane().setCursor(blankCursor);
|
||||
this.addComponentListener(new ComponentListener() {
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
Display.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent e) {}
|
||||
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
wasResized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {}
|
||||
});
|
||||
this.addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent arg0) {
|
||||
switch (arg0.getKeyCode()) {
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
Keyboard.keyPressed(Key.POWER);
|
||||
break;
|
||||
case KeyEvent.VK_D:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.debug_DEG);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_R:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.debug_RAD);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_G:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.debug_GRA);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_X:
|
||||
if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_X);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_B:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.BRIGHTNESS_CYCLE_REVERSE);
|
||||
} else if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.BRIGHTNESS_CYCLE);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_ENTER:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.SOLVE);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_1:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM1);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_2:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM2);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_3:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM3);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_4:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM4);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_5:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM5);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_6:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM6);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_7:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM7);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_8:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM8);
|
||||
} else if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.PARENTHESIS_OPEN);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_9:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM9);
|
||||
} else if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.PARENTHESIS_CLOSE);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_0:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM0);
|
||||
} else if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.EQUAL);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_ADD:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.PLUS);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_SUBTRACT:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.MINUS);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_MULTIPLY:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.MULTIPLY);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_DIVIDE:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.DIVIDE);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_BACK_SPACE:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.DELETE);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_DELETE:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.RESET);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_LEFT:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LEFT);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_RIGHT:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.RIGHT);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_NUMPAD4:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.HISTORY_BACK);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_NUMPAD6:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.HISTORY_FORWARD);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_PERIOD:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.DOT);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_SHIFT:
|
||||
Keyboard.keyPressed(Key.SHIFT);
|
||||
break;
|
||||
case KeyEvent.VK_A:
|
||||
Keyboard.keyPressed(Key.ALPHA);
|
||||
break;
|
||||
case KeyEvent.VK_NUMPAD1:
|
||||
Keyboard.keyPressed(Key.SQRT);
|
||||
break;
|
||||
case KeyEvent.VK_NUMPAD2:
|
||||
Keyboard.keyPressed(Key.ROOT);
|
||||
break;
|
||||
case KeyEvent.VK_NUMPAD3:
|
||||
Keyboard.keyPressed(Key.POWER_OF_2);
|
||||
break;
|
||||
case KeyEvent.VK_NUMPAD5:
|
||||
Keyboard.keyPressed(Key.POWER_OF_x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent arg0) {
|
||||
switch (arg0.getKeyCode()) {
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
Keyboard.keyReleased(Key.POWER);
|
||||
break;
|
||||
case KeyEvent.VK_D:
|
||||
Keyboard.keyReleased(Key.debug_DEG);
|
||||
break;
|
||||
case KeyEvent.VK_R:
|
||||
Keyboard.keyReleased(Key.debug_RAD);
|
||||
break;
|
||||
case KeyEvent.VK_G:
|
||||
Keyboard.keyReleased(Key.debug_GRA);
|
||||
break;
|
||||
case KeyEvent.VK_X:
|
||||
if (Keyboard.alpha) {
|
||||
Keyboard.keyReleased(Key.LETTER_X);
|
||||
} else {
|
||||
Keyboard.keyReleased(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_B:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyReleased(Key.BRIGHTNESS_CYCLE_REVERSE);
|
||||
} else if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyReleased(Key.BRIGHTNESS_CYCLE);
|
||||
} else {
|
||||
Keyboard.keyReleased(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_ENTER:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyReleased(Key.SOLVE);
|
||||
} else {
|
||||
Keyboard.keyReleased(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_1:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyReleased(Key.debug1);
|
||||
} else {
|
||||
Keyboard.keyReleased(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_2:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyReleased(Key.debug2);
|
||||
} else {
|
||||
Keyboard.keyReleased(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_3:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyReleased(Key.debug3);
|
||||
} else {
|
||||
Keyboard.keyReleased(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_4:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyReleased(Key.debug4);
|
||||
} else {
|
||||
Keyboard.keyReleased(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_5:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyReleased(Key.debug5);
|
||||
} else {
|
||||
Keyboard.keyReleased(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_SHIFT:
|
||||
Keyboard.keyReleased(Key.SHIFT);
|
||||
break;
|
||||
case KeyEvent.VK_A:
|
||||
Keyboard.keyReleased(Key.ALPHA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(int width, int height) {
|
||||
super.setSize(width, height);
|
||||
c.setSize(width, height);
|
||||
}
|
||||
|
||||
public static class CustomCanvas extends JPanel {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 605243927485370885L;
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics graphics) {
|
||||
Display.update(graphics, forcerefresh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repaint() {
|
||||
forcerefresh = false;
|
||||
super.repaint();
|
||||
}
|
||||
|
||||
private boolean forcerefresh = false;
|
||||
|
||||
public void repaint(boolean force) {
|
||||
forcerefresh = force;
|
||||
super.repaint();
|
||||
}
|
||||
}
|
||||
}
|
275
src/org/warp/engine/Display.java
Normal file
275
src/org/warp/engine/Display.java
Normal file
@ -0,0 +1,275 @@
|
||||
package org.warp.engine;
|
||||
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.device.PIFrame;
|
||||
import org.warp.picalculator.Main;
|
||||
|
||||
public class Display {
|
||||
|
||||
private static PIFrame INSTANCE = new PIFrame();
|
||||
public static int[] size = new int[] { 1, 1 };
|
||||
public static BufferedImage g = new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_ARGB);
|
||||
public static int[] canvas2d = new int[1];
|
||||
public static int color = 0xFF000000;
|
||||
private static volatile Startable refresh;
|
||||
private static boolean initialized = false;
|
||||
|
||||
public static void setTitle(String title) {
|
||||
INSTANCE.setTitle(title);
|
||||
}
|
||||
|
||||
public static void setResizable(boolean r) {
|
||||
INSTANCE.setResizable(r);
|
||||
if (!r)
|
||||
INSTANCE.setUndecorated(true);
|
||||
}
|
||||
|
||||
public static void setDisplayMode(final int ww, final int wh) {
|
||||
INSTANCE.setSize(ww, wh);
|
||||
size = new int[] { ww, wh };
|
||||
canvas2d = new int[ww * wh];
|
||||
g = new BufferedImage(ww, wh, BufferedImage.TYPE_INT_ARGB);
|
||||
INSTANCE.wasResized = false;
|
||||
}
|
||||
|
||||
public static void create() {
|
||||
INSTANCE.setVisible(true);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
public static boolean initialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
public static boolean wasResized() {
|
||||
if (INSTANCE.wasResized) {
|
||||
size = new int[] { INSTANCE.getWidth(), INSTANCE.getHeight() };
|
||||
canvas2d = new int[size[0] * size[1]];
|
||||
g = new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_ARGB);
|
||||
INSTANCE.wasResized = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int getWidth() {
|
||||
return INSTANCE.getWidth()-Main.screenPos[0];
|
||||
}
|
||||
|
||||
public static int getHeight() {
|
||||
return INSTANCE.getHeight()-Main.screenPos[1];
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
initialized = false;
|
||||
INSTANCE.setVisible(false);
|
||||
INSTANCE.dispose();
|
||||
}
|
||||
|
||||
public static void start(Startable refresh) {
|
||||
Display.refresh = refresh;
|
||||
}
|
||||
|
||||
@Deprecated()
|
||||
public static void refresh() {
|
||||
if (PIDisplay.screen == null || PIDisplay.loading || (PIDisplay.error != null && PIDisplay.error.length() > 0) || PIDisplay.screen == null || PIDisplay.screen.mustBeRefreshed()) {
|
||||
Display.INSTANCE.c.repaint(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void refresh(boolean force) {
|
||||
Display.INSTANCE.c.repaint(force);
|
||||
}
|
||||
|
||||
public static void update(Graphics g, boolean forcerefresh) {
|
||||
if (refresh != null) {
|
||||
refresh.force = forcerefresh;
|
||||
refresh.run();
|
||||
|
||||
final int[] a = ((DataBufferInt) Display.g.getRaster().getDataBuffer()).getData();
|
||||
System.arraycopy(canvas2d, 0, a, 0, canvas2d.length);
|
||||
g.clearRect(0, 0, size[0], size[1]);
|
||||
g.drawImage(Display.g, 0, 0, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Startable {
|
||||
public Startable() {
|
||||
this.force = false;
|
||||
}
|
||||
|
||||
public Startable(boolean force) {
|
||||
this.force = force;
|
||||
}
|
||||
|
||||
public boolean force = false;
|
||||
|
||||
public abstract void run();
|
||||
}
|
||||
|
||||
public static class Render {
|
||||
public static int clearcolor = 0xFFCCE7D4;
|
||||
public static RAWFont currentFont;
|
||||
|
||||
public static void glColor3f(int r, int gg, int b) {
|
||||
glColor4f(r, gg, b, 255);
|
||||
}
|
||||
|
||||
public static void glColor(int c) {
|
||||
color = c & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
public static void glClearColor(int c) {
|
||||
clearcolor = c & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
public static void glColor4f(int red, int green, int blue, int alpha) {
|
||||
color = (alpha << 24) + (red << 16) + (green << 8) + (blue);
|
||||
}
|
||||
|
||||
public static void glClearColor(int red, int green, int blue, int alpha) {
|
||||
clearcolor = (alpha << 24) + (red << 16) + (green << 8) + (blue);
|
||||
}
|
||||
|
||||
public static void glClear() {
|
||||
for (int x = 0; x < size[0]; x++) {
|
||||
for (int y = 0; y < size[1]; y++) {
|
||||
canvas2d[x + y * size[0]] = clearcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void glDrawSkin(int skinwidth, int[] skin, int x0, int y0, int s0, int t0, int s1, int t1, boolean transparent) {
|
||||
x0+=Main.screenPos[0];
|
||||
y0+=Main.screenPos[1];
|
||||
if (x0 >= size[0] || y0 >= size[0]) {
|
||||
return;
|
||||
}
|
||||
if (x0 + (s1-s0) >= size[0]) {
|
||||
s1 = size[0] - x0 + s0;
|
||||
}
|
||||
if (y0 + (t1-t0) >= size[1]) {
|
||||
t1 = size[1] - y0 + t0;
|
||||
}
|
||||
int oldColor;
|
||||
int newColor;
|
||||
for (int texx = 0; texx < s1 - s0; texx++) {
|
||||
for (int texy = 0; texy < t1 - t0; texy++) {
|
||||
newColor = skin[(s0 + texx) + (t0 + texy) * skinwidth];
|
||||
if (transparent) {
|
||||
oldColor = canvas2d[(x0 + texx) + (y0 + texy) * size[0]];
|
||||
float a2 = ((float)(newColor >> 24 & 0xFF)) / 255f;
|
||||
float a1 = 1f-a2;
|
||||
int r = (int) ((oldColor >> 16 & 0xFF) * a1 + (newColor >> 16 & 0xFF) * a2);
|
||||
int g = (int) ((oldColor >> 8 & 0xFF) * a1 + (newColor >> 8 & 0xFF) * a2);
|
||||
int b = (int) ((oldColor & 0xFF) * a1 + (newColor & 0xFF) * a2);
|
||||
newColor = 0xFF000000 | r << 16 | g << 8 | b;
|
||||
}
|
||||
canvas2d[(x0 + texx) + (y0 + texy) * size[0]] = newColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void glDrawLine(int x0, int y0, int x1, int y1) {
|
||||
x0+=Main.screenPos[0];
|
||||
x1+=Main.screenPos[0];
|
||||
y0+=Main.screenPos[1];
|
||||
y1+=Main.screenPos[1];
|
||||
if (x0 >= size[0] || y0 >= size[0]) {
|
||||
return;
|
||||
}
|
||||
if (y0 == y1) {
|
||||
for (int x = 0; x <= x1 - x0; x++) {
|
||||
canvas2d[x0 + x + y0 * size[0]] = color;
|
||||
}
|
||||
} else if (x0 == x1) {
|
||||
for (int y = 0; y <= y1 - y0; y++) {
|
||||
canvas2d[x0 + (y0 + y) * size[0]] = color;
|
||||
}
|
||||
} else {
|
||||
int m = (y1 - y0) / (x1 - x0);
|
||||
for (int texx = 0; texx <= x1 - x0; texx++) {
|
||||
if (x0 + texx < size[0] && y0 + (m * texx) < size[1]) {
|
||||
canvas2d[(x0 + texx) + (y0 + (m * texx)) * size[0]] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void glFillRect(int x0, int y0, int w1, int h1) {
|
||||
x0+=Main.screenPos[0];
|
||||
y0+=Main.screenPos[1];
|
||||
int x1 = x0+w1;
|
||||
int y1 = y0+h1;
|
||||
if (x0 >= size[0] || y0 >= size[0]) {
|
||||
return;
|
||||
}
|
||||
if (x1 >= size[0]) {
|
||||
x1 = size[0];
|
||||
}
|
||||
if (y1 >= size[1]) {
|
||||
y1 = size[1];
|
||||
}
|
||||
final int sizeW = size[0];
|
||||
for (int x = x0; x < x1; x++) {
|
||||
for (int y = y0; y < y1; y++) {
|
||||
canvas2d[(x) + (y) * sizeW] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] getMatrixOfImage(BufferedImage bufferedImage) {
|
||||
int width = bufferedImage.getWidth(null);
|
||||
int height = bufferedImage.getHeight(null);
|
||||
int[] pixels = new int[width * height];
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
pixels[i + j * width] = bufferedImage.getRGB(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public static void glDrawStringLeft(int x, int y, String text) {
|
||||
x+=Main.screenPos[0];
|
||||
y+=Main.screenPos[1];
|
||||
final int[] chars = currentFont.getCharIndexes(text);
|
||||
currentFont.drawText(canvas2d, size, x, y, chars, color);
|
||||
}
|
||||
|
||||
public static void glDrawStringCenter(int x, int y, String text) {
|
||||
glDrawStringLeft(x - (getStringWidth(text) / 2), y, text);
|
||||
}
|
||||
|
||||
public static void glDrawStringRight(int x, int y, String text) {
|
||||
glDrawStringLeft(x - getStringWidth(text), y, text);
|
||||
}
|
||||
|
||||
public static void setFont(RAWFont font) {
|
||||
if (currentFont != font) {
|
||||
currentFont = font;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getStringWidth(String text) {
|
||||
int w =(currentFont.charW+1)*text.length();
|
||||
if (text.length() > 0) {
|
||||
return w-1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
// return text.length()*6;
|
||||
}
|
||||
|
||||
public static int getWidth(FontMetrics fm, String text) {
|
||||
return fm.stringWidth(text);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
195
src/org/warp/engine/RAWFont.java
Normal file
195
src/org/warp/engine/RAWFont.java
Normal file
@ -0,0 +1,195 @@
|
||||
package org.warp.engine;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author andreacv
|
||||
*/
|
||||
public class RAWFont {
|
||||
|
||||
public boolean[][] rawchars;
|
||||
public int[] chars32;
|
||||
public long[] chars64;
|
||||
public static final boolean is64 = true;
|
||||
public int minBound = 10;
|
||||
public int maxBound = 9599;
|
||||
public int charW;
|
||||
public int charH;
|
||||
public int charS;
|
||||
|
||||
public void create(String name) {
|
||||
try {
|
||||
loadFont("/font_"+name+".rft");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
if (is64) {
|
||||
chars64 = new long[maxBound-minBound];
|
||||
} else {
|
||||
chars32 = new int[(maxBound-minBound)*2];
|
||||
}
|
||||
for (int charIndex = 0; charIndex < maxBound-minBound; charIndex++) {
|
||||
if (is64) {
|
||||
boolean[] currentChar = rawchars[charIndex];
|
||||
if (currentChar == null) {
|
||||
chars64[charIndex] = 0x1FFFFFFFFFFFL;
|
||||
} else {
|
||||
long result = 0, l = charS;
|
||||
for (int i = 0; i < l; ++i) {
|
||||
result = (result << 1) | (currentChar[i] ? 1L : 0L);
|
||||
}
|
||||
chars64[charIndex] = result;
|
||||
}
|
||||
} else {
|
||||
boolean[] currentChar = rawchars[charIndex];
|
||||
if (currentChar == null) {
|
||||
chars32[charIndex*2] = 0x1FFFFFFF;
|
||||
chars32[(charIndex*2)+1] = 0xFFFF;
|
||||
} else {
|
||||
int result1 = 0, result2 = 0, l1 = 29, l2 = currentChar.length;
|
||||
for (int i = 0; i < l1; ++i) {
|
||||
result1 = (result1 << 1) + (currentChar[i] ? 1 : 0);
|
||||
}
|
||||
for (int i = l1; i < l2; ++i) {
|
||||
result2 = (result2 << 1) + (currentChar[i] ? 1 : 0);
|
||||
}
|
||||
chars32[charIndex*2] = result1;
|
||||
chars32[(charIndex*2)+1] = result2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object obj = new Object();
|
||||
WeakReference<Object> ref = new WeakReference<>(obj);
|
||||
obj = null;
|
||||
while (ref.get() != null) {
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
if (filelength >= 16) {
|
||||
if (file[0x0] == 114 && file[0x1] == 97 && file[0x2] == 119 && file[0x3] == 0xFF && file[0x6] == 0xFF && file[0xB] == 0xFF) {
|
||||
charW = file[0x4];
|
||||
charH = file[0x5];
|
||||
charS = charW*charH;
|
||||
minBound = file[0x7] << 24 | file[0x8] << 16 | file[0x9] << 8 | file[0xA];
|
||||
maxBound = file[0xC] << 24 | file[0xD] << 16 | file[0xE] << 8 | file[0xF];
|
||||
if (maxBound <= minBound) {
|
||||
maxBound = 9599; //TODO remove it: temp fix
|
||||
}
|
||||
rawchars = new boolean[maxBound-minBound][];
|
||||
int index = 0x10;
|
||||
while (index < filelength) {
|
||||
int charIndex = file[index] << 8 | file[index+1];
|
||||
boolean[] rawchar = new boolean[charS];
|
||||
int charbytescount = (int) Math.ceil(charS/8)+1;
|
||||
int currentBit = 0;
|
||||
for (int i = 0; i <= charbytescount; i++) {
|
||||
for (int bit = 0; bit < 8; bit++) {
|
||||
if (currentBit >= charS) {
|
||||
break;
|
||||
}
|
||||
rawchar[i*8+bit] = (((file[index + 2 + i] >> (7-bit)) & 0x1)>=1)?true:false;
|
||||
currentBit++;
|
||||
}
|
||||
}
|
||||
rawchars[charIndex - minBound] = rawchar;
|
||||
index += 2 + charbytescount;
|
||||
}
|
||||
} else {
|
||||
throw new IOException();
|
||||
}
|
||||
} else {
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getCharIndexes(String txt) {
|
||||
final int l = txt.length();
|
||||
int[] indexes = new int[l];
|
||||
char[] chars = txt.toCharArray();
|
||||
for (int i = 0; i < l; i++) {
|
||||
indexes[i] = (chars[i] & 0xFFFF)-minBound;
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void saveArray(int[] screen, String coutputpng) {
|
||||
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) {
|
||||
Logger.getLogger(RAWFont.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawText(int[] screen, int[] screenSize, int x, int y, int[] text, int color) {
|
||||
final int screenLength = screen.length;
|
||||
int screenPos = 0;
|
||||
if (is64) {
|
||||
long res = 0;
|
||||
final int l = text.length;
|
||||
for (int i = 0; i < l; i++) {
|
||||
long chr = chars64[text[i]];
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
for (int j = charS-1; j >= 0; j--) {
|
||||
res = (chr >> j) & 1;
|
||||
screenPos = (x + dx) + (y + dy) * screenSize[0];
|
||||
if (res == 1 & screenLength > screenPos) {
|
||||
screen[screenPos] = color;
|
||||
}
|
||||
dx++;
|
||||
if (dx >= charW) {
|
||||
dx = 0;
|
||||
dy++;
|
||||
}
|
||||
}
|
||||
x+=charW+1;
|
||||
}
|
||||
} else {
|
||||
int res = 0;
|
||||
final int l = text.length;
|
||||
for (int i = 0; i < l; i++) {
|
||||
final int charIndex = text[i]*2;
|
||||
int chrP1 = chars32[charIndex];
|
||||
int chrP2 = chars32[charIndex+1];
|
||||
for (int dx = 0; dx < charW; dx++) {
|
||||
for (int dy = 0; dy < charH; dy++) {
|
||||
int bit = dx + dy * charW;
|
||||
if (bit < 29) {
|
||||
res = chrP1 >> (28-bit) & 1;
|
||||
} else {
|
||||
res = chrP2 >> (12-bit) & 1;
|
||||
}
|
||||
screenPos = x + (i * (charW + 1)) + dx + (y + dy) * screenSize[0];
|
||||
if (res == 1 & screenLength > res) {
|
||||
screen[screenPos] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
src/org/warp/engine/Screen.java
Normal file
41
src/org/warp/engine/Screen.java
Normal file
@ -0,0 +1,41 @@
|
||||
package org.warp.engine;
|
||||
|
||||
import org.warp.device.Keyboard.Key;
|
||||
import org.warp.device.PIDisplay;
|
||||
|
||||
public abstract class Screen {
|
||||
public PIDisplay d;
|
||||
public boolean created = false;
|
||||
public boolean initialized = false;
|
||||
public boolean canBeInHistory = false;
|
||||
|
||||
public Screen() {}
|
||||
|
||||
public void initialize() throws InterruptedException {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
public void create() throws InterruptedException {
|
||||
if (!created) {
|
||||
created = true;
|
||||
created();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void created() throws InterruptedException;
|
||||
|
||||
public abstract void init() throws InterruptedException;
|
||||
|
||||
public abstract void render();
|
||||
|
||||
public abstract void beforeRender(float dt);
|
||||
|
||||
public abstract boolean mustBeRefreshed();
|
||||
|
||||
public abstract boolean keyPressed(Key k);
|
||||
|
||||
public abstract boolean keyReleased(Key k);
|
||||
}
|
@ -1,696 +0,0 @@
|
||||
package org.warp.engine.lwjgl;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
|
||||
import org.lwjgl.glfw.GLFWKeyCallback;
|
||||
import org.lwjgl.glfw.GLFWVidMode;
|
||||
import org.lwjgl.glfw.GLFWWindowSizeCallback;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GLCapabilities;
|
||||
import org.lwjgl.opengl.GLUtil;
|
||||
import org.lwjgl.stb.STBTTAlignedQuad;
|
||||
import org.lwjgl.stb.STBTTPackContext;
|
||||
import org.lwjgl.stb.STBTTPackedchar;
|
||||
import org.warpgate.pi.calculator.Calculator;
|
||||
import org.warpgate.pi.calculator.Keyboard;
|
||||
import org.warpgate.pi.calculator.Main;
|
||||
import org.warpgate.pi.calculator.Utils;
|
||||
|
||||
import de.matthiasmann.twl.utils.PNGDecoder;
|
||||
import de.matthiasmann.twl.utils.PNGDecoder.Format;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import static org.warp.engine.lwjgl.GLFWUtil.*;
|
||||
import static org.warp.engine.lwjgl.IOUtil.*;
|
||||
import static org.lwjgl.glfw.Callbacks.*;
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL13.*;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
import static org.lwjgl.stb.STBTruetype.*;
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
import static org.lwjgl.stb.STBImage.*;
|
||||
|
||||
/**
|
||||
* 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 Display {
|
||||
|
||||
private static final int BITMAP_W = 5*128;
|
||||
private static final int BITMAP_H = 9*256;
|
||||
|
||||
private static final float[] scale = {
|
||||
30.0f,
|
||||
15.0f
|
||||
};
|
||||
|
||||
// ----
|
||||
|
||||
private final STBTTAlignedQuad q = STBTTAlignedQuad.malloc();
|
||||
private final FloatBuffer xb = memAllocFloat(1);
|
||||
private final FloatBuffer yb = memAllocFloat(1);
|
||||
|
||||
private long window;
|
||||
|
||||
// ----
|
||||
|
||||
private int ww = 480;
|
||||
private int wh = 320;
|
||||
|
||||
private int fbw = ww;
|
||||
private int fbh = wh;
|
||||
|
||||
private int font_tex;
|
||||
private int skin_tex;
|
||||
private int skin_w;
|
||||
private int skin_h;
|
||||
private int skin_comp;
|
||||
private ByteBuffer skin;
|
||||
|
||||
private STBTTPackedchar.Buffer chardata;
|
||||
|
||||
private boolean black_on_white;
|
||||
private boolean integer_align;
|
||||
private boolean translating;
|
||||
private boolean rotating;
|
||||
|
||||
private boolean supportsSRGB;
|
||||
private boolean srgb;
|
||||
|
||||
private float rotate_t, translate_t;
|
||||
|
||||
private boolean show_tex;
|
||||
|
||||
private int font = 0;
|
||||
|
||||
private final int maxCharIndex = 9500;
|
||||
private float[] background = new float[]{0f,0f,0f};
|
||||
public boolean loading = true;
|
||||
public String error = null;
|
||||
public String[] errorStackTrace = null;
|
||||
public final int[] glyphsHeight = new int[]{9, 6};
|
||||
public float translation = 0.0f;
|
||||
public boolean translation_top_to_bottom = true;
|
||||
public static float brightness = 1.0f;
|
||||
|
||||
private Screen screen;
|
||||
|
||||
public Display(Screen screen, int ww, int wh) {
|
||||
this.ww = ww;
|
||||
this.wh = wh;
|
||||
setScreen(screen);
|
||||
}
|
||||
/*
|
||||
private void load_skin() {
|
||||
try {
|
||||
skin_tex = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D, skin_tex);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
InputStream in = new FileInputStream("res/skin.png");
|
||||
PNGDecoder decoder = new PNGDecoder(in);
|
||||
|
||||
System.out.println("width="+decoder.getWidth());
|
||||
System.out.println("height="+decoder.getHeight());
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight());
|
||||
decoder.decode(buf, decoder.getWidth()*4, Format.RGBA);
|
||||
buf.flip();
|
||||
|
||||
skin = buf;
|
||||
skin_w = decoder.getWidth();
|
||||
skin_h = decoder.getHeight();
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, skin_w,
|
||||
skin_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, skin);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
private void setScreen(Screen screen) {
|
||||
if (screen.initialized == false) {
|
||||
if (screen.canBeInHistory) {
|
||||
Calculator.currentSession = 0;
|
||||
for (int i = 1; i < Calculator.sessions.length; i++) {
|
||||
Calculator.sessions[i] = Calculator.sessions[i-1];
|
||||
}
|
||||
Calculator.sessions[0] = this.screen;
|
||||
}
|
||||
}
|
||||
screen.d = this;
|
||||
try {
|
||||
screen.initialize();
|
||||
this.screen = screen;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canGoBack() {
|
||||
if (this.screen != Calculator.sessions[Calculator.currentSession]) {
|
||||
|
||||
} else if (Calculator.currentSession+1 < Calculator.sessions.length) {
|
||||
if (Calculator.sessions[Calculator.currentSession + 1] != null) {
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (Calculator.sessions[Calculator.currentSession] != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void goBack() {
|
||||
if (canGoBack()) {
|
||||
if (this.screen != Calculator.sessions[Calculator.currentSession]) {
|
||||
|
||||
} else {
|
||||
Calculator.currentSession += 1;
|
||||
}
|
||||
this.screen = Calculator.sessions[Calculator.currentSession];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean canGoForward() {
|
||||
if (this.screen != Calculator.sessions[Calculator.currentSession]) {
|
||||
|
||||
} else if (Calculator.currentSession > 0) {
|
||||
if (Calculator.sessions[Calculator.currentSession - 1] != null) {
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (Calculator.sessions[Calculator.currentSession] != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void goForward() {
|
||||
if (canGoForward()) {
|
||||
if (this.screen != Calculator.sessions[Calculator.currentSession]) {
|
||||
|
||||
} else {
|
||||
Calculator.currentSession -= 1;
|
||||
}
|
||||
this.screen = Calculator.sessions[Calculator.currentSession];
|
||||
}
|
||||
}
|
||||
|
||||
private Screen getScreen() {
|
||||
return this.screen;
|
||||
}
|
||||
|
||||
|
||||
private void load_skin() {
|
||||
ByteBuffer imageBuffer;
|
||||
try {
|
||||
imageBuffer = ioResourceToByteBuffer("skin.png", 8 * 1024);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
skin_tex = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D, skin_tex);
|
||||
IntBuffer w = BufferUtils.createIntBuffer(1);
|
||||
IntBuffer h = BufferUtils.createIntBuffer(1);
|
||||
IntBuffer comp = BufferUtils.createIntBuffer(1);
|
||||
|
||||
skin = stbi_load_from_memory(imageBuffer, w, h, comp, 0);
|
||||
|
||||
if ( skin == null )
|
||||
throw new RuntimeException("Failed to load image: " + stbi_failure_reason());
|
||||
skin_w = w.get(0);
|
||||
skin_h = h.get(0);
|
||||
skin_comp = comp.get(0);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
if ( skin_comp == 3 ) {
|
||||
if ( (skin_w & 3) != 0 )
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 2 - (skin_w & 1));
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, skin_w, skin_h, 0, GL_RGB, GL_UNSIGNED_BYTE, skin);
|
||||
} else {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, skin_w, skin_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, skin);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
stbi_image_free(skin);
|
||||
}
|
||||
|
||||
private void load_fonts() {
|
||||
font_tex = glGenTextures();
|
||||
chardata = STBTTPackedchar.mallocBuffer(6*maxCharIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, font_tex);
|
||||
|
||||
|
||||
try {
|
||||
STBTTPackContext pc = STBTTPackContext.malloc();
|
||||
ByteBuffer ttfBig = ioResourceToByteBuffer("font_big.ttf", 18000);
|
||||
ByteBuffer ttfSmall = ioResourceToByteBuffer("font_small.ttf", 18000);
|
||||
|
||||
ByteBuffer bitmap = BufferUtils.createByteBuffer(BITMAP_W * BITMAP_H);
|
||||
|
||||
stbtt_PackBegin(pc, bitmap, BITMAP_W, BITMAP_H, 0, 1, null);
|
||||
chardata.limit(maxCharIndex);
|
||||
chardata.position(0);
|
||||
stbtt_PackSetOversampling(pc, 1, 1);
|
||||
stbtt_PackFontRange(pc, ttfBig, 0, 15 /* Font size */, 0, chardata);
|
||||
chardata.clear();
|
||||
chardata.limit(maxCharIndex*2);
|
||||
chardata.position(maxCharIndex);
|
||||
stbtt_PackSetOversampling(pc, 1, 1);
|
||||
stbtt_PackFontRange(pc, ttfSmall, 0, 15 /* Font size */, 0, chardata);
|
||||
chardata.clear();
|
||||
stbtt_PackEnd(pc);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BITMAP_W, BITMAP_H, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void draw_init() {
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glViewport(0, 0, fbw, fbh);
|
||||
clearColor(background[0], background[1], background[2], 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0, ww, wh, 0.0, -1.0, 1.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
private static void drawBoxTC(float x0, float y0, float x1, float y1, float s0, float t0, float s1, float t1) {
|
||||
glTexCoord2f(s0, t0);
|
||||
glVertex2f(x0, y0);
|
||||
glTexCoord2f(s1, t0);
|
||||
glVertex2f(x1, y0);
|
||||
glTexCoord2f(s1, t1);
|
||||
glVertex2f(x1, y1);
|
||||
glTexCoord2f(s0, t1);
|
||||
glVertex2f(x0, y1);
|
||||
}
|
||||
|
||||
private void print(float x, float y, int font, String text) {
|
||||
xb.put(0, x);
|
||||
yb.put(0, y+glyphsHeight[font]);
|
||||
|
||||
chardata.position(font * maxCharIndex);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, font_tex);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
for ( int i = 0; i < text.length(); i++ ) {
|
||||
stbtt_GetPackedQuad(chardata, BITMAP_W, BITMAP_H, text.charAt(i), xb, yb, q, (font == 0 && integer_align)?1:0);
|
||||
drawBoxTC(
|
||||
q.x0(), q.y0(), q.x1(), q.y1(),
|
||||
q.s0(), q.t0(), q.s1(), q.t1()
|
||||
);
|
||||
}
|
||||
glEnd();
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
private int[] textSize(int font, String text) {
|
||||
float[] size = new float[]{0,0};
|
||||
xb.put(0, 0);
|
||||
yb.put(0, 0);
|
||||
|
||||
chardata.position(font * maxCharIndex);
|
||||
|
||||
for ( int i = 0; i < text.length(); i++ ) {
|
||||
stbtt_GetPackedQuad(chardata, BITMAP_W, BITMAP_H, text.charAt(i), xb, yb, q, (font == 0 && integer_align)?1:0);
|
||||
size[0]=q.x1();
|
||||
size[1]=q.y1();
|
||||
}
|
||||
return new int[]{(int) size[0], (int) size[1]};
|
||||
}
|
||||
|
||||
private void drawSkinPart(int[] posOnScreen, float[] posOnSkin) {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
colore(1, 1, 1, 1);
|
||||
glBindTexture(GL_TEXTURE_2D, skin_tex);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
drawBoxTC(posOnScreen[0],posOnScreen[1],posOnScreen[2], posOnScreen[3], posOnSkin[0]/1000, posOnSkin[1]/100, posOnSkin[2]/1000, posOnSkin[3]/100);
|
||||
glEnd();
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
private void drawLine(int[]... pos) {
|
||||
glLineWidth(1.0f);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
|
||||
for (int[] single_pos : pos) {
|
||||
glVertex2d(single_pos[0], single_pos[1]);
|
||||
glVertex2d(single_pos[2], single_pos[3]);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
private void drawRect(int[]... pos) {
|
||||
glLineWidth(1.0f);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (int[] single_pos : pos) {
|
||||
glVertex2d(single_pos[0], single_pos[1]);
|
||||
glVertex2d(single_pos[2], single_pos[1]);
|
||||
glVertex2d(single_pos[2], single_pos[3]);
|
||||
glVertex2d(single_pos[0], single_pos[3]);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
private void draw_status() {
|
||||
colore(background[0],background[1],background[2]);
|
||||
drawRect(new int[]{0,0,ww,20});
|
||||
colore(0,0,0);
|
||||
drawLine(new int[]{0,20,ww,20});
|
||||
colore(0,0,0);
|
||||
if (Keyboard.shift) {
|
||||
drawSkinPart(new int[]{2+18*0,2,2+16+18*0,2+16}, new float[]{16*2,16*0,16+16*2,16+16*0});
|
||||
} else {
|
||||
drawSkinPart(new int[]{2+18*0,2,2+16+18*0,2+16}, new float[]{16*3,16*0,16+16*3,16+16*0});
|
||||
}
|
||||
if (Keyboard.alpha) {
|
||||
drawSkinPart(new int[]{2+18*1,2,2+16+18*1,2+16}, new float[]{16*0,16*0,16+16*0,16+16*0});
|
||||
} else {
|
||||
drawSkinPart(new int[]{2+18*1,2,2+16+18*1,2+16}, new float[]{16*1,16*0,16+16*1,16+16*0});
|
||||
}
|
||||
if (Calculator.angleMode == "deg") {
|
||||
drawSkinPart(new int[]{8+18*2,2,8+16+18*2,2+16}, new float[]{16*4,16*0,16+16*4,16+16*0});
|
||||
drawSkinPart(new int[]{8+18*3,2,8+16+18*3,2+16}, new float[]{16*7,16*0,16+16*7,16+16*0});
|
||||
drawSkinPart(new int[]{8+18*4,2,8+16+18*4,2+16}, new float[]{16*9,16*0,16+16*9,16+16*0});
|
||||
} else if (Calculator.angleMode == "rad") {
|
||||
drawSkinPart(new int[]{8+18*2,2,8+16+18*2,2+16}, new float[]{16*5,16*0,16+16*5,16+16*0});
|
||||
drawSkinPart(new int[]{8+18*3,2,8+16+18*3,2+16}, new float[]{16*6,16*0,16+16*6,16+16*0});
|
||||
drawSkinPart(new int[]{8+18*4,2,8+16+18*4,2+16}, new float[]{16*9,16*0,16+16*9,16+16*0});
|
||||
} else if (Calculator.angleMode == "gra") {
|
||||
drawSkinPart(new int[]{8+18*2,2,8+16+18*2,2+16}, new float[]{16*5,16*0,16+16*5,16+16*0});
|
||||
drawSkinPart(new int[]{8+18*3,2,8+16+18*3,2+16}, new float[]{16*7,16*0,16+16*7,16+16*0});
|
||||
drawSkinPart(new int[]{8+18*4,2,8+16+18*4,2+16}, new float[]{16*8,16*0,16+16*8,16+16*0});
|
||||
} else {
|
||||
drawSkinPart(new int[]{8+18*2,2,8+16+18*2,2+16}, new float[]{16*5,16*0,16+16*5,16+16*0});
|
||||
drawSkinPart(new int[]{8+18*3,2,8+16+18*3,2+16}, new float[]{16*7,16*0,16+16*7,16+16*0});
|
||||
drawSkinPart(new int[]{8+18*4,2,8+16+18*4,2+16}, new float[]{16*9,16*0,16+16*9,16+16*0});
|
||||
}
|
||||
|
||||
int padding = 2;
|
||||
|
||||
int brightness = (int)(Display.brightness * 4);
|
||||
if (brightness == 1) {
|
||||
drawSkinPart(new int[]{ww-(padding+18*0),2,ww-(padding+16+18*0),2+16}, new float[]{16*10,16*0,16+16*10,16+16*0});
|
||||
} else if (brightness == 2) {
|
||||
drawSkinPart(new int[]{ww-(padding+18*0),2,ww-(padding+16+18*0),2+16}, new float[]{16*11,16*0,16+16*11,16+16*0});
|
||||
} else if (brightness == 3) {
|
||||
drawSkinPart(new int[]{ww-(padding+18*0),2,ww-(padding+16+18*0),2+16}, new float[]{16*12,16*0,16+16*12,16+16*0});
|
||||
} else if (brightness == 4) {
|
||||
drawSkinPart(new int[]{ww-(padding+18*0),2,ww-(padding+16+18*0),2+16}, new float[]{16*13,16*0,16+16*13,16+16*0});
|
||||
}
|
||||
|
||||
padding += 18+6;
|
||||
|
||||
boolean canGoBack = canGoBack();
|
||||
boolean canGoForward = canGoForward();
|
||||
|
||||
|
||||
if (Calculator.haxMode) {
|
||||
drawSkinPart(new int[]{ww-(padding+16),2,ww-padding,2+16}, new float[]{16*18,16*0,16+16*18,16+16*0});
|
||||
padding += 18+6;
|
||||
}
|
||||
|
||||
if (canGoBack && canGoForward) {
|
||||
drawSkinPart(new int[]{ww-(padding+16),2,ww-padding,2+16}, new float[]{16*14,16*0,16+16*14,16+16*0});
|
||||
} else if (canGoBack) {
|
||||
drawSkinPart(new int[]{ww-(padding+16),2,ww-padding,2+16}, new float[]{16*15,16*0,16+16*15,16+16*0});
|
||||
} else if (canGoForward) {
|
||||
drawSkinPart(new int[]{ww-(padding+16),2,ww-padding,2+16}, new float[]{16*16,16*0,16+16*16,16+16*0});
|
||||
} else {
|
||||
drawSkinPart(new int[]{ww-(padding+16),2,ww-padding,2+16}, new float[]{16*17,16*0,16+16*17,16+16*0});
|
||||
}
|
||||
|
||||
padding += 18;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void draw_screen() {
|
||||
screen.render();
|
||||
}
|
||||
|
||||
|
||||
private void draw_bottom() {
|
||||
|
||||
}
|
||||
|
||||
private void draw_world() {
|
||||
float x = 20;
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
colore(1.0f, 1.0f, 1.0f);
|
||||
|
||||
if (error != null) {
|
||||
colore(0.0f, 0.0f, 0.0f, 0.75f);
|
||||
print(ww-textSize(1, "ANDREA CAVALLI'S CALCULATOR")[0]-2, wh-this.glyphsHeight[1]-2, 1, "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(0.0f, 0.0f, 0.0f, 0.75f);
|
||||
print((ww/2)-(textSize(0, "UNEXPECTED EXCEPTION")[0]/2), 11, 0, "UNEXPECTED EXCEPTION");
|
||||
colore(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
print((ww/2)-(textSize(1, error)[0]/2), 22, 1, error);
|
||||
colore(0.0f, 0.0f, 0.0f, 0.4f);
|
||||
int i = 22;
|
||||
for (String stackPart : errorStackTrace) {
|
||||
print(2, 22+i, 1, stackPart);
|
||||
i+=11;
|
||||
}
|
||||
} else if (loading) {
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
int titlew = textSize(0, "ANDREA CAVALLI'S CALCULATOR")[0];
|
||||
print((ww/2)-(titlew/2)-1, (wh/2)-25+translation, 0, "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
print((ww/2)-(titlew/2)+1, (wh/2)-25+translation, 0, "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
print((ww/2)-(titlew/2), (wh/2)-25-1+translation, 0, "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
print((ww/2)-(titlew/2), (wh/2)-25+1+translation, 0, "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(1.0f, 0.5f, 0.0f, 1.0f);
|
||||
print((ww/2)-(titlew/2), (wh/2)-25+translation, 0, "ANDREA CAVALLI'S CALCULATOR");
|
||||
colore(0.0f, 0.0f, 0.0f, 0.75f);
|
||||
print((ww/2)-(textSize(0, "LOADING")[0]/2), (wh/2)+11, 0, "LOADING");
|
||||
colore(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
print((ww/2)-(textSize(1, "PLEASE WAIT...")[0]/2), (wh/2)+22, 1, "PLEASE WAIT...");
|
||||
} else {
|
||||
draw_status();
|
||||
draw_screen();
|
||||
draw_bottom();
|
||||
}
|
||||
}
|
||||
|
||||
private void draw() {
|
||||
draw_init();
|
||||
draw_world();
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
private void loopmode(float dt) {
|
||||
|
||||
rotate_t += dt;
|
||||
translate_t += dt;
|
||||
|
||||
/*
|
||||
* Calcoli
|
||||
*/
|
||||
|
||||
if (translation >= 10.0f) {
|
||||
translation = 10.0f;
|
||||
translation_top_to_bottom = false;
|
||||
} else if (translation <= -10.0f) {
|
||||
translation = -10.0f;
|
||||
translation_top_to_bottom = true;
|
||||
}
|
||||
|
||||
if (translation_top_to_bottom) {
|
||||
translation += dt*15;
|
||||
} else {
|
||||
translation -= dt*15;
|
||||
}
|
||||
|
||||
screen.beforeRender(dt);
|
||||
|
||||
draw();
|
||||
}
|
||||
|
||||
private GLFWKeyCallback keyCallback = new GLFWKeyCallback() {
|
||||
@Override
|
||||
public void invoke(long window, int key, int scancode, int action, int mods) {
|
||||
if ( action == GLFW_RELEASE )
|
||||
return;
|
||||
switch ( key ) {
|
||||
case GLFW_KEY_ESCAPE:
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
break;
|
||||
case GLFW_KEY_F:
|
||||
font = 1;
|
||||
break;
|
||||
case GLFW_KEY_R:
|
||||
rotating = !rotating;
|
||||
rotate_t = 0.0f;
|
||||
break;
|
||||
case GLFW_KEY_P:
|
||||
integer_align = !integer_align;
|
||||
break;
|
||||
case GLFW_KEY_G:
|
||||
font = 0;
|
||||
break;
|
||||
case GLFW_KEY_V:
|
||||
show_tex = !show_tex;
|
||||
break;
|
||||
case GLFW_KEY_B:
|
||||
black_on_white = !black_on_white;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private GLFWWindowSizeCallback sizecallback = new GLFWWindowSizeCallback() {
|
||||
@Override
|
||||
public void invoke(long window, int width, int height) {
|
||||
Display.this.ww = width;
|
||||
Display.this.wh = height;
|
||||
}
|
||||
};
|
||||
|
||||
private GLFWFramebufferSizeCallback fbsizecallback = new GLFWFramebufferSizeCallback() {
|
||||
@Override
|
||||
public void invoke(long window, int width, int height) {
|
||||
Display.this.fbw = width;
|
||||
Display.this.fbh = height;
|
||||
}
|
||||
};
|
||||
|
||||
private void createWindow(String title) {
|
||||
GLFWErrorCallback.createPrint().set();
|
||||
if ( glfwInit() == GLFW_FALSE )
|
||||
throw new IllegalStateException("Unable to initialize GLFW");
|
||||
|
||||
glfwDefaultWindowHints();
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
|
||||
this.window = glfwCreateWindow(ww, wh, title, NULL, NULL);
|
||||
if ( window == NULL )
|
||||
throw new RuntimeException("Failed to create the GLFW window");
|
||||
|
||||
glfwSetWindowSizeCallback(window, sizecallback);
|
||||
glfwSetFramebufferSizeCallback(window, fbsizecallback);
|
||||
glfwSetKeyCallback(window, keyCallback);
|
||||
|
||||
// Center window
|
||||
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
|
||||
glfwSetWindowPos(
|
||||
window,
|
||||
(vidmode.width() - ww) / 2,
|
||||
(vidmode.height() - wh) / 2
|
||||
);
|
||||
|
||||
// Create context
|
||||
glfwMakeContextCurrent(window);
|
||||
GL.createCapabilities();
|
||||
|
||||
glfwSwapInterval(1);
|
||||
glfwShowWindow(window);
|
||||
|
||||
glfwInvoke(window, sizecallback, fbsizecallback);
|
||||
|
||||
// Detect sRGB support
|
||||
GLCapabilities caps = GL.getCapabilities();
|
||||
supportsSRGB = caps.OpenGL30 || caps.GL_ARB_framebuffer_sRGB || caps.GL_EXT_framebuffer_sRGB;
|
||||
}
|
||||
|
||||
public void run(String title) {
|
||||
try {
|
||||
createWindow(title);
|
||||
load_skin();
|
||||
load_fonts();
|
||||
|
||||
long time = System.nanoTime();
|
||||
while ( glfwWindowShouldClose(window) == GLFW_FALSE ) {
|
||||
glfwPollEvents();
|
||||
|
||||
long t = System.nanoTime();
|
||||
float dt = (float)((t - time) / 1000000000.0);
|
||||
time = t;
|
||||
|
||||
loopmode(dt);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
destroy();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void destroy() {
|
||||
chardata.clear();
|
||||
|
||||
glfwTerminate();
|
||||
glfwSetErrorCallback(null);
|
||||
|
||||
memFree(yb);
|
||||
memFree(xb);
|
||||
|
||||
q.free();
|
||||
}
|
||||
|
||||
public void setBackground(float d, float e, float f) {
|
||||
background = new float[]{d,e,f};
|
||||
}
|
||||
|
||||
public void colore(float f1, float f2, float f3) {
|
||||
glColor3f(f1*brightness, f2*brightness, f3*brightness);
|
||||
}
|
||||
|
||||
public void colore(float f1, float f2, float f3, float f4) {
|
||||
glColor4f(f1*brightness, f2*brightness, f3*brightness, f4);
|
||||
}
|
||||
|
||||
public void clearColor(float f1, float f2, float f3, float f4) {
|
||||
glClearColor(f1*brightness,f2*brightness,f3*brightness,f4);
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package org.warp.engine.lwjgl;
|
||||
|
||||
import org.lwjgl.glfw.GLFWFramebufferSizeCallbackI;
|
||||
import org.lwjgl.glfw.GLFWWindowSizeCallbackI;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
import static org.lwjgl.system.MemoryStack.*;
|
||||
|
||||
/** GLFW demo utilities. */
|
||||
public final class GLFWUtil {
|
||||
|
||||
private GLFWUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the specified callbacks using the current window and framebuffer sizes of the specified GLFW window.
|
||||
*
|
||||
* @param window the GLFW window
|
||||
* @param windowSizeCB the window size callback, may be null
|
||||
* @param framebufferSizeCB the framebuffer size callback, may be null
|
||||
*/
|
||||
public static void glfwInvoke(
|
||||
long window,
|
||||
GLFWWindowSizeCallbackI windowSizeCB,
|
||||
GLFWFramebufferSizeCallbackI framebufferSizeCB
|
||||
) {
|
||||
try ( MemoryStack stack = stackPush() ) {
|
||||
IntBuffer w = stack.mallocInt(1);
|
||||
IntBuffer h = stack.mallocInt(1);
|
||||
|
||||
if ( windowSizeCB != null ) {
|
||||
glfwGetWindowSize(window, w, h);
|
||||
windowSizeCB.invoke(window, w.get(0), h.get(0));
|
||||
}
|
||||
|
||||
if ( framebufferSizeCB != null ) {
|
||||
glfwGetFramebufferSize(window, w, h);
|
||||
framebufferSizeCB.invoke(window, w.get(0), h.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package org.warp.engine.lwjgl;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.lwjgl.BufferUtils.*;
|
||||
|
||||
public final class IOUtil {
|
||||
|
||||
private IOUtil() {
|
||||
}
|
||||
|
||||
private static ByteBuffer resizeBuffer(ByteBuffer buffer, int newCapacity) {
|
||||
ByteBuffer newBuffer = BufferUtils.createByteBuffer(newCapacity);
|
||||
buffer.flip();
|
||||
newBuffer.put(buffer);
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the specified resource and returns the raw data as a ByteBuffer.
|
||||
*
|
||||
* @param resource the resource to read
|
||||
* @param bufferSize the initial buffer size
|
||||
*
|
||||
* @return the resource data
|
||||
*
|
||||
* @throws IOException if an IO error occurs
|
||||
*/
|
||||
public static ByteBuffer ioResourceToByteBuffer(String resource, int bufferSize) throws IOException {
|
||||
ByteBuffer buffer;
|
||||
|
||||
Path path = Paths.get(resource);
|
||||
if ( Files.isReadable(path) ) {
|
||||
try (SeekableByteChannel fc = Files.newByteChannel(path)) {
|
||||
buffer = BufferUtils.createByteBuffer((int)fc.size() + 1);
|
||||
while ( fc.read(buffer) != -1 ) ;
|
||||
}
|
||||
} else {
|
||||
try (
|
||||
InputStream source = IOUtil.class.getClassLoader().getResourceAsStream(resource);
|
||||
ReadableByteChannel rbc = Channels.newChannel(source)
|
||||
) {
|
||||
buffer = createByteBuffer(bufferSize);
|
||||
|
||||
while ( true ) {
|
||||
int bytes = rbc.read(buffer);
|
||||
if ( bytes == -1 )
|
||||
break;
|
||||
if ( buffer.remaining() == 0 )
|
||||
buffer = resizeBuffer(buffer, buffer.capacity() * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package org.warp.engine.lwjgl;
|
||||
|
||||
public abstract class Screen {
|
||||
public Display d;
|
||||
public boolean initialized = false;
|
||||
public boolean canBeInHistory = false;
|
||||
|
||||
public Screen() {
|
||||
}
|
||||
|
||||
public void initialize() throws InterruptedException {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void init() throws InterruptedException;
|
||||
|
||||
public abstract void render();
|
||||
|
||||
public abstract void beforeRender(float dt);
|
||||
}
|
219
src/org/warp/picalculator/BMPFile.java
Normal file
219
src/org/warp/picalculator/BMPFile.java
Normal file
@ -0,0 +1,219 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.PixelGrabber;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class BMPFile extends Component {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 9182927946568629682L;
|
||||
// --- Private constants
|
||||
private final static int BITMAPFILEHEADER_SIZE = 14;
|
||||
private final static int BITMAPINFOHEADER_SIZE = 40;
|
||||
// --- Private variable declaration
|
||||
// --- Bitmap file header
|
||||
@SuppressWarnings("unused")
|
||||
private byte bitmapFileHeader[] = new byte[14];
|
||||
private byte bfType[] = { 'B', 'M' };
|
||||
private int bfSize = 0;
|
||||
private int bfReserved1 = 0;
|
||||
private int bfReserved2 = 0;
|
||||
private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
|
||||
// --- Bitmap info header
|
||||
@SuppressWarnings("unused")
|
||||
private byte bitmapInfoHeader[] = new byte[40];
|
||||
private int biSize = BITMAPINFOHEADER_SIZE;
|
||||
private int biWidth = 0;
|
||||
private int biHeight = 0;
|
||||
private int biPlanes = 1;
|
||||
private int biBitCount = 24;
|
||||
private int biCompression = 0;
|
||||
private int biSizeImage = 0x030000;
|
||||
private int biXPelsPerMeter = 0x0;
|
||||
private int biYPelsPerMeter = 0x0;
|
||||
private int biClrUsed = 0;
|
||||
private int biClrImportant = 0;
|
||||
// --- Bitmap raw data
|
||||
private int bitmap[];
|
||||
// --- File section
|
||||
private FileOutputStream fo;
|
||||
|
||||
// --- Default constructor
|
||||
public BMPFile() {}
|
||||
|
||||
public void saveBitmap(String parFilename, Image parImage, int parWidth, int parHeight) {
|
||||
try {
|
||||
fo = new FileOutputStream(parFilename);
|
||||
save(parImage, parWidth, parHeight);
|
||||
fo.close();
|
||||
} catch (Exception saveEx) {
|
||||
saveEx.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The saveMethod is the main method of the process. This method
|
||||
* will call the convertImage method to convert the memory image to
|
||||
* a byte array; method writeBitmapFileHeader creates and writes
|
||||
* the bitmap file header; writeBitmapInfoHeader creates the
|
||||
* information header; and writeBitmap writes the image.
|
||||
*
|
||||
*/
|
||||
private void save(Image parImage, int parWidth, int parHeight) {
|
||||
try {
|
||||
convertImage(parImage, parWidth, parHeight);
|
||||
writeBitmapFileHeader();
|
||||
writeBitmapInfoHeader();
|
||||
writeBitmap();
|
||||
} catch (Exception saveEx) {
|
||||
saveEx.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* convertImage converts the memory image to the bitmap format (BRG).
|
||||
* It also computes some information for the bitmap info header.
|
||||
*
|
||||
*/
|
||||
private boolean convertImage(Image parImage, int parWidth, int parHeight) {
|
||||
int pad;
|
||||
bitmap = new int[parWidth * parHeight];
|
||||
PixelGrabber pg = new PixelGrabber(parImage, 0, 0, parWidth, parHeight, bitmap, 0, parWidth);
|
||||
try {
|
||||
pg.grabPixels();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return (false);
|
||||
}
|
||||
pad = (4 - ((parWidth * 3) % 4)) * parHeight;
|
||||
biSizeImage = ((parWidth * parHeight) * 3) + pad;
|
||||
bfSize = biSizeImage + BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
|
||||
biWidth = parWidth;
|
||||
biHeight = parHeight;
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
* writeBitmap converts the image returned from the pixel grabber to
|
||||
* the format required. Remember: scan lines are inverted in
|
||||
* a bitmap file!
|
||||
*
|
||||
* Each scan line must be padded to an even 4-byte boundary.
|
||||
*/
|
||||
private void writeBitmap() {
|
||||
int size;
|
||||
int value;
|
||||
int j;
|
||||
int i;
|
||||
int rowCount;
|
||||
int rowIndex;
|
||||
int lastRowIndex;
|
||||
int pad;
|
||||
int padCount;
|
||||
byte rgb[] = new byte[3];
|
||||
size = (biWidth * biHeight) - 1;
|
||||
pad = 4 - ((biWidth * 3) % 4);
|
||||
if (pad == 4) // <==== Bug correction
|
||||
pad = 0; // <==== Bug correction
|
||||
rowCount = 1;
|
||||
padCount = 0;
|
||||
rowIndex = size - biWidth;
|
||||
lastRowIndex = rowIndex;
|
||||
try {
|
||||
for (j = 0; j < size; j++) {
|
||||
value = bitmap[rowIndex];
|
||||
rgb[0] = (byte) (value & 0xFF);
|
||||
rgb[1] = (byte) ((value >> 8) & 0xFF);
|
||||
rgb[2] = (byte) ((value >> 16) & 0xFF);
|
||||
fo.write(rgb);
|
||||
if (rowCount == biWidth) {
|
||||
padCount += pad;
|
||||
for (i = 1; i <= pad; i++) {
|
||||
fo.write(0x00);
|
||||
}
|
||||
rowCount = 1;
|
||||
rowIndex = lastRowIndex - biWidth;
|
||||
lastRowIndex = rowIndex;
|
||||
} else
|
||||
rowCount++;
|
||||
rowIndex++;
|
||||
}
|
||||
// --- Update the size of the file
|
||||
bfSize += padCount - pad;
|
||||
biSizeImage += padCount - pad;
|
||||
} catch (Exception wb) {
|
||||
wb.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* writeBitmapFileHeader writes the bitmap file header to the file.
|
||||
*
|
||||
*/
|
||||
private void writeBitmapFileHeader() {
|
||||
try {
|
||||
fo.write(bfType);
|
||||
fo.write(intToDWord(bfSize));
|
||||
fo.write(intToWord(bfReserved1));
|
||||
fo.write(intToWord(bfReserved2));
|
||||
fo.write(intToDWord(bfOffBits));
|
||||
} catch (Exception wbfh) {
|
||||
wbfh.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* writeBitmapInfoHeader writes the bitmap information header
|
||||
* to the file.
|
||||
*
|
||||
*/
|
||||
private void writeBitmapInfoHeader() {
|
||||
try {
|
||||
fo.write(intToDWord(biSize));
|
||||
fo.write(intToDWord(biWidth));
|
||||
fo.write(intToDWord(biHeight));
|
||||
fo.write(intToWord(biPlanes));
|
||||
fo.write(intToWord(biBitCount));
|
||||
fo.write(intToDWord(biCompression));
|
||||
fo.write(intToDWord(biSizeImage));
|
||||
fo.write(intToDWord(biXPelsPerMeter));
|
||||
fo.write(intToDWord(biYPelsPerMeter));
|
||||
fo.write(intToDWord(biClrUsed));
|
||||
fo.write(intToDWord(biClrImportant));
|
||||
} catch (Exception wbih) {
|
||||
wbih.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* intToWord converts an int to a word, where the return
|
||||
* value is stored in a 2-byte array.
|
||||
*
|
||||
*/
|
||||
private byte[] intToWord(int parValue) {
|
||||
byte retValue[] = new byte[2];
|
||||
retValue[0] = (byte) (parValue & 0x00FF);
|
||||
retValue[1] = (byte) ((parValue >> 8) & 0x00FF);
|
||||
return (retValue);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* intToDWord converts an int to a double word, where the return
|
||||
* value is stored in a 4-byte array.
|
||||
*
|
||||
*/
|
||||
private byte[] intToDWord(int parValue) {
|
||||
byte retValue[] = new byte[4];
|
||||
retValue[0] = (byte) (parValue & 0x00FF);
|
||||
retValue[1] = (byte) ((parValue >> 8) & 0x000000FF);
|
||||
retValue[2] = (byte) ((parValue >> 16) & 0x000000FF);
|
||||
retValue[3] = (byte) ((parValue >> 24) & 0x000000FF);
|
||||
return (retValue);
|
||||
}
|
||||
}
|
79
src/org/warp/picalculator/Calculator.java
Normal file
79
src/org/warp/picalculator/Calculator.java
Normal file
@ -0,0 +1,79 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import org.nevec.rjm.NumeroAvanzato;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Screen;
|
||||
import org.warp.picalculator.screens.EquationScreen;
|
||||
import org.warp.picalculator.screens.SolveEquationScreen;
|
||||
|
||||
public class Calculator {
|
||||
|
||||
public static String angleMode = "deg";
|
||||
public static Screen[] sessions = new Screen[5];
|
||||
public static int currentSession = 0;
|
||||
public static boolean haxMode = true;
|
||||
|
||||
public static Termine calcolarisultato(String string) throws Errore {
|
||||
System.out.println("INPUT: " + string);
|
||||
Espressione espressione = new Espressione(string);
|
||||
return espressione.calcola();
|
||||
}
|
||||
|
||||
public static Funzione interpreta(String string) throws Errore {
|
||||
if (string.contains("{")) {
|
||||
if (!string.startsWith("{")) {
|
||||
throw new Errore(Errori.SYNTAX_ERROR);
|
||||
}
|
||||
String[] parts = string.substring(1).split("\\{");
|
||||
Sistema s = new Sistema();
|
||||
for (String part : parts) {
|
||||
s.addVariableToEnd(interpretaEquazione(part));
|
||||
}
|
||||
return s;
|
||||
} else if (string.contains("=")) {
|
||||
return interpretaEquazione(string);
|
||||
} else {
|
||||
return new Espressione(string);
|
||||
}
|
||||
}
|
||||
|
||||
public static Funzione interpretaEquazione(String string) throws Errore {
|
||||
String[] parts = string.split("=");
|
||||
if (parts.length == 1) {
|
||||
return new Equazione(new Espressione(parts[0]), new Termine(NumeroAvanzato.ZERO));
|
||||
} else if (parts.length == 2) {
|
||||
return new Equazione(new Espressione(parts[0]), new Espressione(parts[1]));
|
||||
} else {
|
||||
throw new Errore(Errori.SYNTAX_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public static void solve() throws Errore {
|
||||
if (Calculator.currentSession == 0 && Calculator.sessions[0] instanceof EquationScreen) {
|
||||
EquationScreen es = (EquationScreen) Calculator.sessions[0];
|
||||
Funzione f = es.f;
|
||||
if (f instanceof Equazione) {
|
||||
PIDisplay.INSTANCE.setScreen(new SolveEquationScreen(es));
|
||||
} else {
|
||||
es.f2 = es.f.calcola();
|
||||
es.f2.calcolaGrafica();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void solve(char letter) throws Errore {
|
||||
if (Calculator.currentSession == 0 && Calculator.sessions[0] instanceof EquationScreen) {
|
||||
EquationScreen es = (EquationScreen) Calculator.sessions[0];
|
||||
Funzione f = es.f;
|
||||
if (f instanceof Equazione) {
|
||||
es.f2 = ((Equazione)f).calcola(letter);
|
||||
es.f2.calcolaGrafica();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void simplify() {
|
||||
|
||||
}
|
||||
|
||||
}
|
175
src/org/warp/picalculator/Divisione.java
Normal file
175
src/org/warp/picalculator/Divisione.java
Normal file
@ -0,0 +1,175 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.getStringWidth;
|
||||
import static org.warp.engine.Display.Render.glColor3f;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
import static org.warp.engine.Display.Render.glFillRect;
|
||||
|
||||
import org.nevec.rjm.NumeroAvanzatoVec;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Display;
|
||||
|
||||
public class Divisione extends FunzioneDueValoriBase {
|
||||
|
||||
public Divisione(FunzioneBase value1, FunzioneBase value2) {
|
||||
super(value1, value2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return Simboli.DIVISION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Termine calcola() throws Errore {
|
||||
if (variable2 == null || variable1 == null) {
|
||||
return new Termine("0");
|
||||
}
|
||||
if (variable2.calcola().getTerm().compareTo(NumeroAvanzatoVec.ZERO) == 0) {
|
||||
throw new Errore(Errori.DIVISION_BY_ZERO);
|
||||
}
|
||||
return variable1.calcola().divide(variable2.calcola());
|
||||
}
|
||||
|
||||
public boolean hasMinus() {
|
||||
String numerator = variable1.toString();
|
||||
if (numerator.startsWith("-")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void draw(int x, int y, boolean small, boolean drawMinus) {
|
||||
boolean beforedrawminus = this.drawMinus;
|
||||
this.drawMinus = drawMinus;
|
||||
draw(x, y);
|
||||
this.drawMinus = beforedrawminus;
|
||||
}
|
||||
|
||||
private boolean drawMinus = true;
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable1.setSmall(true);
|
||||
variable1.calcolaGrafica();
|
||||
|
||||
variable2.setSmall(true);
|
||||
variable2.calcolaGrafica();
|
||||
|
||||
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);
|
||||
|
||||
Object var1 = variable1;
|
||||
Object var2 = variable2;
|
||||
boolean minus = false;
|
||||
int minusw = 0;
|
||||
int minush = 0;
|
||||
String numerator = ((Funzione) var1).toString();
|
||||
if (numerator.startsWith("-") && ((Funzione) var1) instanceof Termine && ((Termine) var1).term.isBigInteger(true)) {
|
||||
minus = true;
|
||||
numerator = numerator.substring(1);
|
||||
}
|
||||
int w1 = 0;
|
||||
int h1 = 0;
|
||||
if (minus) {
|
||||
w1 = getStringWidth(numerator);
|
||||
h1 = Utils.getFontHeight(small);
|
||||
} else {
|
||||
w1 = ((Funzione) var1).getWidth();
|
||||
h1 = ((Funzione) var1).getHeight();
|
||||
}
|
||||
int w2 = ((Funzione) var2).getWidth();
|
||||
int maxw;
|
||||
if (w1 > w2) {
|
||||
maxw = 1 + w1;
|
||||
} else {
|
||||
maxw = 1 + w2;
|
||||
}
|
||||
if (minus && drawMinus) {
|
||||
minusw = getStringWidth("-") + 1;
|
||||
minush = Utils.getFontHeight(small);
|
||||
if (small) {
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
} else {
|
||||
Display.Render.setFont(PIDisplay.fonts[0]);
|
||||
}
|
||||
glDrawStringLeft(x+1, y + h1 + 1 + 1 - (minush / 2), "-");
|
||||
glDrawStringLeft((int) (x+1 + minusw + 1 + (maxw - w1) / 2d), y, numerator);
|
||||
} else {
|
||||
((Funzione) var1).draw((int) (x+1 + minusw + (maxw - w1) / 2d), y);
|
||||
}
|
||||
((Funzione) var2).draw((int) (x+1 + minusw + (maxw - w2) / 2d), y + h1 + 1 + 1 + 1);
|
||||
glColor3f(0, 0, 0);
|
||||
glFillRect(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 Termine && ((Termine) variable1).term.isBigInteger(true)) {
|
||||
minus = true;
|
||||
numerator = numerator.substring(1);
|
||||
}
|
||||
int h1 = 0;
|
||||
if (minus) {
|
||||
h1 = Utils.getFontHeight(small);
|
||||
} else {
|
||||
h1 = variable1.getHeight();
|
||||
}
|
||||
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 Termine && ((Termine) variable1).term.isBigInteger(true)) {
|
||||
minus = true;
|
||||
numerator = numerator.substring(1);
|
||||
}
|
||||
int w1 = 0;
|
||||
if (minus) {
|
||||
w1 = getStringWidth(numerator);
|
||||
} else {
|
||||
w1 = variable1.getWidth();
|
||||
}
|
||||
int w2 = variable2.getWidth();
|
||||
int maxw = 0;
|
||||
if (w1 > w2) {
|
||||
maxw = w1+1;
|
||||
} else {
|
||||
maxw = w2+1;
|
||||
}
|
||||
if (minus && drawMinus) {
|
||||
return 1 + getStringWidth("-") + 1 + maxw;
|
||||
} else {
|
||||
return 1 + maxw;
|
||||
}
|
||||
}
|
||||
}
|
57
src/org/warp/picalculator/Equazione.java
Normal file
57
src/org/warp/picalculator/Equazione.java
Normal file
@ -0,0 +1,57 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
public class Equazione extends FunzioneDueValori {
|
||||
|
||||
public Equazione(Funzione value1, Funzione value2) {
|
||||
super(value1,value2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return Simboli.EQUATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Funzione calcola() throws Errore {
|
||||
return new Equazione(new Sottrazione((FunzioneBase)variable1.calcola(), (FunzioneBase)variable2.calcola()).calcola(), new Termine("0"));
|
||||
}
|
||||
|
||||
public Funzione calcola(char charIncognita) {
|
||||
@SuppressWarnings("unused")
|
||||
ArrayList<Equazione> e;
|
||||
//TODO: Finire. Fare in modo che risolva i passaggi fino a che non ce ne sono più
|
||||
return null;
|
||||
}
|
||||
|
||||
public ArrayList<Equazione> risolviPassaggio(char charIncognita) {
|
||||
ArrayList<Equazione> result = new ArrayList<Equazione>();
|
||||
result.add(this.clone());
|
||||
for (Tecnica t : Tecnica.tecniche) {
|
||||
ArrayList<Equazione> newResults = new ArrayList<Equazione>();
|
||||
final int sz = result.size();
|
||||
for (int n = 0; n < sz; n++) {
|
||||
newResults.addAll(t.risolvi(result.get(n)));
|
||||
}
|
||||
Set<Equazione> hs = new HashSet<>();
|
||||
hs.addAll(newResults);
|
||||
newResults.clear();
|
||||
newResults.addAll(hs);
|
||||
result = newResults;
|
||||
}
|
||||
// TODO: controllare se è a posto
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Equazione clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
|
||||
public class Errore extends java.lang.Throwable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -1014947815755694651L;
|
||||
|
||||
public Errore(Errori IDErrore) {
|
||||
id = IDErrore;
|
||||
}
|
||||
|
||||
public Errori id = Errori.ERROR;
|
||||
}
|
||||
package org.warp.picalculator;
|
||||
|
||||
public class Errore extends java.lang.Throwable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -1014947815755694651L;
|
||||
|
||||
public Errore(Errori IDErrore) {
|
||||
id = IDErrore;
|
||||
}
|
||||
|
||||
public Errori id = Errori.ERROR;
|
||||
}
|
5
src/org/warp/picalculator/Errori.java
Normal file
5
src/org/warp/picalculator/Errori.java
Normal file
@ -0,0 +1,5 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
public enum Errori {
|
||||
ERROR, DIVISION_BY_ZERO, UNBALANCED_BRACKETS, NOT_IMPLEMENTED, NEGATIVE_PARAMETER, NUMBER_TOO_LARGE, NUMBER_TOO_SMALL, CONVERSION_ERROR, SYNTAX_ERROR, NOT_AN_EQUATION
|
||||
}
|
673
src/org/warp/picalculator/Espressione.java
Normal file
673
src/org/warp/picalculator/Espressione.java
Normal file
@ -0,0 +1,673 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.glColor3f;
|
||||
import static org.warp.engine.Display.Render.glDrawLine;
|
||||
import static org.warp.picalculator.Utils.ArrayToRegex;
|
||||
import static org.warp.picalculator.Utils.concat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.nevec.rjm.NumeroAvanzato;
|
||||
import org.nevec.rjm.NumeroAvanzatoVec;
|
||||
|
||||
public class Espressione extends FunzioneMultiplaBase {
|
||||
|
||||
public Espressione() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Espressione(FunzioneBase[] values) {
|
||||
super(values);
|
||||
}
|
||||
|
||||
private boolean parentesiIniziale = false;
|
||||
|
||||
public Espressione(String string) throws Errore {
|
||||
this(string, "", true);
|
||||
}
|
||||
|
||||
public Espressione(String string, String debugSpaces, boolean parentesiIniziale) throws Errore {
|
||||
super();
|
||||
this.parentesiIniziale = parentesiIniziale;
|
||||
boolean isNumber = false;
|
||||
|
||||
// Determina se l'espressione è già un numero:
|
||||
try {
|
||||
new Termine(string);
|
||||
isNumber = true;
|
||||
} catch (NumberFormatException ex) {
|
||||
isNumber = false;
|
||||
}
|
||||
|
||||
String processExpression = string;
|
||||
Utils.debug.println(debugSpaces + "•Analyzing expression:" + processExpression);
|
||||
|
||||
if (isNumber){
|
||||
// Se l'espressione è già un numero:
|
||||
Termine t = new Termine(string);
|
||||
setVariables(new FunzioneBase[] { t });
|
||||
Utils.debug.println(debugSpaces + "•Result:" + t.toString());
|
||||
} else {
|
||||
// Altrimenti prepara l'espressione:
|
||||
debugSpaces += " ";
|
||||
|
||||
// Se l'espressione non è già un numero:
|
||||
|
||||
// Controlla se ci sono più di un uguale
|
||||
int equationsFound = 0;
|
||||
int systemsFound = 0;
|
||||
for (char c : processExpression.toCharArray()) {
|
||||
if (("" + c).equals(Simboli.EQUATION)) {
|
||||
equationsFound += 1;
|
||||
}
|
||||
if (("" + c).equals(Simboli.SYSTEM)) {
|
||||
equationsFound += 1;
|
||||
}
|
||||
}
|
||||
if (equationsFound == 1 && systemsFound == 0) {
|
||||
processExpression = Simboli.SYSTEM + processExpression;
|
||||
systemsFound += 1;
|
||||
}
|
||||
if (equationsFound != systemsFound) {
|
||||
throw new Errore(Errori.SYNTAX_ERROR);
|
||||
}
|
||||
|
||||
// Correggi i segni ++ e -- in eccesso
|
||||
Pattern pattern = Pattern.compile("\\+\\++?|\\-\\-+?");
|
||||
Matcher matcher = pattern.matcher(processExpression);
|
||||
boolean cambiati = false;
|
||||
while (matcher.find()) {
|
||||
cambiati = true;
|
||||
String correzione = "+";
|
||||
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
|
||||
matcher = pattern.matcher(processExpression);
|
||||
}
|
||||
|
||||
// Correggi i segni +- e -+ in eccesso
|
||||
pattern = Pattern.compile("\\+\\-|\\-\\+");
|
||||
matcher = pattern.matcher(processExpression);
|
||||
while (matcher.find()) {
|
||||
cambiati = true;
|
||||
String correzione = "-";
|
||||
processExpression = processExpression.substring(0, matcher.start(0)) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
|
||||
matcher = pattern.matcher(processExpression);
|
||||
}
|
||||
|
||||
// Rimuovi i segni appena dopo le parentesi
|
||||
if (processExpression.contains("(+")) {
|
||||
cambiati = true;
|
||||
processExpression = processExpression.replace("(+", "(");
|
||||
}
|
||||
|
||||
// Cambia i segni appena prima le parentesi
|
||||
if (processExpression.contains("-(")) {
|
||||
cambiati = true;
|
||||
processExpression = processExpression.replace("-(", "-1*(");
|
||||
}
|
||||
// Rimuovi i segni appena dopo l'inizio
|
||||
if (processExpression.startsWith("+")) {
|
||||
cambiati = true;
|
||||
processExpression = processExpression.substring(1, processExpression.length());
|
||||
}
|
||||
|
||||
// Rimuovi i + in eccesso
|
||||
pattern = Pattern.compile("[" + ArrayToRegex(Utils.add(concat(Simboli.segni(true, true), Simboli.funzioni()), "(")) + "]\\+[^" + ArrayToRegex(concat(concat(Simboli.segni(true, true), Simboli.funzioni()), new String[] { "(", ")" })) + "]+?[" + ArrayToRegex(concat(Simboli.segni(true, true), Simboli.funzioni())) + "]|[" + ArrayToRegex(concat(Simboli.segni(true, true), Simboli.funzioni())) + "]+?\\+[^" + ArrayToRegex(concat(concat(Simboli.segni(true, true), Simboli.funzioni()), new String[] { "(", ")" })) + "]");
|
||||
matcher = pattern.matcher(processExpression);
|
||||
cambiati = false;
|
||||
while (matcher.find()) {
|
||||
cambiati = true;
|
||||
String correzione = matcher.group(0).replaceFirst(Matcher.quoteReplacement("+"), "");
|
||||
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
|
||||
matcher = pattern.matcher(processExpression);
|
||||
}
|
||||
|
||||
// Correggi i segni - in +-
|
||||
pattern = Pattern.compile("[^" + Utils.ArrayToRegex(concat(concat(Simboli.funzioni(), new String[] { Simboli.PARENTHESIS_OPEN }), Simboli.segni(true, true))) + "]-");
|
||||
matcher = pattern.matcher(processExpression);
|
||||
while (matcher.find()) {
|
||||
cambiati = true;
|
||||
String correzione = "+-";
|
||||
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
|
||||
matcher = pattern.matcher(processExpression);
|
||||
}
|
||||
|
||||
if (cambiati) {
|
||||
Utils.debug.println(debugSpaces + "•Resolved signs:" + processExpression);
|
||||
}
|
||||
|
||||
// Aggiungi i segni * accanto alle parentesi
|
||||
pattern = Pattern.compile("\\([^\\(]+?\\)");
|
||||
matcher = pattern.matcher(processExpression);
|
||||
cambiati = false;
|
||||
while (matcher.find()) {
|
||||
cambiati = true;
|
||||
// sistema i segni * impliciti prima e dopo l'espressione.
|
||||
String beforeexp = processExpression.substring(0, matcher.start(0));
|
||||
String newexp = matcher.group(0).substring(1, matcher.group(0).length() - 1);
|
||||
String afterexp = processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
|
||||
if (Pattern.compile("[^\\-" + Utils.ArrayToRegex(Utils.add(concat(Simboli.funzioni(), concat(Simboli.segni(true, true), Simboli.sintassiGenerale())), "(")) + "]$").matcher(beforeexp).find()) {
|
||||
// Se la stringa precedente finisce con un numero
|
||||
beforeexp += Simboli.MULTIPLICATION;
|
||||
}
|
||||
if (Pattern.compile("^[^\\-" + Utils.ArrayToRegex(Utils.add(concat(Simboli.funzioni(), concat(Simboli.segni(true, true), Simboli.sintassiGenerale())), ")")) + "]").matcher(afterexp).find()) {
|
||||
// Se la stringa successiva inizia con un numero
|
||||
afterexp = Simboli.MULTIPLICATION + afterexp;
|
||||
}
|
||||
processExpression = beforeexp + "⑴" + newexp + "⑵" + afterexp;
|
||||
matcher = pattern.matcher(processExpression);
|
||||
}
|
||||
|
||||
processExpression = processExpression.replace("⑴", "(").replace("⑵", ")");
|
||||
|
||||
if (cambiati) {
|
||||
Utils.debug.println(debugSpaces + "•Added implicit multiplications:" + processExpression);
|
||||
}
|
||||
|
||||
Utils.debug.println(debugSpaces + "•Subdivision in classes:");
|
||||
|
||||
debugSpaces += " ";
|
||||
|
||||
// Suddividi tutto
|
||||
Espressione parentesiNonSuddivisaCorrettamente = new Espressione();
|
||||
parentesiNonSuddivisaCorrettamente.setVariables(new FunzioneBase[] {});
|
||||
String tmp = "";
|
||||
final String[] funzioni = concat(concat(concat(concat(Simboli.funzioni(), Simboli.parentesi()), Simboli.segni(true, true)), Simboli.incognite()), Simboli.sintassiGenerale());
|
||||
for (int i = 0; i < processExpression.length(); i++) {
|
||||
// Per ogni carattere cerca se è un numero o una funzione:
|
||||
String charI = processExpression.charAt(i) + "";
|
||||
if (Utils.isInArray(charI, funzioni)) {
|
||||
|
||||
// Cerca il tipo di funzione tra le esistenti
|
||||
FunzioneBase f = null;
|
||||
switch (charI) {
|
||||
case Simboli.SUM:
|
||||
f = new Somma(null, null);
|
||||
break;
|
||||
case Simboli.MULTIPLICATION:
|
||||
f = new Moltiplicazione(null, null);
|
||||
break;
|
||||
case Simboli.PRIORITARY_MULTIPLICATION:
|
||||
f = new MoltiplicazionePrioritaria(null, null);
|
||||
break;
|
||||
case Simboli.DIVISION:
|
||||
f = new Divisione(null, null);
|
||||
break;
|
||||
case Simboli.NTH_ROOT:
|
||||
f = new Radice(null, null);
|
||||
break;
|
||||
case Simboli.SQUARE_ROOT:
|
||||
f = new RadiceQuadrata(null);
|
||||
break;
|
||||
case Simboli.POTENZA:
|
||||
f = new Potenza(null, null);
|
||||
break;
|
||||
case Simboli.PARENTHESIS_OPEN:
|
||||
// cerca l'ultima parentesi chiusa
|
||||
int startIndex = i;
|
||||
int endIndex = -1;
|
||||
int jumps = -1;
|
||||
for (int i2 = startIndex; i2 < processExpression.length(); i2++) {
|
||||
if ((processExpression.charAt(i2) + "").equals(Simboli.PARENTHESIS_CLOSE)) {
|
||||
if (jumps == 0) {
|
||||
endIndex = i2;
|
||||
break;
|
||||
} else if (jumps > 0) {
|
||||
jumps -= 1;
|
||||
} else if (jumps < 0) {
|
||||
throw new Errore(Errori.UNBALANCED_BRACKETS);
|
||||
}
|
||||
} else if ((processExpression.charAt(i2) + "").equals(Simboli.PARENTHESIS_OPEN)) {
|
||||
jumps += 1;
|
||||
}
|
||||
}
|
||||
if (endIndex == -1 || endIndex < startIndex) {
|
||||
throw new Errore(Errori.UNBALANCED_BRACKETS);
|
||||
}
|
||||
startIndex += 1;
|
||||
i = startIndex;
|
||||
|
||||
String tmpExpr = "";
|
||||
while (i < endIndex) {
|
||||
tmpExpr += processExpression.charAt(i);
|
||||
i++;
|
||||
}
|
||||
f = new Espressione(tmpExpr, debugSpaces, false);
|
||||
break;
|
||||
default:
|
||||
if (Utils.isInArray(charI, Simboli.incognite())) {
|
||||
// Fallback
|
||||
NumeroAvanzato na = NumeroAvanzato.ONE;
|
||||
Incognite iy = na.getIncognitey();
|
||||
iy.incognite.add(new Incognita(charI.charAt(0), 1, 1));
|
||||
na = na.setIncognitey(iy);
|
||||
f = new Termine(na);
|
||||
} else {
|
||||
throw new java.lang.RuntimeException("Il carattere " + charI + " non è tra le funzioni designate!\nAggiungerlo ad esse o rimuovere il carattere dall'espressione!");
|
||||
}
|
||||
}
|
||||
if (f instanceof Espressione) {
|
||||
tmp = "";
|
||||
} else if (f instanceof Termine) {
|
||||
if (parentesiNonSuddivisaCorrettamente.getVariablesLength() == 0) {
|
||||
if (tmp.length() > 0) {
|
||||
parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp));
|
||||
Utils.debug.println(debugSpaces + "•Added value to expression:" + tmp);
|
||||
parentesiNonSuddivisaCorrettamente.addVariableToEnd(new MoltiplicazionePrioritaria(null, null));
|
||||
Utils.debug.println(debugSpaces + "•Added variable to expression:" + new MoltiplicazionePrioritaria(null, null).simbolo());
|
||||
}
|
||||
} else {
|
||||
if (tmp.length() > 0) {
|
||||
if (parentesiNonSuddivisaCorrettamente.getVariable(parentesiNonSuddivisaCorrettamente.getVariablesLength() - 1) instanceof Termine) {
|
||||
parentesiNonSuddivisaCorrettamente.addVariableToEnd(new MoltiplicazionePrioritaria(null, null));
|
||||
Utils.debug.println(debugSpaces + "•Added variable to expression:" + new MoltiplicazionePrioritaria(null, null).simbolo());
|
||||
}
|
||||
if (tmp.equals("-")) {
|
||||
tmp = "-1";
|
||||
}
|
||||
parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp));
|
||||
Utils.debug.println(debugSpaces + "•Added value to expression:" + tmp);
|
||||
}
|
||||
if (tmp.length() > 0 || parentesiNonSuddivisaCorrettamente.getVariable(parentesiNonSuddivisaCorrettamente.getVariablesLength() - 1) instanceof Termine) {
|
||||
parentesiNonSuddivisaCorrettamente.addVariableToEnd(new MoltiplicazionePrioritaria(null, null));
|
||||
Utils.debug.println(debugSpaces + "•Added variable to expression:" + new MoltiplicazionePrioritaria(null, null).simbolo());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tmp.length() != 0) {
|
||||
parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp));
|
||||
Utils.debug.println(debugSpaces + "•Added variable to expression:" + tmp);
|
||||
}
|
||||
}
|
||||
parentesiNonSuddivisaCorrettamente.addVariableToEnd(f);
|
||||
Utils.debug.println(debugSpaces + "•Added variable to expression:" + f.simbolo());
|
||||
tmp = "";
|
||||
} else {
|
||||
try {
|
||||
if (charI.equals("-") == false && charI.equals(".") == false) {
|
||||
new BigDecimal(tmp + charI);
|
||||
}
|
||||
// Se il carattere è un numero intero, un segno
|
||||
// negativo, o un punto
|
||||
tmp += charI;
|
||||
} catch (Exception exc) {
|
||||
throw new java.lang.RuntimeException("Il carattere " + tmp + charI + " non è nè un numero nè un espressione presente nella lista completa!\nAggiungerlo ad essa o rimuovere il carattere dall'espressione!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tmp.length() > 0) {
|
||||
Utils.debug.println(debugSpaces + "•Added variable to expression:" + tmp);
|
||||
try {
|
||||
parentesiNonSuddivisaCorrettamente.addVariableToEnd(new Termine(tmp));
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new Errore(Errori.SYNTAX_ERROR);
|
||||
}
|
||||
tmp = "";
|
||||
}
|
||||
|
||||
int dsl = debugSpaces.length();
|
||||
debugSpaces = "";
|
||||
for (int i = 0; i < dsl - 2; i++) {
|
||||
debugSpaces += " ";
|
||||
}
|
||||
Utils.debug.println(debugSpaces + "•Finished the subdivision in classes.");
|
||||
// Fine suddivisione di insieme
|
||||
|
||||
Utils.debug.println(debugSpaces + "•Removing useless parentheses");
|
||||
for (int i = 0; i < parentesiNonSuddivisaCorrettamente.variables.length; i++) {
|
||||
if (parentesiNonSuddivisaCorrettamente.variables[i] instanceof Espressione) {
|
||||
Espressione par = (Espressione) parentesiNonSuddivisaCorrettamente.variables[i];
|
||||
if (par.variables.length == 1) {
|
||||
FunzioneBase subFunz = par.variables[0];
|
||||
if (subFunz instanceof Espressione || subFunz instanceof Termine) {
|
||||
parentesiNonSuddivisaCorrettamente.variables[i] = subFunz;
|
||||
Utils.debug.println(debugSpaces + " •Useless parentheses removed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inizia l'affinazione dell'espressione
|
||||
Utils.debug.println(debugSpaces + "•Pushing classes...");
|
||||
|
||||
FunzioneBase[] funzioniOLDArray = parentesiNonSuddivisaCorrettamente.getVariables();
|
||||
ArrayList<FunzioneBase> funzioniOLD = new ArrayList<FunzioneBase>();
|
||||
for (int i = 0; i < funzioniOLDArray.length; i++) {
|
||||
FunzioneBase funzione = funzioniOLDArray[i];
|
||||
if (funzione != null) {
|
||||
//Affinazione
|
||||
if (funzione instanceof Radice) {
|
||||
if ((i - 1) >= 0 && funzioniOLDArray[i-1] instanceof Termine && ((Termine)funzioniOLDArray[i-1]).getTerm().compareTo(new NumeroAvanzatoVec(new NumeroAvanzato(new BigInteger("2")))) == 0) {
|
||||
funzioniOLDArray[i] = null;
|
||||
funzioniOLDArray[i-1] = null;
|
||||
funzioniOLD.remove(funzioniOLD.size()-1);
|
||||
i -= 1;
|
||||
funzione = new RadiceQuadrata(null);
|
||||
}
|
||||
}
|
||||
//Aggiunta della funzione alla lista grezza
|
||||
funzioniOLD.add(funzione);
|
||||
}
|
||||
}
|
||||
|
||||
if (funzioniOLD.size() > 1) {
|
||||
Utils.debug.println(debugSpaces + " •Correcting classes:");
|
||||
|
||||
int before = 0;
|
||||
String fase = "funzioniSN";
|
||||
int n = 0;
|
||||
do {
|
||||
before = funzioniOLD.size();
|
||||
int i = 0;
|
||||
boolean change = false;
|
||||
if (Utils.ciSonoMoltiplicazioniPrioritarieNonImpostate(funzioniOLD)) {
|
||||
fase = "moltiplicazioni prioritarie"; // PRIMA FASE
|
||||
} else if (Utils.ciSonoFunzioniSNnonImpostate(funzioniOLD)) {
|
||||
fase = "funzioniSN"; // SECONDA FASE
|
||||
} else if (Utils.ciSonoFunzioniNSNnonImpostate(funzioniOLD)) {
|
||||
fase = "funzioniNSN"; // TERZA FASE
|
||||
} else if (Utils.ciSonoMoltiplicazioniNonImpostate(funzioniOLD)) {
|
||||
fase = "moltiplicazioni"; // QUARTA FASE
|
||||
} else if (Utils.ciSonoSommeNonImpostate(funzioniOLD)) {
|
||||
fase = "somme"; // QUINTA FASE
|
||||
} else {
|
||||
// fase = "errore";
|
||||
System.out.println("WARN: ---> POSSIBILE ERRORE????? <---");// BOH
|
||||
// throw new Errore(Errori.SYNTAX_ERROR);
|
||||
while (funzioniOLD.size() > 1) {
|
||||
funzioniOLD.set(0, new Moltiplicazione(funzioniOLD.get(0), funzioniOLD.remove(1)));
|
||||
}
|
||||
}
|
||||
Utils.debug.println(debugSpaces + " •Phase: "+fase);
|
||||
while (i < funzioniOLD.size() && change == false && funzioniOLD.size() > 1) {
|
||||
FunzioneBase funzioneTMP = funzioniOLD.get(i);
|
||||
if (funzioneTMP instanceof FunzioneDueValoriBase) {
|
||||
if (fase != "funzioniSN") {
|
||||
if (
|
||||
(fase == "somme" && (funzioneTMP instanceof Somma) == true && ((funzioneTMP instanceof FunzioneAnterioreBase && ((FunzioneAnterioreBase) funzioneTMP).variable == null) || (funzioneTMP instanceof FunzioneDueValoriBase && ((FunzioneDueValoriBase) funzioneTMP).variable1 == null && ((FunzioneDueValoriBase) funzioneTMP).variable2 == null) || (!(funzioneTMP instanceof FunzioneAnterioreBase) && !(funzioneTMP instanceof FunzioneDueValoriBase))))
|
||||
||
|
||||
(
|
||||
fase.equals("moltiplicazioni prioritarie")
|
||||
&&
|
||||
(funzioneTMP instanceof MoltiplicazionePrioritaria)
|
||||
&&
|
||||
((FunzioneDueValoriBase) funzioneTMP).variable1 == null
|
||||
&&
|
||||
((FunzioneDueValoriBase) funzioneTMP).variable2 == null
|
||||
)
|
||||
||
|
||||
(
|
||||
fase.equals("moltiplicazioni")
|
||||
&&
|
||||
(
|
||||
(funzioneTMP instanceof Moltiplicazione)
|
||||
||
|
||||
(funzioneTMP instanceof Divisione)
|
||||
)
|
||||
&&
|
||||
((FunzioneDueValoriBase) funzioneTMP).variable1 == null
|
||||
&&
|
||||
((FunzioneDueValoriBase) funzioneTMP).variable2 == null
|
||||
)
|
||||
||
|
||||
(
|
||||
fase == "funzioniNSN"
|
||||
&&
|
||||
(funzioneTMP instanceof Somma) == false
|
||||
&&
|
||||
(funzioneTMP instanceof Moltiplicazione) == false
|
||||
&&
|
||||
(funzioneTMP instanceof MoltiplicazionePrioritaria) == false
|
||||
&&
|
||||
(funzioneTMP instanceof Divisione) == false
|
||||
&&
|
||||
(
|
||||
(
|
||||
funzioneTMP instanceof FunzioneAnterioreBase
|
||||
&&
|
||||
((FunzioneAnterioreBase) funzioneTMP).variable == null
|
||||
)
|
||||
||
|
||||
(
|
||||
funzioneTMP instanceof FunzioneDueValoriBase
|
||||
&&
|
||||
((FunzioneDueValoriBase) funzioneTMP).variable1 == null
|
||||
&&
|
||||
((FunzioneDueValoriBase) funzioneTMP).variable2 == null
|
||||
)
|
||||
||
|
||||
(
|
||||
!(funzioneTMP instanceof FunzioneAnterioreBase)
|
||||
&&
|
||||
!(funzioneTMP instanceof FunzioneDueValoriBase)
|
||||
)
|
||||
)
|
||||
)
|
||||
) {
|
||||
change = true;
|
||||
|
||||
if (i + 1 < funzioniOLD.size() && i - 1 >= 0) {
|
||||
((FunzioneDueValoriBase) funzioneTMP).setVariable1((FunzioneBase) funzioniOLD.get(i - 1));
|
||||
((FunzioneDueValoriBase) funzioneTMP).setVariable2((FunzioneBase) funzioniOLD.get(i + 1));
|
||||
funzioniOLD.set(i, funzioneTMP);
|
||||
|
||||
// è importante togliere prima gli elementi
|
||||
// in fondo e poi quelli davanti, perché gli
|
||||
// indici scalano da destra a sinistra.
|
||||
funzioniOLD.remove(i + 1);
|
||||
funzioniOLD.remove(i - 1);
|
||||
|
||||
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.simbolo());
|
||||
try {
|
||||
Utils.debug.println(debugSpaces + " " + "var1=" + ((FunzioneDueValoriBase) funzioneTMP).getVariable1().calcola());
|
||||
} catch (NullPointerException ex2) {}
|
||||
try {
|
||||
Utils.debug.println(debugSpaces + " " + "var2=" + ((FunzioneDueValoriBase) funzioneTMP).getVariable2().calcola());
|
||||
} catch (NullPointerException ex2) {}
|
||||
try {
|
||||
Utils.debug.println(debugSpaces + " " + "(result)=" + ((FunzioneDueValoriBase) funzioneTMP).calcola());
|
||||
} catch (NullPointerException ex2) {}
|
||||
|
||||
} else {
|
||||
throw new java.lang.RuntimeException("Argomenti mancanti! Sistemare l'equazione!");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (funzioneTMP instanceof FunzioneAnterioreBase) {
|
||||
if ((fase == "funzioniSN" && ((FunzioneAnterioreBase) funzioneTMP).variable == null)) {
|
||||
if (i + 1 < funzioniOLD.size()) {
|
||||
FunzioneBase nextFunc = funzioniOLD.get(i + 1);
|
||||
if (nextFunc instanceof FunzioneAnterioreBase && ((FunzioneAnterioreBase)nextFunc).variable == null) {
|
||||
|
||||
} else {
|
||||
change = true;
|
||||
((FunzioneAnterioreBase) funzioneTMP).setVariable((FunzioneBase) nextFunc);
|
||||
funzioniOLD.set(i, funzioneTMP);
|
||||
|
||||
// è importante togliere prima gli elementi in
|
||||
// fondo e poi quelli davanti, perché gli indici
|
||||
// scalano da destra a sinistra.
|
||||
funzioniOLD.remove(i + 1);
|
||||
|
||||
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.simbolo());
|
||||
FunzioneBase var = ((FunzioneAnterioreBase) funzioneTMP).getVariable().calcola();
|
||||
if (var == null) {
|
||||
Utils.debug.println(debugSpaces + " " + "var=null");
|
||||
} else {
|
||||
Utils.debug.println(debugSpaces + " " + "var=" + var.toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new java.lang.RuntimeException("Argomenti mancanti! Sistemare l'equazione!");
|
||||
}
|
||||
}
|
||||
} else if (funzioneTMP instanceof Termine || funzioneTMP instanceof Espressione) {
|
||||
if (n < 300) {
|
||||
// Utils.debug.println(debugSpaces+" •Set variable
|
||||
// to number:"+funzioneTMP.calcola());
|
||||
}
|
||||
} else {
|
||||
throw new java.lang.RuntimeException("Tipo sconosciuto");
|
||||
}
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
} while (((funzioniOLD.size() != before || fase != "somme") && funzioniOLD.size() > 1));
|
||||
}
|
||||
setVariables(funzioniOLD);
|
||||
|
||||
dsl = debugSpaces.length();
|
||||
debugSpaces = "";
|
||||
for (int i = 0; i < dsl - 2; i++) {
|
||||
debugSpaces += " ";
|
||||
}
|
||||
Utils.debug.println(debugSpaces + "•Finished correcting classes.");
|
||||
|
||||
Termine result = calcola();
|
||||
Utils.debug.println(debugSpaces + "•Result:" + result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return "Parentesi";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Termine calcola() throws Errore {
|
||||
if (variables.length == 0) {
|
||||
return new Termine("0");
|
||||
} else if (variables.length == 1) {
|
||||
return (Termine) variables[0].calcola();
|
||||
} else {
|
||||
Termine result = new Termine("0");
|
||||
for (Funzione f : variables) {
|
||||
result = result.add((Termine) f.calcola());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
for (Funzione var : variables) {
|
||||
var.setSmall(small);
|
||||
var.calcolaGrafica();
|
||||
}
|
||||
|
||||
width = calcWidth();
|
||||
height = calcHeight();
|
||||
line = calcLine();
|
||||
}
|
||||
|
||||
public boolean parenthesesNeeded() {
|
||||
boolean parenthesesneeded = true;
|
||||
if (parentesiIniziale) {
|
||||
parenthesesneeded = false;
|
||||
} else {
|
||||
if (variables.length == 1) {
|
||||
if (variables[0] instanceof Divisione) {
|
||||
parenthesesneeded = false;
|
||||
} else {
|
||||
parenthesesneeded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parenthesesneeded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
if (parenthesesNeeded() == false) {
|
||||
this.variables[0].draw(x, y);
|
||||
} else {
|
||||
float miny = y;
|
||||
float maxy = y + getHeight();
|
||||
int h = getHeight();
|
||||
x += 1;
|
||||
glColor3f(0, 0, 0);
|
||||
glDrawLine(x, y + 2, x + 2, y);
|
||||
glDrawLine(x, y + 2, x, y + h - 3);
|
||||
glDrawLine(x, y + h - 3, x + 2, y + h - 1);
|
||||
x += 4;
|
||||
for (Funzione f : variables) {
|
||||
float fheight = f.getHeight();
|
||||
float y2 = miny + ((maxy - miny) / 2 - fheight / 2);
|
||||
f.draw(x, (int) y2);
|
||||
x += f.getWidth();
|
||||
}
|
||||
x += 2;
|
||||
glDrawLine(x, y, x + 2, y + 2);
|
||||
glDrawLine(x + 2, y + 2, x + 2, y + h - 3);
|
||||
glDrawLine(x, y + h - 1, x + 2, y + h - 3);
|
||||
x += 4;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
private int calcWidth() {
|
||||
if (parenthesesNeeded() == false) {
|
||||
return this.variables[0].getWidth();
|
||||
} else {
|
||||
int w = 0;
|
||||
for (Funzione f : variables) {
|
||||
w += f.getWidth();
|
||||
}
|
||||
return 1 + 4 + w + 2 + 4;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
private int calcHeight() {
|
||||
if (parentesiIniziale || variables.length == 1) {
|
||||
return this.variables[0].getHeight();
|
||||
} else {
|
||||
Funzione tmin = null;
|
||||
Funzione tmax = null;
|
||||
for (Funzione t : variables) {
|
||||
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 (parentesiIniziale || variables.length == 1) {
|
||||
return this.variables[0].getLine();
|
||||
} else {
|
||||
Funzione tl = null;
|
||||
for (Funzione t : variables) {
|
||||
if (tl == null || t.getLine() >= tl.getLine()) {
|
||||
tl = t;
|
||||
}
|
||||
}
|
||||
if (tl == null)
|
||||
return Utils.getFontHeight(small) / 2;
|
||||
return tl.getLine();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
19
src/org/warp/picalculator/Funzione.java
Normal file
19
src/org/warp/picalculator/Funzione.java
Normal file
@ -0,0 +1,19 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
public interface Funzione {
|
||||
public String simbolo();
|
||||
|
||||
public Funzione calcola() throws Errore;
|
||||
|
||||
public void calcolaGrafica();
|
||||
|
||||
public void draw(int x, int y);
|
||||
|
||||
public int getWidth();
|
||||
|
||||
public int getHeight();
|
||||
|
||||
public int getLine();
|
||||
|
||||
public void setSmall(boolean small);
|
||||
}
|
97
src/org/warp/picalculator/FunzioneAnteriore.java
Normal file
97
src/org/warp/picalculator/FunzioneAnteriore.java
Normal file
@ -0,0 +1,97 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.getStringWidth;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
|
||||
import org.nevec.rjm.NumeroAvanzatoVec;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Display;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
public abstract class FunzioneAnteriore implements Funzione {
|
||||
public FunzioneAnteriore(Funzione value) {
|
||||
setVariable(value);
|
||||
}
|
||||
|
||||
protected Funzione variable = new Termine(NumeroAvanzatoVec.ZERO);
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int line;
|
||||
protected boolean small;
|
||||
|
||||
public Funzione getVariable() {
|
||||
return variable;
|
||||
}
|
||||
|
||||
public void setVariable(Funzione value) {
|
||||
variable = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String simbolo();
|
||||
|
||||
@Override
|
||||
public abstract Funzione calcola() throws Errore;
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable.setSmall(small);
|
||||
variable.calcolaGrafica();
|
||||
|
||||
width = getStringWidth(simbolo()) + 1 + getVariable().getWidth();
|
||||
height = variable.getHeight();
|
||||
line = variable.getLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
float h1 = getVariable().getHeight();
|
||||
int wsegno = getStringWidth(simbolo());
|
||||
float hsegno = Utils.getFontHeight(small);
|
||||
float maxh = getHeight();
|
||||
if (small) {
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
} else {
|
||||
Display.Render.setFont(PIDisplay.fonts[0]);
|
||||
}
|
||||
|
||||
glDrawStringLeft(x, (int) Math.floor(y + (maxh - hsegno) / 2), simbolo());
|
||||
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 calcola().toString();
|
||||
} catch (Errore e) {
|
||||
return e.id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunzioneAnteriore clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
}
|
97
src/org/warp/picalculator/FunzioneAnterioreBase.java
Normal file
97
src/org/warp/picalculator/FunzioneAnterioreBase.java
Normal file
@ -0,0 +1,97 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.getStringWidth;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
|
||||
import org.nevec.rjm.NumeroAvanzatoVec;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Display;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
public abstract class FunzioneAnterioreBase extends FunzioneBase {
|
||||
public FunzioneAnterioreBase(FunzioneBase value) {
|
||||
setVariable(value);
|
||||
}
|
||||
|
||||
protected FunzioneBase variable = new Termine(NumeroAvanzatoVec.ZERO);
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int line;
|
||||
protected boolean small;
|
||||
|
||||
public FunzioneBase getVariable() {
|
||||
return variable;
|
||||
}
|
||||
|
||||
public void setVariable(FunzioneBase value) {
|
||||
variable = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String simbolo();
|
||||
|
||||
@Override
|
||||
public abstract Termine calcola() throws Errore;
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable.setSmall(small);
|
||||
variable.calcolaGrafica();
|
||||
|
||||
width = getStringWidth(simbolo()) + 1 + getVariable().getWidth();
|
||||
height = variable.getHeight();
|
||||
line = variable.getLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
float h1 = getVariable().getHeight();
|
||||
int wsegno = getStringWidth(simbolo());
|
||||
float hsegno = Utils.getFontHeight(small);
|
||||
float maxh = getHeight();
|
||||
if (small) {
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
} else {
|
||||
Display.Render.setFont(PIDisplay.fonts[0]);
|
||||
}
|
||||
|
||||
glDrawStringLeft(x, (int) Math.floor(y + (maxh - hsegno) / 2), simbolo());
|
||||
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 calcola().toString();
|
||||
} catch (Errore e) {
|
||||
return e.id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunzioneAnterioreBase clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
}
|
29
src/org/warp/picalculator/FunzioneBase.java
Normal file
29
src/org/warp/picalculator/FunzioneBase.java
Normal file
@ -0,0 +1,29 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
public abstract class FunzioneBase implements Funzione {
|
||||
|
||||
@Override
|
||||
public abstract String simbolo();
|
||||
|
||||
@Override
|
||||
public abstract Termine calcola() throws Errore;
|
||||
|
||||
@Override
|
||||
public abstract void calcolaGrafica();
|
||||
|
||||
@Override
|
||||
public abstract void draw(int x, int y);
|
||||
|
||||
@Override
|
||||
public abstract int getWidth();
|
||||
|
||||
@Override
|
||||
public abstract int getHeight();
|
||||
|
||||
@Override
|
||||
public abstract int getLine();
|
||||
|
||||
@Override
|
||||
public abstract void setSmall(boolean small);
|
||||
|
||||
}
|
142
src/org/warp/picalculator/FunzioneDueValori.java
Normal file
142
src/org/warp/picalculator/FunzioneDueValori.java
Normal file
@ -0,0 +1,142 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.getStringWidth;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
|
||||
import org.nevec.rjm.Rational;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Display;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
public abstract class FunzioneDueValori implements Funzione {
|
||||
public FunzioneDueValori(Funzione value1, Funzione value2) {
|
||||
setVariable1(value1);
|
||||
setVariable2(value2);
|
||||
}
|
||||
|
||||
protected Funzione variable1 = new Termine(Rational.ZERO);
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int line;
|
||||
protected boolean small;
|
||||
|
||||
public Funzione getVariable1() {
|
||||
return variable1;
|
||||
}
|
||||
|
||||
public void setVariable1(Funzione value) {
|
||||
variable1 = value;
|
||||
}
|
||||
|
||||
protected Funzione variable2 = new Termine(Rational.ZERO);
|
||||
|
||||
public Funzione getVariable2() {
|
||||
return variable2;
|
||||
}
|
||||
|
||||
public void setVariable2(Funzione value) {
|
||||
variable2 = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String simbolo();
|
||||
|
||||
@Override
|
||||
public abstract Funzione calcola() throws Errore;
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable1.setSmall(small);
|
||||
variable1.calcolaGrafica();
|
||||
|
||||
variable2.setSmall(small);
|
||||
variable2.calcolaGrafica();
|
||||
|
||||
width = calcWidth();
|
||||
height = calcHeight();
|
||||
line = calcLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
int ln = getLine();
|
||||
int dx = 0;
|
||||
variable1.draw(dx + x, ln - variable1.getLine() + y);
|
||||
dx += 1+variable1.getWidth();
|
||||
if (drawSignum()) {
|
||||
if (small) {
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
} else {
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
}
|
||||
glDrawStringLeft(dx + x, ln - Utils.getFontHeight(small) / 2 + y, simbolo());
|
||||
dx += getStringWidth(simbolo());
|
||||
}
|
||||
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() {
|
||||
try {
|
||||
return calcola().toString();
|
||||
} catch (Errore e) {
|
||||
return e.id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunzioneDueValori clone() {
|
||||
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() ? getStringWidth(simbolo()) : 0) + variable2.getWidth();
|
||||
}
|
||||
|
||||
protected int calcHeight() {
|
||||
|
||||
Funzione tmin = variable1;
|
||||
Funzione 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() {
|
||||
Funzione tl = variable1;
|
||||
if (tl == null || variable2.getLine() >= tl.getLine()) {
|
||||
tl = variable2;
|
||||
}
|
||||
return tl.getLine();
|
||||
}
|
||||
}
|
142
src/org/warp/picalculator/FunzioneDueValoriBase.java
Normal file
142
src/org/warp/picalculator/FunzioneDueValoriBase.java
Normal file
@ -0,0 +1,142 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.getStringWidth;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
|
||||
import org.nevec.rjm.Rational;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Display;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
public abstract class FunzioneDueValoriBase extends FunzioneBase {
|
||||
public FunzioneDueValoriBase(FunzioneBase value1, FunzioneBase value2) {
|
||||
setVariable1(value1);
|
||||
setVariable2(value2);
|
||||
}
|
||||
|
||||
protected FunzioneBase variable1 = new Termine(Rational.ZERO);
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int line;
|
||||
protected boolean small;
|
||||
|
||||
public FunzioneBase getVariable1() {
|
||||
return variable1;
|
||||
}
|
||||
|
||||
public void setVariable1(FunzioneBase value) {
|
||||
variable1 = value;
|
||||
}
|
||||
|
||||
protected FunzioneBase variable2 = new Termine(Rational.ZERO);
|
||||
|
||||
public FunzioneBase getVariable2() {
|
||||
return variable2;
|
||||
}
|
||||
|
||||
public void setVariable2(FunzioneBase value) {
|
||||
variable2 = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String simbolo();
|
||||
|
||||
@Override
|
||||
public abstract Termine calcola() throws Errore;
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable1.setSmall(small);
|
||||
variable1.calcolaGrafica();
|
||||
|
||||
variable2.setSmall(small);
|
||||
variable2.calcolaGrafica();
|
||||
|
||||
width = calcWidth();
|
||||
height = calcHeight();
|
||||
line = calcLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
int ln = getLine();
|
||||
int dx = 0;
|
||||
variable1.draw(dx + x, ln - variable1.getLine() + y);
|
||||
dx += 1+variable1.getWidth();
|
||||
if (drawSignum()) {
|
||||
if (small) {
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
} else {
|
||||
Display.Render.setFont(PIDisplay.fonts[0]);
|
||||
}
|
||||
glDrawStringLeft(dx + x, ln - Utils.getFontHeight(small) / 2 + y, simbolo());
|
||||
dx += getStringWidth(simbolo());
|
||||
}
|
||||
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() {
|
||||
try {
|
||||
return calcola().toString();
|
||||
} catch (Errore e) {
|
||||
return e.id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunzioneDueValoriBase clone() {
|
||||
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() ? getStringWidth(simbolo()) : 0) + variable2.getWidth();
|
||||
}
|
||||
|
||||
protected int calcHeight() {
|
||||
|
||||
FunzioneBase tmin = variable1;
|
||||
FunzioneBase 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() {
|
||||
FunzioneBase tl = variable1;
|
||||
if (tl == null || variable2.getLine() >= tl.getLine()) {
|
||||
tl = variable2;
|
||||
}
|
||||
return tl.getLine();
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -7,18 +7,27 @@ import com.rits.cloning.Cloner;
|
||||
|
||||
public abstract class FunzioneMultipla implements Funzione {
|
||||
public FunzioneMultipla() {
|
||||
setVariables(new Funzione[]{});
|
||||
setVariables(new Funzione[] {});
|
||||
}
|
||||
|
||||
public FunzioneMultipla(Funzione[] values) {
|
||||
setVariables(values);
|
||||
}
|
||||
|
||||
protected Funzione[] variables;
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int line;
|
||||
protected boolean small;
|
||||
|
||||
public Funzione[] getVariables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
public void setVariables(Funzione[] value) {
|
||||
variables = value;
|
||||
}
|
||||
|
||||
public void setVariables(final List<Funzione> value) {
|
||||
int vsize = value.size();
|
||||
Funzione[] tmp = new Funzione[vsize];
|
||||
@ -27,32 +36,37 @@ public abstract class FunzioneMultipla implements Funzione {
|
||||
}
|
||||
variables = tmp;
|
||||
}
|
||||
|
||||
|
||||
public Funzione getVariable(int index) {
|
||||
return variables[index];
|
||||
}
|
||||
|
||||
public void setVariable(int index, Funzione value) {
|
||||
variables[index] = value;
|
||||
}
|
||||
|
||||
|
||||
public void addVariableToEnd(Funzione value) {
|
||||
int index = variables.length;
|
||||
setVariablesLength(index+1);
|
||||
setVariablesLength(index + 1);
|
||||
variables[index] = value;
|
||||
}
|
||||
|
||||
public int getVariablesLength() {
|
||||
return variables.length;
|
||||
}
|
||||
|
||||
|
||||
public void setVariablesLength(int length) {
|
||||
variables = Arrays.copyOf(variables, length);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract String simbolo();
|
||||
|
||||
@Override
|
||||
public abstract Termine calcola() throws Errore;
|
||||
public abstract Funzione calcola() throws Errore;
|
||||
|
||||
@Override
|
||||
public abstract void calcolaGrafica();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -68,4 +82,9 @@ public abstract class FunzioneMultipla implements Funzione {
|
||||
Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
}
|
90
src/org/warp/picalculator/FunzioneMultiplaBase.java
Normal file
90
src/org/warp/picalculator/FunzioneMultiplaBase.java
Normal file
@ -0,0 +1,90 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
public abstract class FunzioneMultiplaBase extends FunzioneBase {
|
||||
public FunzioneMultiplaBase() {
|
||||
setVariables(new FunzioneBase[] {});
|
||||
}
|
||||
|
||||
public FunzioneMultiplaBase(FunzioneBase[] values) {
|
||||
setVariables(values);
|
||||
}
|
||||
|
||||
protected FunzioneBase[] variables;
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int line;
|
||||
protected boolean small;
|
||||
|
||||
public FunzioneBase[] getVariables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
public void setVariables(FunzioneBase[] value) {
|
||||
variables = value;
|
||||
}
|
||||
|
||||
public void setVariables(final List<FunzioneBase> value) {
|
||||
int vsize = value.size();
|
||||
FunzioneBase[] tmp = new FunzioneBase[vsize];
|
||||
for (int i = 0; i < vsize; i++) {
|
||||
tmp[i] = value.get(i);
|
||||
}
|
||||
variables = tmp;
|
||||
}
|
||||
|
||||
public FunzioneBase getVariable(int index) {
|
||||
return variables[index];
|
||||
}
|
||||
|
||||
public void setVariable(int index, FunzioneBase value) {
|
||||
variables[index] = value;
|
||||
}
|
||||
|
||||
public void addVariableToEnd(FunzioneBase value) {
|
||||
int index = variables.length;
|
||||
setVariablesLength(index + 1);
|
||||
variables[index] = value;
|
||||
}
|
||||
|
||||
public int getVariablesLength() {
|
||||
return variables.length;
|
||||
}
|
||||
|
||||
public void setVariablesLength(int length) {
|
||||
variables = Arrays.copyOf(variables, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String simbolo();
|
||||
|
||||
@Override
|
||||
public abstract Termine calcola() throws Errore;
|
||||
|
||||
@Override
|
||||
public abstract void calcolaGrafica();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return calcola().toString();
|
||||
} catch (Errore e) {
|
||||
return e.id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunzioneMultiplaBase clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
|
||||
import java.math.BigInteger;
|
||||
package org.warp.picalculator;
|
||||
|
||||
import org.nevec.rjm.Rational;
|
||||
|
||||
public class Incognita {
|
||||
public char simbolo = 'X';
|
||||
public Rational esponente = Rational.ONE;
|
||||
|
||||
|
||||
public Incognita(char simbolo, Rational esponente) {
|
||||
this.simbolo = simbolo;
|
||||
this.esponente = esponente;
|
||||
@ -17,7 +15,7 @@ public class Incognita {
|
||||
this.simbolo = simbolo;
|
||||
this.esponente = new Rational(a, b);
|
||||
}
|
||||
|
||||
|
||||
public Incognita(char simbolo) {
|
||||
this.simbolo = simbolo;
|
||||
this.esponente = new Rational(1, 1);
|
||||
@ -34,9 +32,9 @@ public class Incognita {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Character.getNumericValue(simbolo)*3+esponente.hashCode();
|
||||
return Character.getNumericValue(simbolo) * 3 + esponente.hashCode();
|
||||
}
|
||||
}
|
@ -1,22 +1,20 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.text.Collator;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.nevec.rjm.BigIntegerMath;
|
||||
import org.nevec.rjm.Rational;
|
||||
|
||||
public class Incognite {
|
||||
|
||||
|
||||
Vector<Incognita> incognite;
|
||||
|
||||
public Incognite() {
|
||||
incognite = new Vector<Incognita>();
|
||||
}
|
||||
|
||||
|
||||
public Incognite(Incognita[] value) {
|
||||
this();
|
||||
for (Incognita i : value) {
|
||||
@ -28,16 +26,16 @@ public class Incognite {
|
||||
this();
|
||||
incognite = value;
|
||||
}
|
||||
|
||||
|
||||
public Incognite(Incognita value) {
|
||||
this();
|
||||
incognite.add(value);
|
||||
}
|
||||
|
||||
|
||||
public int count() {
|
||||
return incognite.size();
|
||||
}
|
||||
|
||||
|
||||
public boolean contieneSimbolo(char simbolo) {
|
||||
for (Incognita i : incognite) {
|
||||
if (i.simbolo == simbolo) {
|
||||
@ -55,7 +53,7 @@ public class Incognite {
|
||||
}
|
||||
return new Rational(0, 1);
|
||||
}
|
||||
|
||||
|
||||
public void impostaEsponenteSimbolo(char simbolo, Rational esponente) {
|
||||
for (Incognita i : incognite) {
|
||||
if (i.simbolo == simbolo) {
|
||||
@ -63,7 +61,7 @@ public class Incognite {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Incognite clone() {
|
||||
@ -72,19 +70,21 @@ public class Incognite {
|
||||
|
||||
public Incognite multiply(Incognite val) {
|
||||
Incognite result = new Incognite();
|
||||
//Passaggio 1: test vari
|
||||
//Se il primo gruppo di incognite è nullo allora ritorna il secondo gruppo
|
||||
// Passaggio 1: test vari
|
||||
// Se il primo gruppo di incognite à nullo allora ritorna il secondo
|
||||
// gruppo
|
||||
if (this.count() == 0) {
|
||||
result = val.clone();
|
||||
return result;
|
||||
}
|
||||
//Se il secondo gruppo di incognite è nullo allora ritorna il primo gruppo
|
||||
// Se il secondo gruppo di incognite à nullo allora ritorna il primo
|
||||
// gruppo
|
||||
if (val.count() == 0) {
|
||||
result = this.clone();
|
||||
return result;
|
||||
}
|
||||
|
||||
//Passaggio 2: le incognite doppie vengono raggruppate.
|
||||
|
||||
// Passaggio 2: le incognite doppie vengono raggruppate.
|
||||
for (Incognita i1 : incognite) {
|
||||
for (Incognita i2 : val.incognite) {
|
||||
if (i1.simbolo == i2.simbolo) {
|
||||
@ -95,7 +95,7 @@ public class Incognite {
|
||||
}
|
||||
}
|
||||
}
|
||||
//Passaggio 3: le incognite non ancora presenti vengono aggiunte.
|
||||
// Passaggio 3: le incognite non ancora presenti vengono aggiunte.
|
||||
for (Incognita i : incognite) {
|
||||
if (!result.contieneSimbolo(i.simbolo)) {
|
||||
result.incognite.add(i);
|
||||
@ -111,8 +111,8 @@ public class Incognite {
|
||||
|
||||
public Incognite divide(Incognite val) {
|
||||
Incognite result = new Incognite();
|
||||
|
||||
//Passaggio 2: le incognite doppie vengono raggruppate.
|
||||
|
||||
// Passaggio 2: le incognite doppie vengono raggruppate.
|
||||
for (Incognita i1 : incognite) {
|
||||
for (Incognita i2 : val.incognite) {
|
||||
if (i1.simbolo == i2.simbolo) {
|
||||
@ -123,7 +123,7 @@ public class Incognite {
|
||||
}
|
||||
}
|
||||
}
|
||||
//Passaggio 3: le incognite non ancora presenti vengono aggiunte.
|
||||
// Passaggio 3: le incognite non ancora presenti vengono aggiunte.
|
||||
for (Incognita i : incognite) {
|
||||
if (!result.contieneSimbolo(i.simbolo)) {
|
||||
result.incognite.add(i);
|
||||
@ -150,7 +150,7 @@ public class Incognite {
|
||||
}
|
||||
return result.normalize();
|
||||
}
|
||||
|
||||
|
||||
public Incognite normalize() {
|
||||
Incognite result = new Incognite();
|
||||
for (Incognita i1 : incognite) {
|
||||
@ -159,42 +159,45 @@ public class Incognite {
|
||||
}
|
||||
}
|
||||
result.incognite.sort(new Comparator<Incognita>() {
|
||||
@Override
|
||||
public int compare(Incognita o1, Incognita o2) {
|
||||
int index1 = letterIndex(o1.simbolo);
|
||||
int index2 = letterIndex(o2.simbolo);
|
||||
return index1-index2;
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public int compare(Incognita o1, Incognita o2) {
|
||||
int index1 = letterIndex(o1.simbolo);
|
||||
int index2 = letterIndex(o2.simbolo);
|
||||
return index1 - index2;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte letterIndex(char l) {
|
||||
return letterIndex(l, false);
|
||||
}
|
||||
|
||||
public static byte letterIndex(char l, boolean reverse) {
|
||||
int total = Simboli.incognite().length-1;
|
||||
int total = Simboli.incognite().length - 1;
|
||||
for (byte x = 0; x < Simboli.incognite().length; x++) {
|
||||
if (Simboli.incognite()[x].equals(""+l)) {
|
||||
if (Simboli.incognite()[x].equals("" + l)) {
|
||||
if (reverse) {
|
||||
return (byte) (total-x);
|
||||
return (byte) (total - x);
|
||||
} else {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public boolean compareTo(Incognite val) {
|
||||
if (this.equals(val)) return true;
|
||||
if (this.equals(val))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object val) {
|
||||
if (val == null) return false;
|
||||
if (val == null)
|
||||
return false;
|
||||
if (val instanceof Incognite) {
|
||||
Incognite ii2 = (Incognite) val;
|
||||
for (Incognita i1 : incognite) {
|
||||
@ -227,14 +230,14 @@ public class Incognite {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String result = "";
|
||||
if (incognite.size() != 1) {
|
||||
for (Incognita i : incognite) {
|
||||
if (i.esponente.compareTo(Rational.ONE) != 0) {
|
||||
result += "("+i.simbolo+"^"+i.esponente+")";
|
||||
result += "(" + i.simbolo + "^" + i.esponente + ")";
|
||||
} else {
|
||||
result += i.simbolo;
|
||||
}
|
||||
@ -242,7 +245,7 @@ public class Incognite {
|
||||
} else if (incognite.size() == 1) {
|
||||
Incognita i = incognite.get(0);
|
||||
if (i.esponente.compareTo(Rational.ONE) != 0) {
|
||||
result += ""+i.simbolo+"^"+i.esponente+"";
|
||||
result += "" + i.simbolo + "^" + i.esponente + "";
|
||||
} else if (i.esponente.compareTo(Rational.ONE) == 0) {
|
||||
result += i.simbolo;
|
||||
}
|
||||
@ -252,19 +255,21 @@ public class Incognite {
|
||||
|
||||
public static Incognite lcm(Incognite val1, Incognite val2) {
|
||||
Incognite result = new Incognite();
|
||||
//Passaggio 1: test vari
|
||||
//Se il primo gruppo di incognite è nullo allora ritorna il secondo gruppo
|
||||
// Passaggio 1: test vari
|
||||
// Se il primo gruppo di incognite à nullo allora ritorna il secondo
|
||||
// gruppo
|
||||
if (val1.count() == 0) {
|
||||
result = val2.clone();
|
||||
return result;
|
||||
}
|
||||
//Se il secondo gruppo di incognite è nullo allora ritorna il primo gruppo
|
||||
// Se il secondo gruppo di incognite à nullo allora ritorna il primo
|
||||
// gruppo
|
||||
if (val2.count() == 0) {
|
||||
result = val1.clone();
|
||||
return result;
|
||||
}
|
||||
|
||||
//Passaggio 2: le incognite doppie vengono raggruppate.
|
||||
|
||||
// Passaggio 2: le incognite doppie vengono raggruppate.
|
||||
for (Incognita i1 : val1.incognite) {
|
||||
for (Incognita i2 : val2.incognite) {
|
||||
if (i1.simbolo == i2.simbolo) {
|
||||
@ -280,7 +285,7 @@ public class Incognite {
|
||||
}
|
||||
}
|
||||
}
|
||||
//Passaggio 3: le incognite non ancora presenti vengono aggiunte.
|
||||
// Passaggio 3: le incognite non ancora presenti vengono aggiunte.
|
||||
for (Incognita i : val1.incognite) {
|
||||
if (!result.contieneSimbolo(i.simbolo)) {
|
||||
result.incognite.add(i);
|
||||
@ -314,7 +319,6 @@ public class Incognite {
|
||||
}
|
||||
}
|
||||
incognitex = newincognitex;
|
||||
|
||||
|
||||
for (Incognita i : incognitey.incognite) {
|
||||
if (i.esponente.signum() < 0) {
|
||||
@ -329,12 +333,11 @@ public class Incognite {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: SPOSTARE LE Y NEGATIVE SOTTO LA FRAZIONE, DALLA Y ALLA Z
|
||||
|
||||
// TODO: SPOSTARE LE Y NEGATIVE SOTTO LA FRAZIONE, DALLA Y ALLA Z
|
||||
|
||||
Incognite incogniteyresult = new Incognite();
|
||||
Incognite incognitezresult = new Incognite();
|
||||
//Le incognite doppie vengono tolte
|
||||
// Le incognite doppie vengono tolte
|
||||
for (Incognita i1 : incognitey.incognite) {
|
||||
for (Incognita i2 : incognitez.incognite) {
|
||||
if (i1.simbolo == i2.simbolo) {
|
||||
@ -347,7 +350,7 @@ public class Incognite {
|
||||
}
|
||||
}
|
||||
|
||||
//Le altre incognite vengono ri-messe
|
||||
// Le altre incognite vengono ri-messe
|
||||
for (Incognita i : incognitey.incognite) {
|
||||
if (!incogniteyresult.contieneSimbolo(i.simbolo)) {
|
||||
incogniteyresult = incogniteyresult.multiply(new Incognite(i));
|
||||
@ -358,31 +361,31 @@ public class Incognite {
|
||||
incognitezresult = incognitezresult.multiply(new Incognite(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
incognitey = incogniteyresult;
|
||||
incognitez = incognitezresult;
|
||||
|
||||
return new Incognite[]{incognitex, incognitey, incognitez};
|
||||
|
||||
return new Incognite[] { incognitex, incognitey, incognitez };
|
||||
}
|
||||
|
||||
public static int priorità(Incognite ii) {
|
||||
double priorità = 0;
|
||||
public static int priorità(Incognite ii) {
|
||||
double priorità = 0;
|
||||
double letterMax = 0;
|
||||
for(Incognita i : ii.incognite) {
|
||||
for (Incognita i : ii.incognite) {
|
||||
int lettIndex = letterIndex(i.simbolo, true);
|
||||
if (lettIndex > letterMax) {
|
||||
letterMax = lettIndex;
|
||||
}
|
||||
}
|
||||
priorità+=letterMax*100000;
|
||||
|
||||
for(Incognita i : ii.incognite) {
|
||||
priorità += letterMax * 100000;
|
||||
|
||||
for (Incognita i : ii.incognite) {
|
||||
int lettIndex = letterIndex(i.simbolo, true);
|
||||
if (letterMax == lettIndex) {
|
||||
priorità+=i.esponente.doubleValue()*100000;
|
||||
priorità += i.esponente.doubleValue() * 100000;
|
||||
}
|
||||
priorità+=+i.esponente.doubleValue();
|
||||
priorità += +i.esponente.doubleValue();
|
||||
}
|
||||
return (int) priorità;
|
||||
return (int) priorità;
|
||||
}
|
||||
}
|
61
src/org/warp/picalculator/Main.java
Normal file
61
src/org/warp/picalculator/Main.java
Normal file
@ -0,0 +1,61 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import org.warp.device.Keyboard;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.picalculator.screens.EquationScreen;
|
||||
|
||||
import com.pi4j.wiringpi.Gpio;
|
||||
|
||||
public class Main {
|
||||
public static int[] screenPos = new int[] { 55, 0 };
|
||||
public static final int[] screenSize = new int[] { 480, 320 };
|
||||
public static final int screenScale = 1;
|
||||
public static PIDisplay d;
|
||||
public static Main instance;
|
||||
|
||||
public Main() throws InterruptedException {
|
||||
instance = this;
|
||||
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
|
||||
beforeStart();
|
||||
d = new PIDisplay(new EquationScreen());
|
||||
d.run("Calculator");
|
||||
Utils.debug.println("Shutdown...");
|
||||
beforeShutdown();
|
||||
Utils.debug.println("");
|
||||
Utils.debug.println("Closed");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public void beforeStart() {
|
||||
if (System.getProperty("os.name").equals("Linux")) {
|
||||
Gpio.wiringPiSetupPhys();
|
||||
Gpio.pinMode(12, Gpio.PWM_OUTPUT);
|
||||
} else {
|
||||
screenPos = new int[]{0,0};
|
||||
Utils.debugOn = true;
|
||||
}
|
||||
PIDisplay.setBrightness(0.5f);
|
||||
}
|
||||
|
||||
|
||||
public void afterStart() {
|
||||
Keyboard.startKeyboard();
|
||||
}
|
||||
|
||||
public void beforeShutdown() {
|
||||
Keyboard.stopKeyboard();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
try {
|
||||
Termine t = new Termine("9999.9");
|
||||
Termine r = t.calcola();
|
||||
System.out.println(t.toString());
|
||||
System.out.println(r.toString());
|
||||
} catch (Errore e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
new Main();
|
||||
}
|
||||
}
|
@ -1,13 +1,10 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.nevec.rjm.NumeroAvanzatoVec;
|
||||
public class Moltiplicazione extends FunzioneDueValoriBase {
|
||||
|
||||
public class Moltiplicazione extends FunzioneDueValori {
|
||||
|
||||
public Moltiplicazione(Funzione value1, Funzione value2) {
|
||||
public Moltiplicazione(FunzioneBase value1, FunzioneBase value2) {
|
||||
super(value1, value2);
|
||||
}
|
||||
|
||||
@ -20,11 +17,11 @@ public class Moltiplicazione extends FunzioneDueValori {
|
||||
public Termine calcola() throws Errore {
|
||||
return getVariable1().calcola().multiply(getVariable2().calcola());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean drawSignum() {
|
||||
Funzione[] tmpVar = new Funzione[]{variable1, variable2};
|
||||
boolean[] ok = new boolean[]{false, false};
|
||||
Funzione[] tmpVar = new Funzione[] { variable1, variable2 };
|
||||
boolean[] ok = new boolean[] { false, false };
|
||||
for (int val = 0; val < 2; val++) {
|
||||
while (!ok[val]) {
|
||||
if (tmpVar[val] instanceof Divisione) {
|
||||
@ -39,9 +36,9 @@ public class Moltiplicazione extends FunzioneDueValori {
|
||||
if (!(tmpVar[0] instanceof Termine)) {
|
||||
ok[val] = true;
|
||||
} else {
|
||||
if (((Termine)tmpVar[0]).term.isBigInteger(false)) {
|
||||
if (((Termine)tmpVar[val]).term.toBigInteger(true).compareTo(new BigInteger("1")) == 0) {
|
||||
if (((Termine)tmpVar[val]).term.toNumeroAvanzato().getIncognitey().count() > 0) {
|
||||
if (((Termine) tmpVar[val]).term.isBigInteger(false)) { // TODO: prima era tmpVar[0], ma crashava. RICONTROLLARE! La logica potrebbe essere sbagliata
|
||||
if (((Termine) tmpVar[val]).term.toBigInteger(true).compareTo(new BigInteger("1")) == 0) {
|
||||
if (((Termine) tmpVar[val]).term.toNumeroAvanzato().getIncognitey().count() > 0) {
|
||||
ok[val] = true;
|
||||
} else {
|
||||
break;
|
||||
@ -55,26 +52,26 @@ public class Moltiplicazione extends FunzioneDueValori {
|
||||
}
|
||||
}
|
||||
} else if (tmpVar[val] instanceof Potenza) {
|
||||
tmpVar[val] = ((Potenza)tmpVar[val]).variable1;
|
||||
tmpVar[val] = ((Potenza) tmpVar[val]).variable1;
|
||||
} else if (tmpVar[val] instanceof Radice) {
|
||||
ok[val] = true;
|
||||
} else if (tmpVar[val] instanceof RadiceQuadrata) {
|
||||
ok[val] = true;
|
||||
} else if (tmpVar[val] instanceof Parentesi) {
|
||||
} else if (tmpVar[val] instanceof Espressione) {
|
||||
ok[0] = true;
|
||||
ok[1] = true;
|
||||
} else if (tmpVar[val] instanceof FunzioneDueValori) {
|
||||
} else if (tmpVar[val] instanceof FunzioneDueValoriBase) {
|
||||
if (val == 0) {
|
||||
tmpVar[val] = ((FunzioneDueValori)tmpVar[val]).variable2;
|
||||
tmpVar[val] = ((FunzioneDueValoriBase) tmpVar[val]).variable2;
|
||||
} else {
|
||||
tmpVar[val] = ((FunzioneDueValori)tmpVar[val]).variable1;
|
||||
tmpVar[val] = ((FunzioneDueValoriBase) tmpVar[val]).variable1;
|
||||
}
|
||||
} else if (tmpVar[val] instanceof FunzioneAnteriore) {
|
||||
tmpVar[val] = ((FunzioneAnteriore)tmpVar[val]).variable;
|
||||
} else if (tmpVar[val] instanceof FunzioneAnterioreBase) {
|
||||
tmpVar[val] = ((FunzioneAnterioreBase) tmpVar[val]).variable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ok[0] == true && ok[1] == true) {
|
||||
return false;
|
||||
} else {
|
23
src/org/warp/picalculator/MoltiplicazionePrioritaria.java
Normal file
23
src/org/warp/picalculator/MoltiplicazionePrioritaria.java
Normal file
@ -0,0 +1,23 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
public class MoltiplicazionePrioritaria extends FunzioneDueValoriBase {
|
||||
|
||||
public MoltiplicazionePrioritaria(FunzioneBase value1, FunzioneBase value2) {
|
||||
super(value1, value2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return Simboli.PRIORITARY_MULTIPLICATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Termine calcola() throws Errore {
|
||||
return getVariable1().calcola().multiply(getVariable2().calcola());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawSignum() {
|
||||
return false;
|
||||
}
|
||||
}
|
64
src/org/warp/picalculator/ParteSistema.java
Normal file
64
src/org/warp/picalculator/ParteSistema.java
Normal file
@ -0,0 +1,64 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.glColor3f;
|
||||
import static org.warp.engine.Display.Render.glDrawLine;
|
||||
|
||||
public class ParteSistema extends FunzioneAnteriore {
|
||||
|
||||
public ParteSistema(Equazione equazione) {
|
||||
super(equazione);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return Simboli.SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Equazione calcola() throws NumberFormatException, Errore {
|
||||
// TODO implementare il calcolo dei sistemi
|
||||
return (Equazione) variable.calcola();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable.setSmall(false);
|
||||
variable.calcolaGrafica();
|
||||
|
||||
width = 5 + getVariable().getWidth();
|
||||
height = 3 + getVariable().getHeight() + 2;
|
||||
line = 3 + getVariable().getLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
final int h = this.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);
|
||||
glColor3f(0, 0, 0);
|
||||
glDrawLine(x + 2, y + 0, x + 3, y + 0);
|
||||
glDrawLine(x + 1, y + 1, x + 1, y + spazioSotto / 2);
|
||||
glDrawLine(x + 2, y + spazioSotto / 2 + 1, x + 2, y + spazioSotto - 1);
|
||||
glDrawLine(x + 0, y + spazioSotto, x + 1, y + spazioSotto);
|
||||
glDrawLine(x + 2, y + spazioSotto + 1, x + 2, y + spazioSotto + spazioSopra / 2 - 1);
|
||||
glDrawLine(x + 1, y + spazioSotto + spazioSopra / 2, x + 1, y + h - 1);
|
||||
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;
|
||||
}
|
||||
}
|
58
src/org/warp/picalculator/Potenza.java
Normal file
58
src/org/warp/picalculator/Potenza.java
Normal file
@ -0,0 +1,58 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
public class Potenza extends FunzioneDueValoriBase {
|
||||
|
||||
public Potenza(FunzioneBase value1, FunzioneBase value2) {
|
||||
super(value1, value2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return Simboli.POTENZA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable1.setSmall(small);
|
||||
variable1.calcolaGrafica();
|
||||
|
||||
variable2.setSmall(true);
|
||||
variable2.calcolaGrafica();
|
||||
|
||||
height = variable1.getHeight() + variable2.getHeight() - 4;
|
||||
line = variable2.getHeight() - 4 + variable1.getLine();
|
||||
width = getVariable1().getWidth() + getVariable2().getWidth()+1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Termine calcola() throws NumberFormatException, Errore {
|
||||
return getVariable1().calcola().pow(getVariable2().calcola());
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
74
src/org/warp/picalculator/Radice.java
Normal file
74
src/org/warp/picalculator/Radice.java
Normal file
@ -0,0 +1,74 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.glDrawLine;
|
||||
|
||||
import org.nevec.rjm.NumeroAvanzatoVec;
|
||||
|
||||
public class Radice extends FunzioneDueValoriBase {
|
||||
|
||||
public Radice(FunzioneBase value1, FunzioneBase value2) {
|
||||
super(value1, value2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return Simboli.NTH_ROOT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable1.setSmall(true);
|
||||
variable1.calcolaGrafica();
|
||||
|
||||
variable2.setSmall(small);
|
||||
variable2.calcolaGrafica();
|
||||
|
||||
width = 1 + variable1.getWidth() + 2 + variable2.getWidth() + 2;
|
||||
height = variable1.getHeight() + variable2.getHeight() - 2;
|
||||
line = variable1.getHeight() + variable2.getLine() - 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Termine calcola() throws NumberFormatException, Errore {
|
||||
Termine exponent = new Termine(NumeroAvanzatoVec.ONE);
|
||||
exponent = exponent.divide(getVariable1().calcola());
|
||||
return getVariable2().calcola().pow(exponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
// glColor3f(0, 255, 0);
|
||||
// glFillRect(x,y,width,height);
|
||||
// glColor3f(0, 0, 0);
|
||||
|
||||
int w1 = getVariable2().getWidth();
|
||||
int h1 = getVariable2().getHeight();
|
||||
int w2 = getVariable1().getWidth();
|
||||
int h2 = getVariable1().getHeight();
|
||||
int height = getHeight();
|
||||
int hh = (int) Math.ceil((double) h1 / 2);
|
||||
|
||||
getVariable1().draw(x + 1, y);
|
||||
getVariable2().draw(x + 1 + w2 + 2, y + h2 - 2);
|
||||
|
||||
glDrawLine(x + 1 + w2 - 2, y + height - 3, x + 1 + w2, y + height);
|
||||
glDrawLine(x + 1 + w2, y + height - 1 - hh, x + 1 + w2, y + height - 1);
|
||||
glDrawLine(x + 1 + w2 + 1, y + height - 2 - h1, x + 1 + w2 + 1, y + height - 1 - hh - 1);
|
||||
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;
|
||||
}
|
||||
}
|
64
src/org/warp/picalculator/RadiceQuadrata.java
Normal file
64
src/org/warp/picalculator/RadiceQuadrata.java
Normal file
@ -0,0 +1,64 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import org.nevec.rjm.Rational;
|
||||
|
||||
public class RadiceQuadrata extends FunzioneAnterioreBase {
|
||||
|
||||
public RadiceQuadrata(FunzioneBase value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return Simboli.SQUARE_ROOT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable.setSmall(small);
|
||||
variable.calcolaGrafica();
|
||||
|
||||
height = getVariable().getHeight() + 2;
|
||||
width = 1 + 4 + getVariable().getWidth() + 1;
|
||||
line = getVariable().getLine() + 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Termine calcola() throws Errore {
|
||||
try {
|
||||
Termine result = getVariable().calcola();
|
||||
result = result.pow(new Termine(new Rational(1, 2)));
|
||||
return result;
|
||||
} catch(NullPointerException ex) {
|
||||
throw new Errore(Errori.ERROR);
|
||||
} catch(NumberFormatException ex) {
|
||||
throw new Errore(Errori.SYNTAX_ERROR);
|
||||
} catch(ArithmeticException ex) {
|
||||
throw new Errore(Errori.NUMBER_TOO_SMALL);
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
|
||||
public class RisultatoEquazione {
|
||||
public boolean isAnEquation = false;
|
||||
public Termine LR = new Termine("0");
|
||||
|
||||
public RisultatoEquazione(Termine LR, boolean isAnEquation) {
|
||||
this.LR = LR;
|
||||
this.isAnEquation = isAnEquation;
|
||||
}
|
||||
}
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class RisultatoEquazione {
|
||||
public boolean isAnEquation = false;
|
||||
public Termine LR = new Termine(new BigInteger("0"));
|
||||
|
||||
public RisultatoEquazione(Termine LR, boolean isAnEquation) {
|
||||
this.LR = LR;
|
||||
this.isAnEquation = isAnEquation;
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warpgate.pi.calculator.Utils.concat;
|
||||
import static org.warp.picalculator.Utils.concat;
|
||||
|
||||
public class Simboli {
|
||||
public static final String SUM = "+";
|
||||
public static final String SUBTRACTION = "-";
|
||||
public static final String MULTIPLICATION = "*";
|
||||
public static final String PRIORITARY_MULTIPLICATION = "▪";
|
||||
public static final String DIVISION = "/";
|
||||
public static final String NTH_ROOT = "√";
|
||||
public static final String SQUARE_ROOT = "Ⓐ";
|
||||
@ -14,30 +15,39 @@ public class Simboli {
|
||||
public static final String POTENZA = "Ⓑ";
|
||||
public static final String EQUATION = "=";
|
||||
public static final String SYSTEM = "{";
|
||||
|
||||
|
||||
public static final String[] funzioni() {
|
||||
return concat(funzioniNSN(), funzioniSN());
|
||||
}
|
||||
|
||||
public static final String[] funzioniNSN() {
|
||||
return new String[]{NTH_ROOT, POTENZA};
|
||||
return new String[] { NTH_ROOT, POTENZA };
|
||||
}
|
||||
|
||||
public static final String[] funzioniSN() {
|
||||
return new String[]{SQUARE_ROOT};
|
||||
return new String[] { SQUARE_ROOT };
|
||||
}
|
||||
public static final String[] segni(boolean withMultiplication) {
|
||||
String[] ret = new String[]{SUM, DIVISION};
|
||||
|
||||
public static final String[] segni(boolean withMultiplication, boolean withPrioritaryMultiplication) {
|
||||
String[] ret = new String[] { SUM, DIVISION };
|
||||
if (withMultiplication) {
|
||||
ret = Utils.add(ret, MULTIPLICATION);
|
||||
}
|
||||
if (withPrioritaryMultiplication) {
|
||||
ret = Utils.add(ret, PRIORITARY_MULTIPLICATION);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static final String[] parentesi() {
|
||||
return new String[]{PARENTHESIS_OPEN, PARENTHESIS_CLOSE};
|
||||
return new String[] { PARENTHESIS_OPEN, PARENTHESIS_CLOSE };
|
||||
}
|
||||
|
||||
public static String[] incognite() {
|
||||
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", "X", "Y", "Z"};
|
||||
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", "X", "Y", "Z" };
|
||||
}
|
||||
|
||||
public static String[] sintassiGenerale() {
|
||||
return new String[]{SYSTEM, EQUATION};
|
||||
return new String[] { SYSTEM, EQUATION };
|
||||
}
|
||||
}
|
92
src/org/warp/picalculator/Sistema.java
Normal file
92
src/org/warp/picalculator/Sistema.java
Normal file
@ -0,0 +1,92 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.glDrawLine;
|
||||
|
||||
public class Sistema extends FunzioneMultipla {
|
||||
static final int spacing = 2;
|
||||
|
||||
public Sistema() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Sistema(Funzione value) {
|
||||
super(new Funzione[]{value});
|
||||
}
|
||||
|
||||
public Sistema(Funzione[] value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Funzione calcola() throws NumberFormatException, Errore {
|
||||
// TODO implementare il calcolo dei sistemi
|
||||
return variables[0].calcola();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
for (Funzione f : variables) {
|
||||
f.setSmall(false);
|
||||
f.calcolaGrafica();
|
||||
}
|
||||
|
||||
width = 0;
|
||||
for (Funzione f : variables) {
|
||||
if (f.getWidth() > width) {
|
||||
width = f.getWidth();
|
||||
}
|
||||
}
|
||||
width += 5;
|
||||
|
||||
height = 3;
|
||||
for (Funzione f : variables) {
|
||||
height += f.getHeight()+spacing;
|
||||
}
|
||||
height = height - spacing + 2;
|
||||
|
||||
line = height/2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
|
||||
final int h = this.getHeight() - 1;
|
||||
final int paddingTop = 3;
|
||||
final int spazioSotto = (h - 3 - 2) / 2 + paddingTop;
|
||||
final int spazioSopra = h - spazioSotto;
|
||||
int dy = paddingTop;
|
||||
for (Funzione f : variables) {
|
||||
f.draw(x + 5, y + dy);
|
||||
dy+=f.getHeight()+spacing;
|
||||
}
|
||||
|
||||
|
||||
glDrawLine(x + 2, y + 0, x + 3, y + 0);
|
||||
glDrawLine(x + 1, y + 1, x + 1, y + spazioSotto / 2);
|
||||
glDrawLine(x + 2, y + spazioSotto / 2 + 1, x + 2, y + spazioSotto - 1);
|
||||
glDrawLine(x + 0, y + spazioSotto, x + 1, y + spazioSotto);
|
||||
glDrawLine(x + 2, y + spazioSotto + 1, x + 2, y + spazioSotto + spazioSopra / 2 - 1);
|
||||
glDrawLine(x + 1, y + spazioSotto + spazioSopra / 2, x + 1, y + h - 1);
|
||||
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;
|
||||
}
|
||||
}
|
75
src/org/warp/picalculator/Somma.java
Normal file
75
src/org/warp/picalculator/Somma.java
Normal file
@ -0,0 +1,75 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.getStringWidth;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Display;
|
||||
|
||||
public class Somma extends FunzioneDueValoriBase {
|
||||
|
||||
public Somma(FunzioneBase value1, FunzioneBase value2) {
|
||||
super(value1, value2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return Simboli.SUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Termine calcola() throws Errore {
|
||||
Termine val1 = getVariable1().calcola();
|
||||
Termine val2 = getVariable2().calcola();
|
||||
Termine result = val1.add(val2);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
variable1.setSmall(small);
|
||||
variable1.calcolaGrafica();
|
||||
|
||||
variable2.setSmall(small);
|
||||
variable2.calcolaGrafica();
|
||||
|
||||
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);
|
||||
|
||||
int ln = getLine();
|
||||
int dx = 0;
|
||||
variable1.draw(dx + x, ln - variable1.getLine() + y);
|
||||
dx += variable1.getWidth();
|
||||
if (small) {
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
} else {
|
||||
Display.Render.setFont(PIDisplay.fonts[0]);
|
||||
}
|
||||
dx += 1;
|
||||
glDrawStringLeft(dx + x, ln - Utils.getFontHeight(small) / 2 + y, simbolo());
|
||||
dx += getStringWidth(simbolo());
|
||||
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 += getStringWidth(simbolo());
|
||||
return dx += variable2.getWidth();
|
||||
}
|
||||
}
|
@ -1,11 +1,8 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
public class Sottrazione extends FunzioneDueValoriBase {
|
||||
|
||||
public class Sottrazione extends FunzioneDueValori {
|
||||
|
||||
public Sottrazione(Funzione value1, Funzione value2) {
|
||||
public Sottrazione(FunzioneBase value1, FunzioneBase value2) {
|
||||
super(value1, value2);
|
||||
}
|
||||
|
9
src/org/warp/picalculator/Tecnica.java
Normal file
9
src/org/warp/picalculator/Tecnica.java
Normal file
@ -0,0 +1,9 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface Tecnica {
|
||||
public static final Tecnica[] tecniche = new Tecnica[] {};
|
||||
|
||||
public abstract ArrayList<Equazione> risolvi(Equazione equazione);
|
||||
}
|
@ -1,28 +1,36 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.getStringWidth;
|
||||
import static org.warp.engine.Display.Render.glColor3f;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
import static org.warp.engine.Display.Render.glFillRect;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.nevec.rjm.BigDecimalMath;
|
||||
import org.nevec.rjm.NumeroAvanzato;
|
||||
import org.nevec.rjm.NumeroAvanzatoVec;
|
||||
import org.nevec.rjm.Rational;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Display;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
public class Termine implements Funzione {
|
||||
public class Termine extends FunzioneBase {
|
||||
|
||||
protected NumeroAvanzatoVec term = NumeroAvanzatoVec.ZERO;
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int line;
|
||||
protected boolean small;
|
||||
|
||||
public Termine(NumeroAvanzatoVec val) {
|
||||
term = val;
|
||||
}
|
||||
|
||||
public Termine(String s) {
|
||||
public Termine(String s) throws Errore {
|
||||
term = new NumeroAvanzatoVec(new NumeroAvanzato(Utils.getRational(s), Rational.ONE));
|
||||
}
|
||||
|
||||
@ -50,6 +58,13 @@ public class Termine implements Funzione {
|
||||
term = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcolaGrafica() {
|
||||
line = calcLine(); //TODO pp
|
||||
height = calcHeight();
|
||||
width = calcWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Termine calcola() {
|
||||
return this;
|
||||
@ -82,8 +97,9 @@ public class Termine implements Funzione {
|
||||
ret = ret.multiply(new Termine(getTerm()));
|
||||
}
|
||||
} else if (getTerm().isRational(true) && f.getTerm().isRational(false) && f.getTerm().toRational(false).compareTo(Rational.HALF) == 0) {
|
||||
//Rational originalExponent = f.getTerm().toRational();
|
||||
//Rational rootExponent = new Rational(originalExponent.denom(), originalExponent.numer());
|
||||
// Rational originalExponent = f.getTerm().toRational();
|
||||
// Rational rootExponent = new Rational(originalExponent.denom(),
|
||||
// originalExponent.numer());
|
||||
Rational numberToRoot = getTerm().toRational(true);
|
||||
NumeroAvanzato na = new NumeroAvanzato(Rational.ONE, numberToRoot);
|
||||
na = na.setIncognitex(getTerm().toNumeroAvanzato().getIncognitey().multiply(getTerm().toNumeroAvanzato().getIncognitez()));
|
||||
@ -101,34 +117,37 @@ public class Termine implements Funzione {
|
||||
return getTerm().toFancyString();
|
||||
}
|
||||
|
||||
public void draw(int x, int y, Display g, boolean small, boolean drawMinus) {
|
||||
boolean beforedrawminus = this.drawMinus;
|
||||
this.drawMinus = drawMinus;
|
||||
draw(x, y, g, small);
|
||||
this.drawMinus = beforedrawminus;
|
||||
}
|
||||
|
||||
// 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, Display g, boolean small) {
|
||||
public void draw(int x, int y) {
|
||||
|
||||
if (getTerm().isBigInteger(false)) {
|
||||
if (small) {
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
} else {
|
||||
Display.Render.setFont(PIDisplay.fonts[0]);
|
||||
}
|
||||
String t = toString();
|
||||
int w1 = Utils.getPlainTextWidth(t);
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
|
||||
|
||||
if (t.startsWith("-")) {
|
||||
if (drawMinus) {
|
||||
|
||||
|
||||
} else {
|
||||
int minusw = Utils.getPlainTextWidth("-");
|
||||
int minush = Utils.getFontHeight(small);
|
||||
t = t.substring(1);
|
||||
}
|
||||
}
|
||||
Utils.writeLetter(g, t, x, y, small);
|
||||
glDrawStringLeft(x+1, y, t);
|
||||
} else if (getTerm().isRational(false)) {
|
||||
small = true;
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
Rational r = getTerm().toRational(false);
|
||||
boolean minus = false;
|
||||
int minusw = 0;
|
||||
@ -138,94 +157,98 @@ public class Termine implements Funzione {
|
||||
minus = true;
|
||||
numerator = numerator.substring(1);
|
||||
}
|
||||
int w1 = Utils.getPlainTextWidth(numerator);
|
||||
int w1 = getStringWidth(numerator);
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
int w2 = Utils.getPlainTextWidth(r.denom().toString());
|
||||
int h2 = Utils.getFontHeight(small);
|
||||
int w2 = getStringWidth(r.denom().toString());
|
||||
int maxw;
|
||||
if (w1 > w2) {
|
||||
maxw = 1+w1+1;
|
||||
maxw = 1 + w1 + 1;
|
||||
} else {
|
||||
maxw = 1+w2+1;
|
||||
maxw = 1 + w2 + 1;
|
||||
}
|
||||
if (minus) {
|
||||
if (drawMinus) {
|
||||
minusw = Utils.getPlainTextWidth("-");
|
||||
minusw = getStringWidth("-");
|
||||
minush = Utils.getFontHeight(small);
|
||||
maxw += minusw;
|
||||
Utils.writeLetter(g, "-", x, y+h1+1+1-(minush/2), small);
|
||||
glDrawStringLeft(x, y + h1 + 1 + 1 - (minush / 2), "-");
|
||||
}
|
||||
}
|
||||
Utils.writeLetter(g, numerator, (int)(x+minusw+1+((double)(maxw-w1))/2d), y, small);
|
||||
Utils.writeLetter(g, r.denom().toString(), (int)(x+minusw+1+((double)(maxw-w2))/2d), y+h1+1+1+1, small);
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(x+minusw+1, y+h1+1, maxw, 1);
|
||||
glDrawStringLeft((int) (x + minusw + 1 + (maxw - w1) / 2d), y, numerator);
|
||||
glDrawStringLeft((int) (x + minusw + 1 + (maxw - w2) / 2d), y + h1 + 1 + 1 + 1, r.denom().toString());
|
||||
glColor3f(0, 0, 0);
|
||||
glFillRect(x + minusw + 1, y + h1 + 1, maxw, 1);
|
||||
} else if (getTerm().toFancyString().contains("/")) {
|
||||
small = true;
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
String r = getTerm().toFancyString();
|
||||
String numer = r.substring(0, r.lastIndexOf("/"));
|
||||
String denom = r.substring(numer.length()+1, r.length());
|
||||
String denom = r.substring(numer.length() + 1, r.length());
|
||||
if (numer.startsWith("(") && numer.endsWith(")")) {
|
||||
numer = numer.substring(1, numer.length()-1);
|
||||
numer = numer.substring(1, numer.length() - 1);
|
||||
}
|
||||
boolean minus = false;
|
||||
if (numer.startsWith("-")) {
|
||||
minus = true;
|
||||
numer = numer.substring(1);
|
||||
}
|
||||
int w1 = Utils.getPlainTextWidth(numer.toString());
|
||||
int w1 = getStringWidth(numer.toString());
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
int w2 = Utils.getPlainTextWidth(denom.toString());
|
||||
int h2 = Utils.getFontHeight(small);
|
||||
int w2 = getStringWidth(denom.toString());
|
||||
int maxw;
|
||||
if (w1 > w2) {
|
||||
maxw = w1+2;
|
||||
maxw = w1 + 2;
|
||||
} else {
|
||||
maxw = w2+2;
|
||||
maxw = w2 + 2;
|
||||
}
|
||||
int minusw = 0;
|
||||
int minush = 0;
|
||||
if (minus) {
|
||||
if (drawMinus) {
|
||||
minusw = Utils.getPlainTextWidth("-")+1;
|
||||
minusw = getStringWidth("-") + 1;
|
||||
minush = Utils.getFontHeight(small);
|
||||
maxw += minusw;
|
||||
Utils.writeLetter(g, "-", x, y+h1+1+1-(minush/2), small);
|
||||
glDrawStringLeft(x, y + h1 + 1 + 1 - (minush / 2), "-");
|
||||
}
|
||||
}
|
||||
Utils.writeLetter(g, numer, (int)(x+minusw+1+((double)(maxw-w1))/2d), y, small);
|
||||
Utils.writeLetter(g, denom, (int)(x+minusw+1+((double)(maxw-w2))/2d), y+h1+1+1+1, small);
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(x+minusw+1, y+h1+1, maxw, 1);
|
||||
glDrawStringLeft((int) (x + minusw + 1 + (maxw - w1) / 2d), y, numer);
|
||||
glDrawStringLeft((int) (x + minusw + 1 + (maxw - w2) / 2d), y + h1 + 1 + 1 + 1, denom);
|
||||
glColor3f(0, 0, 0);
|
||||
glFillRect(x + minusw + 1, y + h1 + 1, maxw, 1);
|
||||
} else {
|
||||
if (small) {
|
||||
Display.Render.setFont(PIDisplay.fonts[1]);
|
||||
} else {
|
||||
Display.Render.setFont(PIDisplay.fonts[0]);
|
||||
}
|
||||
String r = getTerm().toFancyString();
|
||||
int w1 = Utils.getPlainTextWidth(r.toString());
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
|
||||
|
||||
if (r.startsWith("-")) {
|
||||
if (drawMinus) {
|
||||
|
||||
|
||||
} else {
|
||||
int minusw = Utils.getPlainTextWidth("-")+1;
|
||||
int minush = Utils.getFontHeight(small);
|
||||
r = r.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
Utils.writeLetter(g, r.toString(), x, y, small);
|
||||
|
||||
glDrawStringLeft(x+1, y, r.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public int getHeight(boolean small, boolean drawMinus) {
|
||||
public int getHeight(boolean drawMinus) {
|
||||
boolean beforedrawminus = this.drawMinus;
|
||||
this.drawMinus = drawMinus;
|
||||
int h = getHeight(small);
|
||||
int h = getHeight();
|
||||
this.drawMinus = beforedrawminus;
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getHeight(boolean small) {
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
private int calcHeight() {
|
||||
if (getTerm().isBigInteger(false)) {
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
return h1;
|
||||
@ -233,38 +256,33 @@ public class Termine implements Funzione {
|
||||
small = true;
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
int h2 = Utils.getFontHeight(small);
|
||||
return h1+3+h2;
|
||||
return h1 + 3 + h2;
|
||||
} else if (getTerm().toFancyString().contains("/")) {
|
||||
small = true;
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
int h2 = Utils.getFontHeight(small);
|
||||
return h1+3+h2;
|
||||
return h1 + 3 + h2;
|
||||
} else {
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
return h1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getWidth(boolean drawMinus) {
|
||||
boolean beforedrawminus = this.drawMinus;
|
||||
this.drawMinus = drawMinus;
|
||||
int w = getWidth();
|
||||
this.drawMinus = beforedrawminus;
|
||||
return w;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int calcWidth() {
|
||||
if (getTerm().isBigInteger(false)) {
|
||||
String t = toString();
|
||||
if (t.startsWith("-")) {
|
||||
if (drawMinus) {
|
||||
|
||||
|
||||
} else {
|
||||
t = t.substring(1);
|
||||
}
|
||||
}
|
||||
return Utils.getPlainTextWidth(t);
|
||||
return getStringWidth(t)+1;
|
||||
} else if (getTerm().isRational(false)) {
|
||||
Rational r = getTerm().toRational(false);
|
||||
boolean minus = false;
|
||||
@ -273,59 +291,59 @@ public class Termine implements Funzione {
|
||||
minus = true;
|
||||
numerator = numerator.substring(1);
|
||||
}
|
||||
int w1 = Utils.getPlainTextWidth(numerator);
|
||||
int w2 = Utils.getPlainTextWidth(r.denom().toString());
|
||||
int w1 = getStringWidth(numerator);
|
||||
int w2 = getStringWidth(r.denom().toString());
|
||||
int maxw;
|
||||
if (w1 > w2) {
|
||||
maxw = 1+w1+1;
|
||||
maxw = 1 + w1 + 1;
|
||||
} else {
|
||||
maxw = 1+w2+1;
|
||||
maxw = 1 + w2 + 1;
|
||||
}
|
||||
if (minus) {
|
||||
if (drawMinus) {
|
||||
maxw += Utils.getPlainTextWidth("-");
|
||||
maxw += getStringWidth("-");
|
||||
}
|
||||
}
|
||||
return maxw+2;
|
||||
return maxw + 1;
|
||||
} else if (getTerm().toFancyString().contains("/")) {
|
||||
String r = getTerm().toFancyString();
|
||||
String numer = r.substring(0, r.lastIndexOf("/"));
|
||||
String denom = r.substring(numer.length()+1, r.length());
|
||||
String denom = r.substring(numer.length() + 1, r.length());
|
||||
if (numer.startsWith("(") && numer.endsWith(")")) {
|
||||
numer = numer.substring(1, numer.length()-1);
|
||||
numer = numer.substring(1, numer.length() - 1);
|
||||
}
|
||||
boolean minus = false;
|
||||
if (numer.startsWith("-")) {
|
||||
minus = true;
|
||||
numer = numer.substring(1);
|
||||
}
|
||||
int w1 = Utils.getPlainTextWidth(numer.toString());
|
||||
int w2 = Utils.getPlainTextWidth(denom.toString());
|
||||
int w1 = getStringWidth(numer.toString());
|
||||
int w2 = getStringWidth(denom.toString());
|
||||
int maxw;
|
||||
if (w1 > w2) {
|
||||
maxw = w1+2;
|
||||
maxw = w1 + 1;
|
||||
} else {
|
||||
maxw = w2+2;
|
||||
maxw = w2 + 1;
|
||||
}
|
||||
if (minus) {
|
||||
if (drawMinus) {
|
||||
maxw += Utils.getPlainTextWidth("-");
|
||||
maxw += getStringWidth("-");
|
||||
}
|
||||
}
|
||||
return maxw+2;
|
||||
return maxw + 2;
|
||||
} else {
|
||||
String r = getTerm().toFancyString();
|
||||
if (r.startsWith("-")) {
|
||||
if (drawMinus) {
|
||||
|
||||
|
||||
} else {
|
||||
r = r.substring(1);
|
||||
}
|
||||
}
|
||||
return Utils.getPlainTextWidth(r.toString());
|
||||
return getStringWidth(r.toString())+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean soloIncognitaSemplice() {
|
||||
if (this.getTerm().isBigInteger(true)) {
|
||||
if (this.getTerm().toBigInteger(true).compareTo(BigInteger.ONE) == 0 && this.getTerm().toNumeroAvanzato().getIncognitey().count() > 0) {
|
||||
@ -336,42 +354,51 @@ public class Termine implements Funzione {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLine(boolean small) {
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
private int calcLine() {
|
||||
if (getTerm().isBigInteger(false)) {
|
||||
return Utils.getFontHeight(small)/2;
|
||||
return Utils.getFontHeight(small) / 2;
|
||||
} else if (getTerm().isRational(false)) {
|
||||
small = true;
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
return h1+1;
|
||||
return h1 + 1;
|
||||
} else if (getTerm().toFancyString().contains("/")) {
|
||||
small = true;
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
return h1+1;
|
||||
return h1 + 1;
|
||||
} else {
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
return h1/2;
|
||||
return h1 / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Termine clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public void draw(int x, int y, Graphics g) {
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return Utils.getFontHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 6*toString().length()-1;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* @Override
|
||||
* public void draw(int x, int y, Graphics g) {
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public int getHeight() {
|
||||
* return Utils.getFontHeight();
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public int getWidth() {
|
||||
* return 6*toString().length()-1;
|
||||
* }
|
||||
*/
|
||||
}
|
385
src/org/warp/picalculator/Utils.java
Normal file
385
src/org/warp/picalculator/Utils.java
Normal file
@ -0,0 +1,385 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import static org.warp.engine.Display.Render.glDrawLine;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.nevec.rjm.BigDecimalMath;
|
||||
import org.nevec.rjm.Rational;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static final int scale = 24;
|
||||
public static final int resultScale = 8;
|
||||
|
||||
public static final int scaleMode = BigDecimal.ROUND_HALF_UP;
|
||||
public static final RoundingMode scaleMode2 = RoundingMode.HALF_UP;
|
||||
|
||||
public static DebugStream debug = new DebugStream();
|
||||
|
||||
public static boolean debugOn;
|
||||
|
||||
public static final class DebugStream extends StringWriter {
|
||||
|
||||
public void println(String str) {
|
||||
if (debugOn) {
|
||||
System.err.println(str);
|
||||
}
|
||||
}
|
||||
|
||||
int before = 0;
|
||||
boolean due = false;
|
||||
|
||||
}
|
||||
|
||||
public static boolean isInArray(String ch, String[] a) {
|
||||
boolean contains = false;
|
||||
for (String c : a) {
|
||||
if (c.equals(ch)) {
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return contains;
|
||||
}
|
||||
|
||||
public static String ArrayToRegex(String[] array) {
|
||||
String regex = null;
|
||||
for (String symbol : array) {
|
||||
if (regex != null) {
|
||||
regex += "|\\" + symbol;
|
||||
} else {
|
||||
regex = "\\" + symbol;
|
||||
}
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
|
||||
public static String[] concat(String[] a, String[] b) {
|
||||
int aLen = a.length;
|
||||
int bLen = b.length;
|
||||
String[] c = new String[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) {
|
||||
int aLen = a.length;
|
||||
String[] c = new String[aLen + 1];
|
||||
System.arraycopy(a, 0, c, 0, aLen);
|
||||
c[aLen] = b;
|
||||
return c;
|
||||
}
|
||||
|
||||
public static boolean ciSonoSoloFunzioniImpostateSommeEquazioniESistemi(ArrayList<Funzione> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Somma || fl.get(i) instanceof Equazione || fl.get(i) instanceof ParteSistema || fl.get(i) instanceof Espressione)) {
|
||||
if (fl.get(i) instanceof FunzioneAnterioreBase) {
|
||||
if (((FunzioneAnterioreBase) fl.get(i)).variable == null) {
|
||||
return false;
|
||||
}
|
||||
} else if (fl.get(i) instanceof FunzioneDueValoriBase) {
|
||||
if (((FunzioneDueValoriBase) fl.get(i)).variable1 == null || ((FunzioneDueValoriBase) fl.get(i)).variable2 == null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean ciSonoSoloFunzioniImpostateSommeMoltiplicazioniEquazioniESistemi(ArrayList<Funzione> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Moltiplicazione || fl.get(i) instanceof MoltiplicazionePrioritaria || fl.get(i) instanceof Somma || fl.get(i) instanceof Equazione || fl.get(i) instanceof ParteSistema || fl.get(i) instanceof Espressione)) {
|
||||
if (fl.get(i) instanceof FunzioneAnterioreBase) {
|
||||
if (((FunzioneAnterioreBase) fl.get(i)).variable == null) {
|
||||
return false;
|
||||
}
|
||||
} else if (fl.get(i) instanceof FunzioneDueValoriBase) {
|
||||
if (((FunzioneDueValoriBase) fl.get(i)).variable1 == null || ((FunzioneDueValoriBase) fl.get(i)).variable2 == null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean ciSonoSoloFunzioniImpostateEquazioniESistemi(ArrayList<Funzione> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Equazione || fl.get(i) instanceof ParteSistema || fl.get(i) instanceof Espressione)) {
|
||||
if (fl.get(i) instanceof FunzioneAnterioreBase) {
|
||||
if (((FunzioneAnterioreBase) fl.get(i)).variable == null) {
|
||||
return false;
|
||||
}
|
||||
} else if (fl.get(i) instanceof FunzioneDueValoriBase) {
|
||||
if (((FunzioneDueValoriBase) fl.get(i)).variable1 == null || ((FunzioneDueValoriBase) fl.get(i)).variable2 == null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean ciSonoSoloFunzioniImpostateESistemi(ArrayList<Funzione> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Equazione || fl.get(i) instanceof ParteSistema || fl.get(i) instanceof Espressione)) {
|
||||
if (fl.get(i) instanceof FunzioneAnterioreBase) {
|
||||
if (((FunzioneAnterioreBase) fl.get(i)).variable == null) {
|
||||
return false;
|
||||
}
|
||||
} else if (fl.get(i) instanceof FunzioneDueValoriBase) {
|
||||
if (((FunzioneDueValoriBase) fl.get(i)).variable1 == null || ((FunzioneDueValoriBase) fl.get(i)).variable2 == null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean ciSonoFunzioniSNnonImpostate(ArrayList<FunzioneBase> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (fl.get(i) instanceof FunzioneAnterioreBase) {
|
||||
if (((FunzioneAnterioreBase) fl.get(i)).variable == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean ciSonoFunzioniNSNnonImpostate(ArrayList<FunzioneBase> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (fl.get(i) instanceof FunzioneDueValoriBase && !(fl.get(i) instanceof Somma) && !(fl.get(i) instanceof Sottrazione) && !(fl.get(i) instanceof Moltiplicazione) && !(fl.get(i) instanceof MoltiplicazionePrioritaria) && !(fl.get(i) instanceof Divisione)) {
|
||||
if (((FunzioneDueValoriBase) fl.get(i)).variable1 == null && ((FunzioneDueValoriBase) fl.get(i)).variable2 == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean ciSonoMoltiplicazioniPrioritarieNonImpostate(ArrayList<FunzioneBase> funzioniOLD) {
|
||||
for (int i = 0; i < funzioniOLD.size(); i++) {
|
||||
if (funzioniOLD.get(i) instanceof MoltiplicazionePrioritaria) {
|
||||
if (((FunzioneDueValoriBase) funzioniOLD.get(i)).variable1 == null && ((FunzioneDueValoriBase) funzioniOLD.get(i)).variable2 == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean ciSonoMoltiplicazioniNonImpostate(ArrayList<FunzioneBase> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (fl.get(i) instanceof Moltiplicazione || fl.get(i) instanceof Divisione) {
|
||||
if (((FunzioneDueValoriBase) fl.get(i)).variable1 == null && ((FunzioneDueValoriBase) fl.get(i)).variable2 == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean ciSonoSommeNonImpostate(ArrayList<FunzioneBase> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (fl.get(i) instanceof Somma) {
|
||||
if (((FunzioneDueValoriBase) fl.get(i)).variable1 == null && ((FunzioneDueValoriBase) fl.get(i)).variable2 == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean ciSonoSistemiNonImpostati(ArrayList<Funzione> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (fl.get(i) instanceof ParteSistema) {
|
||||
if (((ParteSistema) fl.get(i)).variable == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean ciSonoAltreFunzioniImpostate(ArrayList<Funzione> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (!(fl.get(i) instanceof Termine || fl.get(i) instanceof Somma || fl.get(i) instanceof Espressione || fl.get(i) instanceof FunzioneAnterioreBase || fl.get(i) instanceof Moltiplicazione || fl.get(i) instanceof MoltiplicazionePrioritaria || fl.get(i) instanceof Divisione)) {
|
||||
if (fl.get(i) instanceof FunzioneAnterioreBase) {
|
||||
if (((FunzioneAnterioreBase) fl.get(i)).variable == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (fl.get(i) instanceof FunzioneDueValoriBase) {
|
||||
if (((FunzioneDueValoriBase) fl.get(i)).variable1 == null || ((FunzioneDueValoriBase) fl.get(i)).variable2 == null) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Rational getRational(BigDecimal str) {
|
||||
try {
|
||||
return getRational(str.toString());
|
||||
} catch (Errore e) {
|
||||
//E' IMPOSSIBILE CHE VENGA THROWATO UN ERRORE
|
||||
return new Rational("0");
|
||||
}
|
||||
}
|
||||
|
||||
public static Rational getRational(String str) throws Errore {
|
||||
try {
|
||||
return new Rational(str);
|
||||
} catch (NumberFormatException ex) {
|
||||
if (new BigDecimal(str).compareTo(new BigDecimal(8000.0)) < 0 && new BigDecimal(str).compareTo(new BigDecimal(-8000.0)) > 0) {
|
||||
if (str.equals("-")) {
|
||||
str = "-1";
|
||||
}
|
||||
long bits = Double.doubleToLongBits(Double.parseDouble(str));
|
||||
|
||||
long sign = bits >>> 63;
|
||||
long exponent = ((bits >>> 52) ^ (sign << 11)) - 1023;
|
||||
long fraction = bits << 12; // bits are "reversed" but that's
|
||||
// not a problem
|
||||
|
||||
long a = 1L;
|
||||
long b = 1L;
|
||||
|
||||
for (int i = 63; i >= 12; i--) {
|
||||
a = a * 2 + ((fraction >>> i) & 1);
|
||||
b *= 2;
|
||||
}
|
||||
|
||||
if (exponent > 0)
|
||||
a *= 1 << exponent;
|
||||
else
|
||||
b *= 1 << -exponent;
|
||||
|
||||
if (sign == 1)
|
||||
a *= -1;
|
||||
|
||||
if (b == 0) {
|
||||
a = 0;
|
||||
b = 1;
|
||||
}
|
||||
|
||||
return new Rational(new BigInteger(a + ""), new BigInteger(b + ""));
|
||||
} else {
|
||||
BigDecimal original = new BigDecimal(str);
|
||||
|
||||
BigInteger numerator = original.unscaledValue();
|
||||
|
||||
BigInteger denominator = BigDecimalMath.pow(BigDecimal.TEN, new BigDecimal(original.scale())).toBigIntegerExact();
|
||||
|
||||
return new Rational(numerator, denominator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static BigDecimal rationalToIrrationalString(Rational r) {
|
||||
return BigDecimalMath.divideRound(new BigDecimal(r.numer()).setScale(Utils.scale, Utils.scaleMode), new BigDecimal(r.denom()).setScale(Utils.scale, Utils.scaleMode));
|
||||
}
|
||||
|
||||
public static boolean variabiliUguali(ArrayList<Incognita> variables, ArrayList<Incognita> variables2) {
|
||||
if (variables.size() != variables2.size()) {
|
||||
return false;
|
||||
} else {
|
||||
for (Incognita v : variables) {
|
||||
if (!variables2.contains(v)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeSquareRoot(Funzione var, int x, int y, boolean small) {
|
||||
var.setSmall(small);
|
||||
int w1 = var.getWidth();
|
||||
int h1 = var.getHeight();
|
||||
int wsegno = 5;
|
||||
int hsegno = h1 + 2;
|
||||
|
||||
var.draw(x + wsegno, y + (hsegno - h1));
|
||||
|
||||
glDrawLine(x + 1, y + hsegno - 3, x + 3, y + hsegno - 1);
|
||||
glDrawLine(x + 3, y + (hsegno - 1) / 2 + 1, x + 3, y + hsegno - 1);
|
||||
glDrawLine(x + 4, y, x + 4, y + (hsegno - 1) / 2);
|
||||
glDrawLine(x + 4, y, x + 4 + 1 + w1 + 1, y);
|
||||
}
|
||||
|
||||
public static final int getFontHeight() {
|
||||
return getFontHeight(false);
|
||||
}
|
||||
|
||||
public static final int getFontHeight(boolean small) {
|
||||
if (small) {
|
||||
return 6;
|
||||
} else {
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getFontHeight(Font font) {
|
||||
if (font.getFontName().contains("Big")) {
|
||||
return 9;
|
||||
} else {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] convertStreamToByteArray(InputStream stream, long size) throws IOException {
|
||||
|
||||
// check to ensure that file size is not larger than Integer.MAX_VALUE.
|
||||
if (size > Integer.MAX_VALUE) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[(int)size];
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
|
||||
int line = 0;
|
||||
// read bytes from stream, and store them in buffer
|
||||
while ((line = stream.read(buffer)) != -1) {
|
||||
// Writes bytes from byte array (buffer) into output stream.
|
||||
os.write(buffer, 0, line);
|
||||
}
|
||||
stream.close();
|
||||
os.flush();
|
||||
os.close();
|
||||
return os.toByteArray();
|
||||
}
|
||||
|
||||
public static int[] realBytes(byte[] bytes) {
|
||||
int len = bytes.length;
|
||||
int[] realbytes = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
realbytes[i] = Byte.toUnsignedInt(bytes[i]);
|
||||
}
|
||||
return realbytes;
|
||||
}
|
||||
}
|
35
src/org/warp/picalculator/device/chip/ParallelToSerial.java
Normal file
35
src/org/warp/picalculator/device/chip/ParallelToSerial.java
Normal file
@ -0,0 +1,35 @@
|
||||
package org.warp.picalculator.device.chip;
|
||||
|
||||
import com.pi4j.wiringpi.Gpio;
|
||||
|
||||
public class ParallelToSerial {
|
||||
|
||||
private int SH_LD;
|
||||
private int CLK_INH;
|
||||
private int QH;
|
||||
private int CLK;
|
||||
|
||||
public ParallelToSerial(int SH_LD_pin, int CLK_INH_pin, int QH_pin, int CLK_pin) {
|
||||
SH_LD = SH_LD_pin;
|
||||
CLK_INH = CLK_INH_pin;
|
||||
QH = QH_pin;
|
||||
CLK = CLK_pin;
|
||||
}
|
||||
|
||||
public boolean[] read() {
|
||||
boolean[] data = new boolean[8];
|
||||
Gpio.digitalWrite(CLK_INH, Gpio.HIGH);
|
||||
Gpio.digitalWrite(SH_LD, Gpio.LOW);
|
||||
Gpio.delay(1);
|
||||
Gpio.digitalWrite(SH_LD, Gpio.HIGH);
|
||||
Gpio.digitalWrite(CLK_INH, Gpio.LOW);
|
||||
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
Gpio.digitalWrite(CLK, Gpio.HIGH);
|
||||
Gpio.digitalWrite(CLK, Gpio.LOW);
|
||||
data[i] = Gpio.digitalRead(QH)==Gpio.HIGH?true:false;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
31
src/org/warp/picalculator/device/chip/SerialToParallel.java
Normal file
31
src/org/warp/picalculator/device/chip/SerialToParallel.java
Normal file
@ -0,0 +1,31 @@
|
||||
package org.warp.picalculator.device.chip;
|
||||
|
||||
import com.pi4j.wiringpi.Gpio;
|
||||
|
||||
public class SerialToParallel {
|
||||
private int RCK; //Storage register clock pin (latch pin)
|
||||
private int SCK; //Shift register clock pin
|
||||
private int SER; //Serial data input
|
||||
|
||||
public SerialToParallel(int RCK_pin, int SCK_pin, int SER_pin) {
|
||||
RCK = RCK_pin;
|
||||
SCK = SCK_pin;
|
||||
SER = SER_pin;
|
||||
}
|
||||
|
||||
public void write(boolean[] data) {
|
||||
if (data.length != 8) {
|
||||
return;
|
||||
} else {
|
||||
Gpio.digitalWrite(RCK, Gpio.LOW);
|
||||
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
Gpio.digitalWrite(SCK, Gpio.LOW);
|
||||
Gpio.digitalWrite(SER, data[i]);
|
||||
Gpio.digitalWrite(SCK, Gpio.HIGH);
|
||||
}
|
||||
|
||||
Gpio.digitalWrite(RCK, Gpio.HIGH);
|
||||
}
|
||||
}
|
||||
}
|
54
src/org/warp/picalculator/screens/EmptyScreen.java
Normal file
54
src/org/warp/picalculator/screens/EmptyScreen.java
Normal file
@ -0,0 +1,54 @@
|
||||
package org.warp.picalculator.screens;
|
||||
|
||||
import org.warp.device.Keyboard.Key;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Screen;
|
||||
|
||||
public class EmptyScreen extends Screen {
|
||||
|
||||
public float endLoading;
|
||||
|
||||
public EmptyScreen() {
|
||||
super();
|
||||
canBeInHistory = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
endLoading = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
endLoading += dt;
|
||||
if (PIDisplay.loading & endLoading >= 2.5) {
|
||||
PIDisplay.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mustBeRefreshed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(Key k) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyReleased(Key k) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
324
src/org/warp/picalculator/screens/EquationScreen.java
Normal file
324
src/org/warp/picalculator/screens/EquationScreen.java
Normal file
@ -0,0 +1,324 @@
|
||||
package org.warp.picalculator.screens;
|
||||
|
||||
import static org.warp.engine.Display.Render.glClearColor;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
import static org.warp.engine.Display.Render.setFont;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.warp.device.Keyboard.Key;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Display;
|
||||
import org.warp.engine.Screen;
|
||||
import org.warp.picalculator.Calculator;
|
||||
import org.warp.picalculator.Errore;
|
||||
import org.warp.picalculator.Errori;
|
||||
import org.warp.picalculator.Funzione;
|
||||
import org.warp.picalculator.Utils;
|
||||
|
||||
public class EquationScreen extends Screen {
|
||||
|
||||
public float endLoading;
|
||||
public volatile String equazioneCorrente = "";
|
||||
public volatile String nuovaEquazione = "";
|
||||
public volatile int caretPos = 0;
|
||||
public volatile boolean showCaret = true;
|
||||
public volatile float showCaretDelta = 0f;
|
||||
public Funzione f;
|
||||
public Funzione f2;
|
||||
public int ew1;
|
||||
public int ew2;
|
||||
public int eh2;
|
||||
public int x1;
|
||||
public int x2;
|
||||
public boolean requiresleep1;
|
||||
public boolean requiresleep2;
|
||||
public boolean aftersleep;
|
||||
public boolean autoscroll;
|
||||
public int errorLevel = 0; // 0 = nessuno, 1 = risultato, 2 = tutto
|
||||
public Errore err1;
|
||||
public Errore err2;
|
||||
boolean mustRefresh = true;
|
||||
|
||||
public EquationScreen() {
|
||||
super();
|
||||
canBeInHistory = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
endLoading = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws InterruptedException {
|
||||
try {
|
||||
/* 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");
|
||||
interpreta("0");
|
||||
// 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");
|
||||
|
||||
} catch (Errore e) {
|
||||
glClearColor(0xFFDC3C32);
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
|
||||
PIDisplay.error = e.id.toString();
|
||||
System.err.println(e.id);
|
||||
}
|
||||
}
|
||||
|
||||
public void interpreta(String eqn) throws Errore {
|
||||
equazioneCorrente = eqn;
|
||||
f = Calculator.interpreta(equazioneCorrente.replace("sqrt", "Ⓐ").replace("^", "Ⓑ"));
|
||||
f.calcolaGrafica();
|
||||
}
|
||||
|
||||
public void solve() throws Errore {
|
||||
Calculator.solve();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
endLoading += dt;
|
||||
if (endLoading >= 1) {
|
||||
PIDisplay.loading = false;
|
||||
}
|
||||
showCaretDelta += dt;
|
||||
if (showCaretDelta >= 0.5f) {
|
||||
mustRefresh = true;
|
||||
showCaret = !showCaret;
|
||||
showCaretDelta = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
setFont(PIDisplay.fonts[0]);
|
||||
glClearColor(0xFFCCE7D4);
|
||||
glDrawStringLeft(2, 22, nuovaEquazione.substring(0, caretPos)+(showCaret?"|":"")+nuovaEquazione.substring(((showCaret==false||nuovaEquazione.length()<=caretPos)?caretPos:caretPos+1), nuovaEquazione.length()));
|
||||
if (f != null)
|
||||
f.draw(2, 22+1+9+1);
|
||||
if (f2 != null)
|
||||
f2.draw(Display.getWidth() - 2 - f2.getWidth(), Display.getHeight() - 2 - f2.getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mustBeRefreshed() {
|
||||
if (mustRefresh) {
|
||||
mustRefresh = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(Key k) {
|
||||
switch (k) {
|
||||
case SIMPLIFY:
|
||||
if (nuovaEquazione.length() > 0) {
|
||||
Calculator.simplify();
|
||||
}
|
||||
return true;
|
||||
case SOLVE:
|
||||
if (PIDisplay.error != null) {
|
||||
Utils.debug.println("Resetting after error...");
|
||||
PIDisplay.error = null;
|
||||
return true;
|
||||
} else {
|
||||
if (nuovaEquazione != equazioneCorrente && nuovaEquazione.length() > 0) {
|
||||
try {
|
||||
try {
|
||||
interpreta(nuovaEquazione);
|
||||
solve();
|
||||
} catch (Exception ex) {
|
||||
throw new Errore(Errori.ERROR);
|
||||
}
|
||||
} catch (Errore e) {
|
||||
glClearColor(0xFFDC3C32);
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
|
||||
PIDisplay.error = e.id.toString();
|
||||
System.err.println(e.id);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case NUM0:
|
||||
typeChar("0");
|
||||
return true;
|
||||
case NUM1:
|
||||
typeChar("1");
|
||||
return true;
|
||||
case NUM2:
|
||||
typeChar("2");
|
||||
return true;
|
||||
case NUM3:
|
||||
typeChar("3");
|
||||
return true;
|
||||
case NUM4:
|
||||
typeChar("4");
|
||||
return true;
|
||||
case NUM5:
|
||||
typeChar("5");
|
||||
return true;
|
||||
case NUM6:
|
||||
typeChar("6");
|
||||
return true;
|
||||
case NUM7:
|
||||
typeChar("7");
|
||||
return true;
|
||||
case NUM8:
|
||||
typeChar("8");
|
||||
return true;
|
||||
case NUM9:
|
||||
typeChar("9");
|
||||
return true;
|
||||
case PLUS:
|
||||
typeChar("+");
|
||||
return true;
|
||||
case MINUS:
|
||||
typeChar("-");
|
||||
return true;
|
||||
case MULTIPLY:
|
||||
typeChar("*");
|
||||
return true;
|
||||
case DIVIDE:
|
||||
typeChar("/");
|
||||
return true;
|
||||
case PARENTHESIS_OPEN:
|
||||
typeChar("(");
|
||||
return true;
|
||||
case PARENTHESIS_CLOSE:
|
||||
typeChar(")");
|
||||
return true;
|
||||
case DOT:
|
||||
typeChar(".");
|
||||
return true;
|
||||
case EQUAL:
|
||||
typeChar("=");
|
||||
return true;
|
||||
case SQRT:
|
||||
typeChar("Ⓐ");
|
||||
return true;
|
||||
case ROOT:
|
||||
typeChar("√");
|
||||
return true;
|
||||
case POWER_OF_2:
|
||||
typeChar("^");
|
||||
typeChar("2");
|
||||
return true;
|
||||
case POWER_OF_x:
|
||||
typeChar("^");
|
||||
return true;
|
||||
case DELETE:
|
||||
if (nuovaEquazione.length() > 0) {
|
||||
if (caretPos > 0) {
|
||||
caretPos-=1;
|
||||
nuovaEquazione=nuovaEquazione.substring(0, caretPos)+nuovaEquazione.substring(caretPos+1, nuovaEquazione.length());
|
||||
} else {
|
||||
nuovaEquazione = nuovaEquazione.substring(1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case LEFT:
|
||||
if (caretPos > 0) {
|
||||
caretPos -= 1;
|
||||
showCaret = true;
|
||||
showCaretDelta = 0L;
|
||||
}
|
||||
return true;
|
||||
case RIGHT:
|
||||
if (caretPos < nuovaEquazione.length()) {
|
||||
caretPos += 1;
|
||||
showCaret = true;
|
||||
showCaretDelta = 0L;
|
||||
}
|
||||
return true;
|
||||
case RESET:
|
||||
if (PIDisplay.error != null) {
|
||||
Utils.debug.println("Resetting after error...");
|
||||
PIDisplay.error = null;
|
||||
return true;
|
||||
} else {
|
||||
caretPos = 0;
|
||||
nuovaEquazione="";
|
||||
return true;
|
||||
}
|
||||
case debug1:
|
||||
PIDisplay.INSTANCE.setScreen(new EmptyScreen());
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void typeChar(String chr) {
|
||||
nuovaEquazione=nuovaEquazione.substring(0, caretPos)+chr+nuovaEquazione.substring(caretPos, nuovaEquazione.length());
|
||||
caretPos+=1;
|
||||
showCaret = true;
|
||||
showCaretDelta = 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyReleased(Key k) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
87
src/org/warp/picalculator/screens/MarioScreen.java
Normal file
87
src/org/warp/picalculator/screens/MarioScreen.java
Normal file
@ -0,0 +1,87 @@
|
||||
package org.warp.picalculator.screens;
|
||||
|
||||
import static org.warp.engine.Display.Render.getMatrixOfImage;
|
||||
import static org.warp.engine.Display.Render.glClearColor;
|
||||
import static org.warp.engine.Display.Render.glDrawSkin;
|
||||
import static org.warp.engine.Display.Render.glDrawStringLeft;
|
||||
import static org.warp.engine.Display.Render.setFont;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.warp.device.Keyboard;
|
||||
import org.warp.device.Keyboard.Key;
|
||||
import org.warp.device.PIDisplay;
|
||||
import org.warp.engine.Screen;
|
||||
import org.warp.picalculator.Main;
|
||||
|
||||
public class MarioScreen extends Screen {
|
||||
|
||||
private int[] skin;
|
||||
private int[] skinSize;
|
||||
private boolean errored;
|
||||
public int posX = 0;
|
||||
|
||||
public MarioScreen() {
|
||||
super();
|
||||
canBeInHistory = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
BufferedImage img;
|
||||
try {
|
||||
img = ImageIO.read(Main.instance.getClass().getResource("/marioskin.png"));
|
||||
skin = getMatrixOfImage(img);
|
||||
skinSize = new int[] { img.getWidth(), img.getHeight() };
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
errored = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
if (!errored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
if (!errored) {
|
||||
if (Keyboard.isKeyDown(2, 5)) { //RIGHT
|
||||
posX+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
if (errored) {
|
||||
glDrawStringLeft(0, 20, "ERROR");
|
||||
} else {
|
||||
setFont(PIDisplay.fonts[0]);
|
||||
glClearColor(0xFFCCE7D4);
|
||||
glDrawSkin(skinSize[0], skin, posX, 25, 36, 1, 70, 27, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mustBeRefreshed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyReleased(Key k) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(Key k) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
74
src/org/warp/picalculator/screens/SolveEquationScreen.java
Normal file
74
src/org/warp/picalculator/screens/SolveEquationScreen.java
Normal file
@ -0,0 +1,74 @@
|
||||
package org.warp.picalculator.screens;
|
||||
|
||||
import static org.warp.engine.Display.Render.glDrawStringCenter;
|
||||
|
||||
import org.warp.device.Keyboard.Key;
|
||||
import org.warp.engine.Display;
|
||||
import org.warp.engine.Screen;
|
||||
import org.warp.picalculator.Calculator;
|
||||
import org.warp.picalculator.Errore;
|
||||
import org.warp.picalculator.Main;
|
||||
|
||||
public class SolveEquationScreen extends Screen {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private EquationScreen es;
|
||||
|
||||
public SolveEquationScreen(EquationScreen es) {
|
||||
super();
|
||||
canBeInHistory = false;
|
||||
|
||||
this.es = es;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
glDrawStringCenter(Display.getWidth()/2, 29, "ciaoooooooooooooooooooooooooooooo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mustBeRefreshed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(Key k) {
|
||||
switch (k) {
|
||||
case LETTER_X:
|
||||
Main.d.goBack();
|
||||
try {
|
||||
Calculator.solve('X');
|
||||
} catch (Errore e) {
|
||||
Screen scr = Main.d.getScreen();
|
||||
if (scr instanceof EquationScreen) {
|
||||
EquationScreen escr = (EquationScreen) scr;
|
||||
escr.errorLevel = 1;
|
||||
escr.err2 = e;
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyReleased(Key k) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -1,212 +0,0 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.awt.image.*;
|
||||
public class BMPFile extends Component {
|
||||
//--- Private constants
|
||||
private final static int BITMAPFILEHEADER_SIZE = 14;
|
||||
private final static int BITMAPINFOHEADER_SIZE = 40;
|
||||
//--- Private variable declaration
|
||||
//--- Bitmap file header
|
||||
private byte bitmapFileHeader [] = new byte [14];
|
||||
private byte bfType [] = {'B', 'M'};
|
||||
private int bfSize = 0;
|
||||
private int bfReserved1 = 0;
|
||||
private int bfReserved2 = 0;
|
||||
private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
|
||||
//--- Bitmap info header
|
||||
private byte bitmapInfoHeader [] = new byte [40];
|
||||
private int biSize = BITMAPINFOHEADER_SIZE;
|
||||
private int biWidth = 0;
|
||||
private int biHeight = 0;
|
||||
private int biPlanes = 1;
|
||||
private int biBitCount = 24;
|
||||
private int biCompression = 0;
|
||||
private int biSizeImage = 0x030000;
|
||||
private int biXPelsPerMeter = 0x0;
|
||||
private int biYPelsPerMeter = 0x0;
|
||||
private int biClrUsed = 0;
|
||||
private int biClrImportant = 0;
|
||||
//--- Bitmap raw data
|
||||
private int bitmap [];
|
||||
//--- File section
|
||||
private FileOutputStream fo;
|
||||
//--- Default constructor
|
||||
public BMPFile() {
|
||||
}
|
||||
public void saveBitmap (String parFilename, Image parImage, int
|
||||
parWidth, int parHeight) {
|
||||
try {
|
||||
fo = new FileOutputStream (parFilename);
|
||||
save (parImage, parWidth, parHeight);
|
||||
fo.close ();
|
||||
}
|
||||
catch (Exception saveEx) {
|
||||
saveEx.printStackTrace ();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The saveMethod is the main method of the process. This method
|
||||
* will call the convertImage method to convert the memory image to
|
||||
* a byte array; method writeBitmapFileHeader creates and writes
|
||||
* the bitmap file header; writeBitmapInfoHeader creates the
|
||||
* information header; and writeBitmap writes the image.
|
||||
*
|
||||
*/
|
||||
private void save (Image parImage, int parWidth, int parHeight) {
|
||||
try {
|
||||
convertImage (parImage, parWidth, parHeight);
|
||||
writeBitmapFileHeader ();
|
||||
writeBitmapInfoHeader ();
|
||||
writeBitmap ();
|
||||
}
|
||||
catch (Exception saveEx) {
|
||||
saveEx.printStackTrace ();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* convertImage converts the memory image to the bitmap format (BRG).
|
||||
* It also computes some information for the bitmap info header.
|
||||
*
|
||||
*/
|
||||
private boolean convertImage (Image parImage, int parWidth, int parHeight) {
|
||||
int pad;
|
||||
bitmap = new int [parWidth * parHeight];
|
||||
PixelGrabber pg = new PixelGrabber (parImage, 0, 0, parWidth, parHeight,
|
||||
bitmap, 0, parWidth);
|
||||
try {
|
||||
pg.grabPixels ();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace ();
|
||||
return (false);
|
||||
}
|
||||
pad = (4 - ((parWidth * 3) % 4)) * parHeight;
|
||||
biSizeImage = ((parWidth * parHeight) * 3) + pad;
|
||||
bfSize = biSizeImage + BITMAPFILEHEADER_SIZE +
|
||||
BITMAPINFOHEADER_SIZE;
|
||||
biWidth = parWidth;
|
||||
biHeight = parHeight;
|
||||
return (true);
|
||||
}
|
||||
/*
|
||||
* writeBitmap converts the image returned from the pixel grabber to
|
||||
* the format required. Remember: scan lines are inverted in
|
||||
* a bitmap file!
|
||||
*
|
||||
* Each scan line must be padded to an even 4-byte boundary.
|
||||
*/
|
||||
private void writeBitmap () {
|
||||
int size;
|
||||
int value;
|
||||
int j;
|
||||
int i;
|
||||
int rowCount;
|
||||
int rowIndex;
|
||||
int lastRowIndex;
|
||||
int pad;
|
||||
int padCount;
|
||||
byte rgb [] = new byte [3];
|
||||
size = (biWidth * biHeight) - 1;
|
||||
pad = 4 - ((biWidth * 3) % 4);
|
||||
if (pad == 4) // <==== Bug correction
|
||||
pad = 0; // <==== Bug correction
|
||||
rowCount = 1;
|
||||
padCount = 0;
|
||||
rowIndex = size - biWidth;
|
||||
lastRowIndex = rowIndex;
|
||||
try {
|
||||
for (j = 0; j < size; j++) {
|
||||
value = bitmap [rowIndex];
|
||||
rgb [0] = (byte) (value & 0xFF);
|
||||
rgb [1] = (byte) ((value >> 8) & 0xFF);
|
||||
rgb [2] = (byte) ((value >> 16) & 0xFF);
|
||||
fo.write (rgb);
|
||||
if (rowCount == biWidth) {
|
||||
padCount += pad;
|
||||
for (i = 1; i <= pad; i++) {
|
||||
fo.write (0x00);
|
||||
}
|
||||
rowCount = 1;
|
||||
rowIndex = lastRowIndex - biWidth;
|
||||
lastRowIndex = rowIndex;
|
||||
}
|
||||
else
|
||||
rowCount++;
|
||||
rowIndex++;
|
||||
}
|
||||
//--- Update the size of the file
|
||||
bfSize += padCount - pad;
|
||||
biSizeImage += padCount - pad;
|
||||
}
|
||||
catch (Exception wb) {
|
||||
wb.printStackTrace ();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* writeBitmapFileHeader writes the bitmap file header to the file.
|
||||
*
|
||||
*/
|
||||
private void writeBitmapFileHeader () {
|
||||
try {
|
||||
fo.write (bfType);
|
||||
fo.write (intToDWord (bfSize));
|
||||
fo.write (intToWord (bfReserved1));
|
||||
fo.write (intToWord (bfReserved2));
|
||||
fo.write (intToDWord (bfOffBits));
|
||||
}
|
||||
catch (Exception wbfh) {
|
||||
wbfh.printStackTrace ();
|
||||
}
|
||||
}
|
||||
/*
|
||||
*
|
||||
* writeBitmapInfoHeader writes the bitmap information header
|
||||
* to the file.
|
||||
*
|
||||
*/
|
||||
private void writeBitmapInfoHeader () {
|
||||
try {
|
||||
fo.write (intToDWord (biSize));
|
||||
fo.write (intToDWord (biWidth));
|
||||
fo.write (intToDWord (biHeight));
|
||||
fo.write (intToWord (biPlanes));
|
||||
fo.write (intToWord (biBitCount));
|
||||
fo.write (intToDWord (biCompression));
|
||||
fo.write (intToDWord (biSizeImage));
|
||||
fo.write (intToDWord (biXPelsPerMeter));
|
||||
fo.write (intToDWord (biYPelsPerMeter));
|
||||
fo.write (intToDWord (biClrUsed));
|
||||
fo.write (intToDWord (biClrImportant));
|
||||
}
|
||||
catch (Exception wbih) {
|
||||
wbih.printStackTrace ();
|
||||
}
|
||||
}
|
||||
/*
|
||||
*
|
||||
* intToWord converts an int to a word, where the return
|
||||
* value is stored in a 2-byte array.
|
||||
*
|
||||
*/
|
||||
private byte [] intToWord (int parValue) {
|
||||
byte retValue [] = new byte [2];
|
||||
retValue [0] = (byte) (parValue & 0x00FF);
|
||||
retValue [1] = (byte) ((parValue >> 8) & 0x00FF);
|
||||
return (retValue);
|
||||
}
|
||||
/*
|
||||
*
|
||||
* intToDWord converts an int to a double word, where the return
|
||||
* value is stored in a 4-byte array.
|
||||
*
|
||||
*/
|
||||
private byte [] intToDWord (int parValue) {
|
||||
byte retValue [] = new byte [4];
|
||||
retValue [0] = (byte) (parValue & 0x00FF);
|
||||
retValue [1] = (byte) ((parValue >> 8) & 0x000000FF);
|
||||
retValue [2] = (byte) ((parValue >> 16) & 0x000000FF);
|
||||
retValue [3] = (byte) ((parValue >> 24) & 0x000000FF);
|
||||
return (retValue);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
|
||||
import org.nevec.rjm.NumeroAvanzatoVec;
|
||||
import org.warp.engine.lwjgl.Screen;
|
||||
|
||||
public class Calculator {
|
||||
|
||||
public static String angleMode = "deg";
|
||||
public static Screen[] sessions = new Screen[5];
|
||||
public static int currentSession = 0;
|
||||
public static boolean haxMode = true;
|
||||
|
||||
public static Termine calcolarisultato(String string) throws Errore {
|
||||
System.out.println("INPUT: " + string);
|
||||
Parentesi espressione = new Parentesi(string);
|
||||
return espressione.calcola();
|
||||
}
|
||||
|
||||
public static RisultatoEquazione calcolaequazione(String string) throws Errore {
|
||||
if (string.split("=").length == 0) {
|
||||
return new RisultatoEquazione(new Termine("0"), true);
|
||||
}
|
||||
if (string.split("=").length <= 2) {
|
||||
if (string.split("=").length == 1) {
|
||||
string = string + "=0";
|
||||
}
|
||||
Termine res1 = calcolarisultato(string.split("=")[0]);
|
||||
Termine res2 = calcolarisultato(string.split("=")[1]);
|
||||
Termine res = res1.add(res2.multiply(new Termine("-1")));
|
||||
if (res.calcola().getTerm().toString().equals("0")) {
|
||||
return new RisultatoEquazione(res.calcola(), true);
|
||||
}
|
||||
return new RisultatoEquazione(res.calcola(), false);
|
||||
}
|
||||
return new RisultatoEquazione(null, false);
|
||||
}
|
||||
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
package org.warpgate.pi.calculator;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import org.nevec.rjm.NumeroAvanzatoVec;
|
||||
import org.nevec.rjm.Rational;
|
||||
|
||||
public class Divisione extends FunzioneDueValori {
|
||||
|
||||
public Divisione(Funzione value1, Funzione value2) {
|
||||
super(value1, value2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String simbolo() {
|
||||
return Simboli.DIVISION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Termine calcola() throws Errore {
|
||||
if (variable2 == null || variable1 == null) {
|
||||
return new Termine("0");
|
||||
}
|
||||
if (variable2.calcola().getTerm().compareTo(NumeroAvanzatoVec.ZERO) == 0) {
|
||||
throw new Errore(Errori.DIVISION_BY_ZERO);
|
||||
}
|
||||
return variable1.calcola().divide(variable2.calcola());
|
||||
}
|
||||
|
||||
public boolean hasMinus() {
|
||||
String numerator = variable1.toString();
|
||||
if (numerator.startsWith("-")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void draw(int x, int y, 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, boolean small) {
|
||||
Object var1 = variable1;
|
||||
Object var2 = variable2;
|
||||
small = true;
|
||||
boolean minus = false;
|
||||
int minusw = 0;
|
||||
int minush = 0;
|
||||
String numerator = ((Funzione)var1).toString();
|
||||
if (numerator.startsWith("-") && ((Funzione)var1) instanceof Termine && ((Termine)var1).term.isBigInteger(true)) {
|
||||
minus = true;
|
||||
numerator = numerator.substring(1);
|
||||
}
|
||||
int w1 = 0;
|
||||
int h1 = 0;
|
||||
if (minus) {
|
||||
w1 = Utils.getPlainTextWidth(numerator);
|
||||
h1 = Utils.getFontHeight(small);
|
||||
} else {
|
||||
w1 = ((Funzione)var1).getWidth();
|
||||
h1 = ((Funzione)var1).getHeight(small);
|
||||
}
|
||||
int w2 = ((Funzione)var2).getWidth();
|
||||
int maxw;
|
||||
if (w1 > w2) {
|
||||
maxw = 1+w1+1;
|
||||
} else {
|
||||
maxw = 1+w2+1;
|
||||
}
|
||||
if (minus && drawMinus) {
|
||||
minusw = Utils.getPlainTextWidth("-")+1;
|
||||
minush = Utils.getFontHeight(small);
|
||||
Utils.writeLetter(g, "-", x, y+h1+1+1-(minush/2), small);
|
||||
Utils.writeLetter(g, numerator, (int)(x+minusw+1+((double)(maxw-w1))/2d), y, small);
|
||||
} else {
|
||||
((Funzione)var1).draw((int)(x+minusw+1+((double)(maxw-w1))/2d), y, g, true);
|
||||
}
|
||||
((Funzione)var2).draw((int)(x+minusw+1+((double)(maxw-w2))/2d), y+h1+1+1+1, g, true);
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(x+minusw+1, y+h1+1, maxw, 1);
|
||||
}
|
||||
|
||||
public int getHeight(boolean small, boolean drawMinus) {
|
||||
boolean beforedrawminus = this.drawMinus;
|
||||
this.drawMinus = drawMinus;
|
||||
int h = getHeight(small);
|
||||
this.drawMinus = beforedrawminus;
|
||||
return h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(boolean small) {
|
||||
boolean minus = false;
|
||||
small = true;
|
||||
String numerator = variable1.toString();
|
||||
if (numerator.startsWith("-") && variable1 instanceof Termine && ((Termine) variable1).term.isBigInteger(true)) {
|
||||
minus = true;
|
||||
numerator = numerator.substring(1);
|
||||
}
|
||||
int w1 = 0;
|
||||
int h1 = 0;
|
||||
if (minus) {
|
||||
w1 = Utils.getPlainTextWidth(numerator);
|
||||
h1 = Utils.getFontHeight(small);
|
||||
} else {
|
||||
w1 = variable1.getWidth();
|
||||
h1 = variable1.getHeight(small);
|
||||
}
|
||||
int w2 = variable2.getWidth();
|
||||
int h2 = variable2.getHeight(small);
|
||||
int maxw;
|
||||
if (w1 > w2) {
|
||||
maxw = 1+w1+1;
|
||||
} else {
|
||||
maxw = 1+w2+1;
|
||||
}
|
||||
return h1+3+h2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLine(boolean small) {
|
||||
return variable1.getHeight(true)+1;
|
||||
}
|
||||
|
||||
public int getWidth(boolean drawMinus) {
|
||||
boolean beforedrawminus = this.drawMinus;
|
||||
this.drawMinus = drawMinus;
|
||||
int w = getWidth();
|
||||
this.drawMinus = beforedrawminus;
|
||||
return w;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
boolean minus = false;
|
||||
String numerator = variable1.toString();
|
||||
if (numerator.startsWith("-") && variable1 instanceof Termine && ((Termine) variable1).term.isBigInteger(true)) {
|
||||
minus = true;
|
||||
numerator = numerator.substring(1);
|
||||
}
|
||||
int w1 = 0;
|
||||
int h1 = 0;
|
||||
if (minus) {
|
||||
w1 = Utils.getPlainTextWidth(numerator);
|
||||
} else {
|
||||
w1 = variable1.getWidth();
|
||||
}
|
||||
int w2 = variable2.getWidth();
|
||||
int maxw;
|
||||
if (w1 > w2) {
|
||||
maxw = 1+w1+1;
|
||||
} else {
|
||||
maxw = 1+w2+1;
|
||||
}
|
||||
if (minus && drawMinus) {
|
||||
return Utils.getPlainTextWidth("-")+1+maxw+1;
|
||||
} else {
|
||||
return maxw+2;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user