Major Graphic Engine revision. Now most of the math functions are broken
due to their outdated rendering methods.
This commit is contained in:
parent
de0340b166
commit
bbdba7aeb3
@ -3,6 +3,7 @@
|
||||
<classpathentry excluding="org/warp/picalculator/deprecatedmath/" kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="src" path="res"/>
|
||||
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.USER_LIBRARY/JOGL"/>
|
||||
<classpathentry kind="lib" path="libs/pi4j-1.1/pi4j-core.jar" sourcepath="libs/pi4j-1.1/pi4j-core-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:platform:/resource/PICalculator/libs/pi4j-1.1/pi4j-core-javadoc.jar!/"/>
|
||||
@ -28,6 +29,5 @@
|
||||
<attribute name="javadoc_location" value="jar:platform:/resource/PICalculator/libs/objenesis-2.4/objenesis-2.4-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/JOGL"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
@ -1,12 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
|
||||
|
60
.settings/org.eclipse.jdt.ui.prefs
Normal file
60
.settings/org.eclipse.jdt.ui.prefs
Normal file
@ -0,0 +1,60 @@
|
||||
cleanup.add_default_serial_version_id=false
|
||||
cleanup.add_generated_serial_version_id=true
|
||||
cleanup.add_missing_annotations=true
|
||||
cleanup.add_missing_deprecated_annotations=true
|
||||
cleanup.add_missing_methods=true
|
||||
cleanup.add_missing_nls_tags=false
|
||||
cleanup.add_missing_override_annotations=true
|
||||
cleanup.add_missing_override_annotations_interface_methods=true
|
||||
cleanup.add_serial_version_id=true
|
||||
cleanup.always_use_blocks=true
|
||||
cleanup.always_use_parentheses_in_expressions=true
|
||||
cleanup.always_use_this_for_non_static_field_access=false
|
||||
cleanup.always_use_this_for_non_static_method_access=false
|
||||
cleanup.convert_functional_interfaces=true
|
||||
cleanup.convert_to_enhanced_for_loop=true
|
||||
cleanup.correct_indentation=true
|
||||
cleanup.format_source_code=true
|
||||
cleanup.format_source_code_changes_only=false
|
||||
cleanup.insert_inferred_type_arguments=false
|
||||
cleanup.make_local_variable_final=true
|
||||
cleanup.make_parameters_final=false
|
||||
cleanup.make_private_fields_final=true
|
||||
cleanup.make_type_abstract_if_missing_method=false
|
||||
cleanup.make_variable_declarations_final=true
|
||||
cleanup.never_use_blocks=false
|
||||
cleanup.never_use_parentheses_in_expressions=false
|
||||
cleanup.organize_imports=false
|
||||
cleanup.qualify_static_field_accesses_with_declaring_class=false
|
||||
cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
|
||||
cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
|
||||
cleanup.qualify_static_member_accesses_with_declaring_class=true
|
||||
cleanup.qualify_static_method_accesses_with_declaring_class=false
|
||||
cleanup.remove_private_constructors=true
|
||||
cleanup.remove_redundant_type_arguments=true
|
||||
cleanup.remove_trailing_whitespaces=false
|
||||
cleanup.remove_trailing_whitespaces_all=true
|
||||
cleanup.remove_trailing_whitespaces_ignore_empty=false
|
||||
cleanup.remove_unnecessary_casts=true
|
||||
cleanup.remove_unnecessary_nls_tags=true
|
||||
cleanup.remove_unused_imports=true
|
||||
cleanup.remove_unused_local_variables=false
|
||||
cleanup.remove_unused_private_fields=true
|
||||
cleanup.remove_unused_private_members=false
|
||||
cleanup.remove_unused_private_methods=true
|
||||
cleanup.remove_unused_private_types=true
|
||||
cleanup.sort_members=false
|
||||
cleanup.sort_members_all=false
|
||||
cleanup.use_anonymous_class_creation=false
|
||||
cleanup.use_blocks=true
|
||||
cleanup.use_blocks_only_for_return_and_throw=false
|
||||
cleanup.use_lambda=true
|
||||
cleanup.use_parentheses_in_expressions=false
|
||||
cleanup.use_this_for_non_static_field_access=true
|
||||
cleanup.use_this_for_non_static_field_access_only_if_necessary=true
|
||||
cleanup.use_this_for_non_static_method_access=true
|
||||
cleanup.use_this_for_non_static_method_access_only_if_necessary=true
|
||||
cleanup_profile=_Drake's Cleanup
|
||||
cleanup_settings_version=2
|
||||
eclipse.preferences.version=1
|
||||
formatter_settings_version=12
|
BIN
res/skin.png
BIN
res/skin.png
Binary file not shown.
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.5 KiB |
BIN
res/skin.xcf
BIN
res/skin.xcf
Binary file not shown.
BIN
res/test.png
Normal file
BIN
res/test.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
@ -64,7 +64,7 @@ public class Cloner {
|
||||
private boolean cloneSynthetics = true;
|
||||
|
||||
public Cloner() {
|
||||
this.instantiationStrategy = ObjenesisInstantiationStrategy.getInstance();
|
||||
instantiationStrategy = ObjenesisInstantiationStrategy.getInstance();
|
||||
init();
|
||||
}
|
||||
|
||||
@ -113,12 +113,12 @@ public class Cloner {
|
||||
fastCloners.put(ConcurrentHashMap.class, new FastClonerConcurrentHashMap());
|
||||
}
|
||||
|
||||
private IDeepCloner deepCloner = new IDeepCloner() {
|
||||
private final IDeepCloner deepCloner = new IDeepCloner() {
|
||||
@Override
|
||||
public <T> T deepClone(T o, Map<Object, Object> clones) {
|
||||
try {
|
||||
return cloneInternal(o, clones);
|
||||
} catch (IllegalAccessException e) {
|
||||
} catch (final IllegalAccessException e) {
|
||||
// just rethrow unchecked
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
@ -128,8 +128,9 @@ 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)
|
||||
if (fastCloner != null) {
|
||||
return fastCloner.clone(o, deepCloner, clones);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -281,8 +282,9 @@ public class Cloner {
|
||||
}
|
||||
|
||||
public void registerFastCloner(final Class<?> c, final IFastCloner fastCloner) {
|
||||
if (fastCloners.containsKey(c))
|
||||
if (fastCloners.containsKey(c)) {
|
||||
throw new IllegalArgumentException(c + " already fast-cloned!");
|
||||
}
|
||||
fastCloners.put(c, fastCloner);
|
||||
}
|
||||
|
||||
@ -307,8 +309,9 @@ public class Cloner {
|
||||
public <T> T fastCloneOrNewInstance(final Class<T> c) {
|
||||
try {
|
||||
final T fastClone = (T) fastClone(c, null);
|
||||
if (fastClone != null)
|
||||
if (fastClone != null) {
|
||||
return fastClone;
|
||||
}
|
||||
} catch (final IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -326,10 +329,12 @@ public class Cloner {
|
||||
* @return a deep-clone of "o".
|
||||
*/
|
||||
public <T> T deepClone(final T o) {
|
||||
if (o == null)
|
||||
if (o == null) {
|
||||
return null;
|
||||
if (!cloningEnabled)
|
||||
}
|
||||
if (!cloningEnabled) {
|
||||
return o;
|
||||
}
|
||||
if (dumpCloned != null) {
|
||||
dumpCloned.startCloning(o.getClass());
|
||||
}
|
||||
@ -342,10 +347,12 @@ public class Cloner {
|
||||
}
|
||||
|
||||
public <T> T deepCloneDontCloneInstances(final T o, final Object... dontCloneThese) {
|
||||
if (o == null)
|
||||
if (o == null) {
|
||||
return null;
|
||||
if (!cloningEnabled)
|
||||
}
|
||||
if (!cloningEnabled) {
|
||||
return o;
|
||||
}
|
||||
if (dumpCloned != null) {
|
||||
dumpCloned.startCloning(o.getClass());
|
||||
}
|
||||
@ -371,10 +378,12 @@ public class Cloner {
|
||||
* @return a shallow clone of "o"
|
||||
*/
|
||||
public <T> T shallowClone(final T o) {
|
||||
if (o == null)
|
||||
if (o == null) {
|
||||
return null;
|
||||
if (!cloningEnabled)
|
||||
}
|
||||
if (!cloningEnabled) {
|
||||
return o;
|
||||
}
|
||||
try {
|
||||
return cloneInternal(o, null);
|
||||
} catch (final IllegalAccessException e) {
|
||||
@ -411,10 +420,12 @@ public class Cloner {
|
||||
*/
|
||||
private boolean isImmutable(final Class<?> clz) {
|
||||
final Boolean isIm = immutables.get(clz);
|
||||
if (isIm != null)
|
||||
if (isIm != null) {
|
||||
return isIm;
|
||||
if (considerImmutable(clz))
|
||||
}
|
||||
if (considerImmutable(clz)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final Class<?> immutableAnnotation = getImmutableAnnotation();
|
||||
for (final Annotation annotation : clz.getDeclaredAnnotations()) {
|
||||
@ -442,34 +453,45 @@ public class Cloner {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T cloneInternal(final T o, final Map<Object, Object> clones) throws IllegalAccessException {
|
||||
if (o == null)
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
if (o == this)
|
||||
{
|
||||
return null; // don't clone the cloner!
|
||||
if (ignoredInstances.containsKey(o))
|
||||
}
|
||||
if (ignoredInstances.containsKey(o)) {
|
||||
return o;
|
||||
if (o instanceof Enum)
|
||||
}
|
||||
if (o instanceof Enum) {
|
||||
return o;
|
||||
}
|
||||
final Class<T> clz = (Class<T>) o.getClass();
|
||||
// skip cloning ignored classes
|
||||
if (nullInstead.contains(clz))
|
||||
if (nullInstead.contains(clz)) {
|
||||
return null;
|
||||
if (ignored.contains(clz))
|
||||
return o;
|
||||
for (final Class<?> iClz : ignoredInstanceOf) {
|
||||
if (iClz.isAssignableFrom(clz))
|
||||
return o;
|
||||
}
|
||||
if (isImmutable(clz))
|
||||
if (ignored.contains(clz)) {
|
||||
return o;
|
||||
}
|
||||
for (final Class<?> iClz : ignoredInstanceOf) {
|
||||
if (iClz.isAssignableFrom(clz)) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
if (isImmutable(clz)) {
|
||||
return o;
|
||||
}
|
||||
if (o instanceof IFreezable) {
|
||||
final IFreezable f = (IFreezable) o;
|
||||
if (f.isFrozen())
|
||||
if (f.isFrozen()) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
final Object clonedPreviously = clones != null ? clones.get(o) : null;
|
||||
if (clonedPreviously != null)
|
||||
if (clonedPreviously != null) {
|
||||
return (T) clonedPreviously;
|
||||
}
|
||||
|
||||
final Object fastClone = fastClone(o, clones);
|
||||
if (fastClone != null) {
|
||||
@ -549,15 +571,18 @@ public class Cloner {
|
||||
* fields of src
|
||||
*/
|
||||
public <T, E extends T> void copyPropertiesOfInheritedClass(final T src, final E dest) {
|
||||
if (src == null)
|
||||
if (src == null) {
|
||||
throw new IllegalArgumentException("src can't be null");
|
||||
if (dest == 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()) {
|
||||
if (!destClz.isArray())
|
||||
if (!destClz.isArray()) {
|
||||
throw new IllegalArgumentException("can't copy from array to non-array class " + destClz);
|
||||
}
|
||||
final int length = Array.getLength(src);
|
||||
for (int i = 0; i < length; i++) {
|
||||
final Object v = Array.get(src, i);
|
||||
@ -639,8 +664,9 @@ public class Cloner {
|
||||
System.out.println("cloned field>" + field + " -- of class " + clz);
|
||||
}
|
||||
};
|
||||
} else
|
||||
} else {
|
||||
dumpCloned = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCloningEnabled() {
|
||||
|
@ -14,7 +14,7 @@ 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;
|
||||
final Calendar c = (Calendar) t;
|
||||
gc.setTimeInMillis(c.getTimeInMillis());
|
||||
gc.setTimeZone((TimeZone) c.getTimeZone().clone());
|
||||
return gc;
|
||||
|
@ -43,10 +43,12 @@ public class Perspectives {
|
||||
* @return the E perspective of o
|
||||
*/
|
||||
public <T, E extends T> E viewAs(final Class<E> c, final T o) {
|
||||
if (o == null)
|
||||
if (o == null) {
|
||||
return null;
|
||||
if (o instanceof Collection<?>)
|
||||
}
|
||||
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;
|
||||
@ -81,8 +83,9 @@ public class Perspectives {
|
||||
*/
|
||||
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)
|
||||
if (currentCollection == null) {
|
||||
return null;
|
||||
}
|
||||
for (final I item : currentCollection) {
|
||||
final NI newItem = viewAs(perspectiveCollectionItemClass, item);
|
||||
newCollection.add(newItem);
|
||||
|
@ -35,11 +35,12 @@ public class Bernoulli {
|
||||
*/
|
||||
protected void set(final int n, final Rational value) {
|
||||
final int nindx = n / 2;
|
||||
if (nindx < a.size())
|
||||
if (nindx < a.size()) {
|
||||
a.set(nindx, value);
|
||||
else {
|
||||
while (a.size() < nindx)
|
||||
} else {
|
||||
while (a.size() < nindx) {
|
||||
a.add(Rational.ZERO);
|
||||
}
|
||||
a.add(value);
|
||||
}
|
||||
}
|
||||
@ -53,15 +54,16 @@ public class Bernoulli {
|
||||
* @throws Error
|
||||
*/
|
||||
public Rational at(int n) throws Error {
|
||||
if (n == 1)
|
||||
if (n == 1) {
|
||||
return (new Rational(-1, 2));
|
||||
else if (n % 2 != 0)
|
||||
} else if (n % 2 != 0) {
|
||||
return Rational.ZERO;
|
||||
else {
|
||||
} else {
|
||||
final int nindx = n / 2;
|
||||
if (a.size() <= nindx) {
|
||||
for (int i = 2 * a.size(); i <= n; i += 2)
|
||||
for (int i = 2 * a.size(); i <= n; i += 2) {
|
||||
set(i, doubleSum(i));
|
||||
}
|
||||
}
|
||||
return a.elementAt(nindx);
|
||||
}
|
||||
@ -80,11 +82,12 @@ public class Bernoulli {
|
||||
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)
|
||||
final BigInteger jpown = (new BigInteger("" + j)).pow(n);
|
||||
if (j % 2 == 0) {
|
||||
jsum = jsum.add(bin.multiply(jpown));
|
||||
else
|
||||
} else {
|
||||
jsum = jsum.subtract(bin.multiply(jpown));
|
||||
}
|
||||
|
||||
/*
|
||||
* update binomial(k,j) recursively
|
||||
|
@ -165,14 +165,16 @@ public class BigComplex {
|
||||
* and v= +- sqrt((l-re)/2 as the new real and imaginary parts.
|
||||
*/
|
||||
final BigDecimal l = abs(mc);
|
||||
if (l.compareTo(BigDecimal.ZERO) == 0)
|
||||
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)
|
||||
if (im.compareTo(BigDecimal.ZERO) >= 0) {
|
||||
return new BigComplex(u, v);
|
||||
else
|
||||
} else {
|
||||
return new BigComplex(u, v.negate());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,14 +23,17 @@ public class BigIntegerMath {
|
||||
* @return The binomial coefficient
|
||||
*/
|
||||
static public BigInteger binomial(final int n, final int k) {
|
||||
if (k == 0)
|
||||
if (k == 0) {
|
||||
return (BigInteger.ONE);
|
||||
}
|
||||
BigInteger bin = new BigInteger("" + n);
|
||||
BigInteger n2 = bin;
|
||||
for (BigInteger i = new BigInteger("" + (k - 1)); i.compareTo(BigInteger.ONE) >= 0; i = i.subtract(BigInteger.ONE))
|
||||
final BigInteger n2 = bin;
|
||||
for (BigInteger i = new BigInteger("" + (k - 1)); i.compareTo(BigInteger.ONE) >= 0; i = i.subtract(BigInteger.ONE)) {
|
||||
bin = bin.multiply(n2.subtract(i));
|
||||
for (BigInteger i = new BigInteger("" + k); i.compareTo(BigInteger.ONE) == 1; i = i.subtract(BigInteger.ONE))
|
||||
}
|
||||
for (BigInteger i = new BigInteger("" + k); i.compareTo(BigInteger.ONE) == 1; i = i.subtract(BigInteger.ONE)) {
|
||||
bin = bin.divide(i);
|
||||
}
|
||||
return (bin);
|
||||
} /* binomial */
|
||||
|
||||
@ -48,8 +51,9 @@ public class BigIntegerMath {
|
||||
/*
|
||||
* binomial(n,0) =1
|
||||
*/
|
||||
if (k.compareTo(BigInteger.ZERO) == 0)
|
||||
if (k.compareTo(BigInteger.ZERO) == 0) {
|
||||
return (BigInteger.ONE);
|
||||
}
|
||||
|
||||
BigInteger bin = new BigInteger("" + n);
|
||||
|
||||
@ -78,8 +82,9 @@ public class BigIntegerMath {
|
||||
* and in the integer domain. First replace C(n,k) by C(n,n-k) if n-k<k.
|
||||
*/
|
||||
BigInteger truek = new BigInteger(k.toString());
|
||||
if (n.subtract(k).compareTo(k) < 0)
|
||||
if (n.subtract(k).compareTo(k) < 0) {
|
||||
truek = n.subtract(k);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate C(num,truek) where num=n and truek is the smaller of n-k
|
||||
@ -168,8 +173,9 @@ public class BigIntegerMath {
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public int isqrt(final int n) {
|
||||
if (n < 0)
|
||||
if (n < 0) {
|
||||
throw new ArithmeticException("Negative argument " + n);
|
||||
}
|
||||
final double resul = Math.sqrt(n);
|
||||
return (int) Math.round(resul);
|
||||
}
|
||||
@ -185,8 +191,9 @@ public class BigIntegerMath {
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public long isqrt(final long n) {
|
||||
if (n < 0)
|
||||
if (n < 0) {
|
||||
throw new ArithmeticException("Negative argument " + n);
|
||||
}
|
||||
final double resul = Math.sqrt(n);
|
||||
return Math.round(resul);
|
||||
}
|
||||
@ -202,16 +209,17 @@ public class BigIntegerMath {
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger isqrt(final BigInteger n) {
|
||||
if (n.compareTo(BigInteger.ZERO) < 0)
|
||||
if (n.compareTo(BigInteger.ZERO) < 0) {
|
||||
throw new ArithmeticException("Negative argument " + n.toString());
|
||||
}
|
||||
/*
|
||||
* Start with an estimate from a floating point reduction.
|
||||
*/
|
||||
BigInteger x;
|
||||
final int bl = n.bitLength();
|
||||
if (bl > 120)
|
||||
if (bl > 120) {
|
||||
x = n.shiftRight(bl / 2 - 1);
|
||||
else {
|
||||
} else {
|
||||
final double resul = Math.sqrt(n.doubleValue());
|
||||
x = new BigInteger("" + Math.round(resul));
|
||||
}
|
||||
@ -221,13 +229,15 @@ public class BigIntegerMath {
|
||||
/*
|
||||
* check whether the result is accurate, x^2 =n
|
||||
*/
|
||||
BigInteger x2 = x.pow(2);
|
||||
final BigInteger x2 = x.pow(2);
|
||||
BigInteger xplus2 = x.add(BigInteger.ONE).pow(2);
|
||||
if (x2.compareTo(n) <= 0 && xplus2.compareTo(n) > 0)
|
||||
if (x2.compareTo(n) <= 0 && xplus2.compareTo(n) > 0) {
|
||||
return x;
|
||||
}
|
||||
xplus2 = xplus2.subtract(x.shiftLeft(2));
|
||||
if (xplus2.compareTo(n) <= 0 && x2.compareTo(n) > 0)
|
||||
if (xplus2.compareTo(n) <= 0 && x2.compareTo(n) > 0) {
|
||||
return x.subtract(BigInteger.ONE);
|
||||
}
|
||||
/*
|
||||
* Newton algorithm. This correction is on the
|
||||
* low side caused by the integer divisions. So the value required
|
||||
@ -251,8 +261,9 @@ public class BigIntegerMath {
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger core(final BigInteger n) {
|
||||
if (n.compareTo(BigInteger.ZERO) < 0)
|
||||
if (n.compareTo(BigInteger.ZERO) < 0) {
|
||||
throw new ArithmeticException("Negative argument " + n);
|
||||
}
|
||||
final Ifactor i = new Ifactor(n);
|
||||
return i.core();
|
||||
}
|
||||
@ -278,17 +289,21 @@ public class BigIntegerMath {
|
||||
static public BigInteger[][] minor(final BigInteger[][] A, final int r, final int c) throws ArithmeticException {
|
||||
/* original row count */
|
||||
final int rL = A.length;
|
||||
if (rL == 0)
|
||||
if (rL == 0) {
|
||||
throw new ArithmeticException("zero row count in matrix");
|
||||
if (r < 0 || r >= rL)
|
||||
}
|
||||
if (r < 0 || r >= rL) {
|
||||
throw new ArithmeticException("row number " + r + " out of range 0.." + (rL - 1));
|
||||
}
|
||||
/* original column count */
|
||||
final int cL = A[0].length;
|
||||
if (cL == 0)
|
||||
if (cL == 0) {
|
||||
throw new ArithmeticException("zero column count in matrix");
|
||||
if (c < 0 || c >= cL)
|
||||
}
|
||||
if (c < 0 || c >= cL) {
|
||||
throw new ArithmeticException("column number " + c + " out of range 0.." + (cL - 1));
|
||||
BigInteger M[][] = new BigInteger[rL - 1][cL - 1];
|
||||
}
|
||||
final BigInteger M[][] = new BigInteger[rL - 1][cL - 1];
|
||||
int imrow = 0;
|
||||
for (int row = 0; row < rL; row++) {
|
||||
if (row != r) {
|
||||
@ -327,15 +342,18 @@ public class BigIntegerMath {
|
||||
throws ArithmeticException {
|
||||
/* original row count */
|
||||
final int rL = A.length;
|
||||
if (rL == 0)
|
||||
if (rL == 0) {
|
||||
throw new ArithmeticException("zero row count in matrix");
|
||||
}
|
||||
/* original column count */
|
||||
final int cL = A[0].length;
|
||||
if (cL == 0)
|
||||
if (cL == 0) {
|
||||
throw new ArithmeticException("zero column count in matrix");
|
||||
if (c < 0 || c >= cL)
|
||||
}
|
||||
if (c < 0 || c >= cL) {
|
||||
throw new ArithmeticException("column number " + c + " out of range 0.." + (cL - 1));
|
||||
BigInteger M[][] = new BigInteger[rL][cL];
|
||||
}
|
||||
final BigInteger M[][] = new BigInteger[rL][cL];
|
||||
for (int row = 0; row < rL; row++) {
|
||||
for (int col = 0; col < cL; col++) {
|
||||
/*
|
||||
@ -343,10 +361,11 @@ public class BigIntegerMath {
|
||||
* surplus
|
||||
* elements will be ignored. Shorter v lead to an exception.
|
||||
*/
|
||||
if (col != c)
|
||||
if (col != c) {
|
||||
M[row][col] = A[row][col];
|
||||
else
|
||||
} else {
|
||||
M[row][col] = v[row];
|
||||
}
|
||||
}
|
||||
}
|
||||
return M;
|
||||
@ -367,20 +386,21 @@ public class BigIntegerMath {
|
||||
BigInteger d = BigInteger.ZERO;
|
||||
/* row size */
|
||||
final int rL = A.length;
|
||||
if (rL == 0)
|
||||
if (rL == 0) {
|
||||
throw new ArithmeticException("zero row count in matrix");
|
||||
}
|
||||
/* column size */
|
||||
final int cL = A[0].length;
|
||||
if (cL != rL)
|
||||
if (cL != rL) {
|
||||
throw new ArithmeticException("Non-square matrix dim " + rL + " by " + cL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the low-order cases directly.
|
||||
*/
|
||||
if (rL == 1)
|
||||
if (rL == 1) {
|
||||
return A[0][0];
|
||||
|
||||
else if (rL == 2) {
|
||||
} else if (rL == 2) {
|
||||
d = A[0][0].multiply(A[1][1]);
|
||||
return d.subtract(A[0][1].multiply(A[1][0]));
|
||||
} else {
|
||||
@ -393,10 +413,11 @@ public class BigIntegerMath {
|
||||
final BigInteger M[][] = minor(A, r, 0);
|
||||
final BigInteger m = A[r][0].multiply(det(M));
|
||||
/* recursive call */
|
||||
if (r % 2 == 0)
|
||||
if (r % 2 == 0) {
|
||||
d = d.add(m);
|
||||
else
|
||||
} else {
|
||||
d = d.subtract(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -421,26 +442,30 @@ public class BigIntegerMath {
|
||||
static public Rational[] solve(final BigInteger[][] A, final BigInteger[] rhs) throws ArithmeticException, Error {
|
||||
|
||||
final int rL = A.length;
|
||||
if (rL == 0)
|
||||
if (rL == 0) {
|
||||
throw new ArithmeticException("zero row count in matrix");
|
||||
}
|
||||
|
||||
/* column size */
|
||||
final int cL = A[0].length;
|
||||
if (cL != rL)
|
||||
if (cL != rL) {
|
||||
throw new ArithmeticException("Non-square matrix dim " + rL + " by " + cL);
|
||||
if (rhs.length != rL)
|
||||
}
|
||||
if (rhs.length != rL) {
|
||||
throw new ArithmeticException("Right hand side dim " + rhs.length + " unequal matrix dim " + rL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gauss elimination
|
||||
*/
|
||||
Rational x[] = new Rational[rL];
|
||||
final Rational x[] = new Rational[rL];
|
||||
|
||||
/*
|
||||
* copy of r.h.s ito a mutable Rationalright hand side
|
||||
*/
|
||||
for (int c = 0; c < cL; c++)
|
||||
for (int c = 0; c < cL; c++) {
|
||||
x[c] = new Rational(rhs[c]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create zeros downwards column c by linear combination of row c and
|
||||
@ -456,11 +481,11 @@ public class BigIntegerMath {
|
||||
for (int r = c + 1; r < rL; r++) {
|
||||
if (A[r][c].compareTo(BigInteger.ZERO) != 0) {
|
||||
for (int cpr = c; cpr < cL; cpr++) {
|
||||
BigInteger tmp = A[c][cpr];
|
||||
final BigInteger tmp = A[c][cpr];
|
||||
A[c][cpr] = A[r][cpr];
|
||||
A[r][cpr] = tmp;
|
||||
}
|
||||
Rational tmp = x[c];
|
||||
final Rational tmp = x[c];
|
||||
x[c] = x[r];
|
||||
x[r] = tmp;
|
||||
swpd = true;
|
||||
@ -471,8 +496,9 @@ public class BigIntegerMath {
|
||||
* not swapped with a non-zero row: determinant zero and no
|
||||
* solution
|
||||
*/
|
||||
if (!swpd)
|
||||
if (!swpd) {
|
||||
throw new ArithmeticException("Zero determinant of main matrix");
|
||||
}
|
||||
}
|
||||
/* create zero at A[c+1..cL-1][c] */
|
||||
for (int r = c + 1; r < rL; r++) {
|
||||
@ -481,20 +507,22 @@ public class BigIntegerMath {
|
||||
* not visited again
|
||||
*/
|
||||
for (int cpr = c + 1; cpr < cL; cpr++) {
|
||||
BigInteger tmp = A[c][c].multiply(A[r][cpr]).subtract(A[c][cpr].multiply(A[r][c]));
|
||||
final BigInteger tmp = A[c][c].multiply(A[r][cpr]).subtract(A[c][cpr].multiply(A[r][c]));
|
||||
A[r][cpr] = tmp;
|
||||
}
|
||||
Rational tmp = x[r].multiply(A[c][c]).subtract(x[c].multiply(A[r][c]));
|
||||
final Rational tmp = x[r].multiply(A[c][c]).subtract(x[c].multiply(A[r][c]));
|
||||
x[r] = tmp;
|
||||
}
|
||||
}
|
||||
if (A[cL - 1][cL - 1].compareTo(BigInteger.ZERO) == 0)
|
||||
if (A[cL - 1][cL - 1].compareTo(BigInteger.ZERO) == 0) {
|
||||
throw new ArithmeticException("Zero determinant of main matrix");
|
||||
}
|
||||
/* backward elimination */
|
||||
for (int r = cL - 1; r >= 0; r--) {
|
||||
x[r] = x[r].divide(A[r][r]);
|
||||
for (int rpr = r - 1; rpr >= 0; rpr--)
|
||||
for (int rpr = r - 1; rpr >= 0; rpr--) {
|
||||
x[rpr] = x[rpr].subtract(x[r].multiply(A[rpr][r]));
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
@ -512,7 +540,7 @@ public class BigIntegerMath {
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger lcm(final BigInteger a, final BigInteger b) {
|
||||
BigInteger g = a.gcd(b);
|
||||
final BigInteger g = a.gcd(b);
|
||||
return a.multiply(b).abs().divide(g);
|
||||
}
|
||||
|
||||
@ -529,11 +557,13 @@ public class BigIntegerMath {
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger valueOf(final Vector<BigInteger> c, final BigInteger x) {
|
||||
if (c.size() == 0)
|
||||
if (c.size() == 0) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
BigInteger res = c.lastElement();
|
||||
for (int i = c.size() - 2; i >= 0; i--)
|
||||
for (int i = c.size() - 2; i >= 0; i--) {
|
||||
res = res.multiply(x).add(c.elementAt(i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -552,32 +582,34 @@ public class BigIntegerMath {
|
||||
* et al, Num. Funct. Anal. Opt. 10 (5)( 1989) 419-488</a>
|
||||
*/
|
||||
static public Rational centrlFactNumt(int n, int k) throws Error {
|
||||
if (k > n || k < 0 || (k % 2) != (n % 2))
|
||||
if (k > n || k < 0 || (k % 2) != (n % 2)) {
|
||||
return Rational.ZERO;
|
||||
else if (k == n)
|
||||
} else if (k == n) {
|
||||
return Rational.ONE;
|
||||
else {
|
||||
} else {
|
||||
/* Proposition 6.2.6 */
|
||||
Factorial f = new Factorial();
|
||||
final Factorial f = new Factorial();
|
||||
Rational jsum = new Rational(0, 1);
|
||||
int kprime = n - k;
|
||||
final int kprime = n - k;
|
||||
for (int j = 0; j <= kprime; j++) {
|
||||
Rational nusum = new Rational(0, 1);
|
||||
for (int nu = 0; nu <= j; nu++) {
|
||||
Rational t = new Rational(j - 2 * nu, 2);
|
||||
t = t.pow(kprime + j);
|
||||
t = t.multiply(binomial(j, nu));
|
||||
if (nu % 2 != 0)
|
||||
if (nu % 2 != 0) {
|
||||
nusum = nusum.subtract(t);
|
||||
else
|
||||
} else {
|
||||
nusum = nusum.add(t);
|
||||
}
|
||||
}
|
||||
nusum = nusum.divide(f.at(j)).divide(n + j);
|
||||
nusum = nusum.multiply(binomial(2 * kprime, kprime - j));
|
||||
if (j % 2 != 0)
|
||||
if (j % 2 != 0) {
|
||||
jsum = jsum.subtract(nusum);
|
||||
else
|
||||
} else {
|
||||
jsum = jsum.add(nusum);
|
||||
}
|
||||
}
|
||||
return jsum.multiply(k).multiply(binomial(n + kprime, k));
|
||||
}
|
||||
@ -597,11 +629,11 @@ public class BigIntegerMath {
|
||||
* et al, Num. Funct. Anal. Opt. 10 (5)( 1989) 419-488</a>
|
||||
*/
|
||||
static public Rational centrlFactNumT(int n, int k) {
|
||||
if (k > n || k < 0 || (k % 2) != (n % 2))
|
||||
if (k > n || k < 0 || (k % 2) != (n % 2)) {
|
||||
return Rational.ZERO;
|
||||
else if (k == n)
|
||||
} else if (k == n) {
|
||||
return Rational.ONE;
|
||||
else {
|
||||
} else {
|
||||
/* Proposition 2.1 */
|
||||
return centrlFactNumT(n - 2, k - 2).add(centrlFactNumT(n - 2, k).multiply(new Rational(k * k, 4)));
|
||||
}
|
||||
|
@ -39,10 +39,11 @@ public class BigIntegerPoly implements Cloneable {
|
||||
*/
|
||||
public BigIntegerPoly(final String L) throws NumberFormatException {
|
||||
a = new Vector<>();
|
||||
Scanner sc = new Scanner(L);
|
||||
final Scanner sc = new Scanner(L);
|
||||
sc.useDelimiter(",");
|
||||
while (sc.hasNextBigInteger())
|
||||
while (sc.hasNextBigInteger()) {
|
||||
a.add(sc.nextBigInteger());
|
||||
}
|
||||
simplify();
|
||||
sc.close();
|
||||
} /* ctor */
|
||||
@ -66,8 +67,9 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* The coefficients a0, a1, a2 etc in a0+a1*x+a2*x^2+...
|
||||
*/
|
||||
public BigIntegerPoly(final BigInteger[] c) {
|
||||
for (int i = 0; i < c.length; i++)
|
||||
a.add(c[i].add(BigInteger.ZERO));
|
||||
for (final BigInteger element : c) {
|
||||
a.add(element.add(BigInteger.ZERO));
|
||||
}
|
||||
simplify();
|
||||
} /* ctor */
|
||||
|
||||
@ -87,9 +89,10 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @since 2012-03-02
|
||||
*/
|
||||
public RatPoly toRatPoly() {
|
||||
RatPoly bd = new RatPoly();
|
||||
for (int i = 0; i < a.size(); i++)
|
||||
final RatPoly bd = new RatPoly();
|
||||
for (int i = 0; i < a.size(); i++) {
|
||||
bd.set(i, a.elementAt(i));
|
||||
}
|
||||
return bd;
|
||||
} /* toRatPoly */
|
||||
|
||||
@ -102,10 +105,11 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @return the polynomial coefficient in front of x^n.
|
||||
*/
|
||||
public BigInteger at(final int n) {
|
||||
if (n < a.size())
|
||||
if (n < a.size()) {
|
||||
return (a.elementAt(n));
|
||||
else
|
||||
} else {
|
||||
return (BigInteger.ZERO);
|
||||
}
|
||||
} /* at */
|
||||
|
||||
/**
|
||||
@ -118,14 +122,16 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public BigInteger valueOf(final BigInteger x) {
|
||||
if (a.size() == 0)
|
||||
if (a.size() == 0) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
BigInteger res = a.lastElement();
|
||||
/*
|
||||
* Heron casted form
|
||||
*/
|
||||
for (int i = a.size() - 2; i >= 0; i--)
|
||||
for (int i = a.size() - 2; i >= 0; i--) {
|
||||
res = res.multiply(x).add(a.elementAt(i));
|
||||
}
|
||||
return res;
|
||||
} /* valueOf */
|
||||
|
||||
@ -154,9 +160,9 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* the new value of the coefficient.
|
||||
*/
|
||||
public void set(final int n, final BigInteger value) {
|
||||
if (n < a.size())
|
||||
if (n < a.size()) {
|
||||
a.set(n, value);
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* fill intermediate powers with coefficients of zero
|
||||
*/
|
||||
@ -180,7 +186,7 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* the new value of the coefficient.
|
||||
*/
|
||||
public void set(final int n, final int value) {
|
||||
BigInteger val2 = new BigInteger("" + value);
|
||||
final BigInteger val2 = new BigInteger("" + value);
|
||||
set(n, val2);
|
||||
} /* set */
|
||||
|
||||
@ -210,9 +216,11 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* If the polynomial is identical to 0, 0 is returned.
|
||||
*/
|
||||
public int ldegree() {
|
||||
for (int n = 0; n < a.size(); n++)
|
||||
if (a.elementAt(n).compareTo(BigInteger.ZERO) != 0)
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
if (a.elementAt(n).compareTo(BigInteger.ZERO) != 0) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} /* ldegree */
|
||||
|
||||
@ -227,10 +235,12 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public BigIntegerPoly multiply(final BigInteger val) {
|
||||
BigIntegerPoly resul = new BigIntegerPoly();
|
||||
if (val.compareTo(BigInteger.ZERO) != 0)
|
||||
for (int n = 0; n < a.size(); n++)
|
||||
final BigIntegerPoly resul = new BigIntegerPoly();
|
||||
if (val.compareTo(BigInteger.ZERO) != 0) {
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
resul.set(n, a.elementAt(n).multiply(val));
|
||||
}
|
||||
}
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
@ -242,15 +252,16 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @return the product of this with the other polynomial
|
||||
*/
|
||||
public BigIntegerPoly multiply(final BigIntegerPoly val) {
|
||||
BigIntegerPoly resul = new BigIntegerPoly();
|
||||
final BigIntegerPoly resul = new BigIntegerPoly();
|
||||
/*
|
||||
* the degree of the result is the sum of the two degrees.
|
||||
*/
|
||||
final int nmax = degree() + val.degree();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
BigInteger coef = BigInteger.ZERO;
|
||||
for (int nleft = 0; nleft <= n; nleft++)
|
||||
for (int nleft = 0; nleft <= n; nleft++) {
|
||||
coef = coef.add(at(nleft).multiply(val.at(n - nleft)));
|
||||
}
|
||||
resul.set(n, coef);
|
||||
}
|
||||
resul.simplify();
|
||||
@ -266,11 +277,12 @@ public class BigIntegerPoly implements Cloneable {
|
||||
*/
|
||||
public BigIntegerPoly pow(final int n) throws ArithmeticException {
|
||||
BigIntegerPoly resul = new BigIntegerPoly("1");
|
||||
if (n < 0)
|
||||
if (n < 0) {
|
||||
throw new ArithmeticException("negative polynomial power " + n);
|
||||
else {
|
||||
for (int i = 1; i <= n; i++)
|
||||
} else {
|
||||
for (int i = 1; i <= n; i++) {
|
||||
resul = resul.multiply(this);
|
||||
}
|
||||
resul.simplify();
|
||||
return resul;
|
||||
}
|
||||
@ -285,14 +297,14 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public BigIntegerPoly add(final BigIntegerPoly val) {
|
||||
BigIntegerPoly resul = new BigIntegerPoly();
|
||||
final BigIntegerPoly resul = new BigIntegerPoly();
|
||||
/*
|
||||
* the degree of the result is the larger of the two degrees (before
|
||||
* simplify() at least).
|
||||
*/
|
||||
final int nmax = (degree() > val.degree()) ? degree() : val.degree();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
BigInteger coef = at(n).add(val.at(n));
|
||||
final BigInteger coef = at(n).add(val.at(n));
|
||||
resul.set(n, coef);
|
||||
}
|
||||
resul.simplify();
|
||||
@ -308,14 +320,14 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @since 2008-10-25
|
||||
*/
|
||||
public BigIntegerPoly subtract(final BigIntegerPoly val) {
|
||||
BigIntegerPoly resul = new BigIntegerPoly();
|
||||
final BigIntegerPoly resul = new BigIntegerPoly();
|
||||
/*
|
||||
* the degree of the result is the larger of the two degrees (before
|
||||
* simplify() at least).
|
||||
*/
|
||||
final int nmax = (degree() > val.degree()) ? degree() : val.degree();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
BigInteger coef = at(n).subtract(val.at(n));
|
||||
final BigInteger coef = at(n).subtract(val.at(n));
|
||||
resul.set(n, coef);
|
||||
}
|
||||
resul.simplify();
|
||||
@ -334,19 +346,20 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @since 2012-03-01
|
||||
*/
|
||||
public BigIntegerPoly[] divideAndRemainder(final BigIntegerPoly val) {
|
||||
BigIntegerPoly[] ret = new BigIntegerPoly[2];
|
||||
final BigIntegerPoly[] ret = new BigIntegerPoly[2];
|
||||
/*
|
||||
* remove any high-order zeros. note that the clone() operation calls
|
||||
* simplify().
|
||||
*/
|
||||
BigIntegerPoly valSimpl = val.clone();
|
||||
BigIntegerPoly thisSimpl = clone();
|
||||
final BigIntegerPoly valSimpl = val.clone();
|
||||
final BigIntegerPoly thisSimpl = clone();
|
||||
|
||||
/*
|
||||
* catch the case with val equal to zero
|
||||
*/
|
||||
if (valSimpl.degree() == 0 && valSimpl.a.firstElement().compareTo(BigInteger.ZERO) == 0)
|
||||
if (valSimpl.degree() == 0 && valSimpl.a.firstElement().compareTo(BigInteger.ZERO) == 0) {
|
||||
throw new ArithmeticException("Division through zero polynomial");
|
||||
}
|
||||
/*
|
||||
* degree of this smaller than degree of val: remainder is this
|
||||
*/
|
||||
@ -363,9 +376,10 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* polynomial division cannot be done with integer coefficients.
|
||||
*/
|
||||
ret[0] = new BigIntegerPoly();
|
||||
BigInteger[] newc = thisSimpl.a.lastElement().divideAndRemainder(valSimpl.a.lastElement());
|
||||
if (newc[1].compareTo(BigInteger.ZERO) != 0)
|
||||
final BigInteger[] newc = thisSimpl.a.lastElement().divideAndRemainder(valSimpl.a.lastElement());
|
||||
if (newc[1].compareTo(BigInteger.ZERO) != 0) {
|
||||
throw new ArithmeticException("Incompatible leading term in " + this + " / " + val);
|
||||
}
|
||||
ret[0].set(thisSimpl.degree() - valSimpl.degree(), newc[0]);
|
||||
|
||||
/*
|
||||
@ -378,10 +392,10 @@ public class BigIntegerPoly implements Cloneable {
|
||||
/*
|
||||
* any remainder left ?
|
||||
*/
|
||||
if (ret[1].degree() < valSimpl.degree())
|
||||
if (ret[1].degree() < valSimpl.degree()) {
|
||||
;
|
||||
else {
|
||||
BigIntegerPoly rem[] = ret[1].divideAndRemainder(val);
|
||||
} else {
|
||||
final BigIntegerPoly rem[] = ret[1].divideAndRemainder(val);
|
||||
ret[0] = ret[0].add(rem[0]);
|
||||
ret[1] = rem[1];
|
||||
}
|
||||
@ -399,13 +413,15 @@ public class BigIntegerPoly implements Cloneable {
|
||||
public String toString() {
|
||||
String str = new String();
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
if (n == 0)
|
||||
if (n == 0) {
|
||||
str += a.elementAt(n).toString();
|
||||
else
|
||||
} else {
|
||||
str += "," + a.elementAt(n).toString();
|
||||
}
|
||||
}
|
||||
if (str.length() == 0)
|
||||
if (str.length() == 0) {
|
||||
str = "0";
|
||||
}
|
||||
return str;
|
||||
} /* toString */
|
||||
|
||||
@ -422,18 +438,21 @@ public class BigIntegerPoly implements Cloneable {
|
||||
final BigInteger num = a.elementAt(n);
|
||||
if (num.compareTo(BigInteger.ZERO) != 0) {
|
||||
str += " ";
|
||||
if (num.compareTo(BigInteger.ZERO) > 0 && n > 0)
|
||||
if (num.compareTo(BigInteger.ZERO) > 0 && n > 0) {
|
||||
str += "+";
|
||||
}
|
||||
str += a.elementAt(n).toString();
|
||||
if (n > 0) {
|
||||
str += "*x";
|
||||
if (n > 1)
|
||||
if (n > 1) {
|
||||
str += "^" + n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (str.length() == 0)
|
||||
if (str.length() == 0) {
|
||||
str = "0";
|
||||
}
|
||||
return str;
|
||||
} /* toPString */
|
||||
|
||||
@ -443,12 +462,14 @@ public class BigIntegerPoly implements Cloneable {
|
||||
*/
|
||||
protected void simplify() {
|
||||
int n = a.size() - 1;
|
||||
if (n >= 0)
|
||||
if (n >= 0) {
|
||||
while (a.elementAt(n).compareTo(BigInteger.ZERO) == 0) {
|
||||
a.removeElementAt(n);
|
||||
if (--n < 0)
|
||||
if (--n < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* simplify */
|
||||
|
||||
/**
|
||||
@ -464,7 +485,7 @@ public class BigIntegerPoly implements Cloneable {
|
||||
*/
|
||||
return new BigIntegerPoly();
|
||||
} else {
|
||||
BigIntegerPoly d = new BigIntegerPoly();
|
||||
final BigIntegerPoly d = new BigIntegerPoly();
|
||||
for (int i = 1; i <= degree(); i++) {
|
||||
final BigInteger c = a.elementAt(i).multiply(new BigInteger("" + i));
|
||||
d.set(i - 1, c);
|
||||
@ -480,9 +501,10 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public BigIntegerPoly trunc(int newdeg) {
|
||||
BigIntegerPoly t = new BigIntegerPoly();
|
||||
for (int i = 0; i <= newdeg; i++)
|
||||
final BigIntegerPoly t = new BigIntegerPoly();
|
||||
for (int i = 0; i <= newdeg; i++) {
|
||||
t.set(i, at(i));
|
||||
}
|
||||
t.simplify();
|
||||
return t;
|
||||
} /* trunc */
|
||||
@ -497,14 +519,16 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* @since 2010-08-29
|
||||
*/
|
||||
public BigIntegerPoly binomialTInv(int maxdeg) {
|
||||
BigIntegerPoly r = new BigIntegerPoly();
|
||||
final BigIntegerPoly r = new BigIntegerPoly();
|
||||
for (int i = 0; i <= maxdeg; i++) {
|
||||
BigInteger c = BigInteger.ZERO;
|
||||
for (int j = 0; j <= i && j < a.size(); j++)
|
||||
if ((j + i) % 2 != 0)
|
||||
for (int j = 0; j <= i && j < a.size(); j++) {
|
||||
if ((j + i) % 2 != 0) {
|
||||
c = c.subtract(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
|
||||
else
|
||||
} else {
|
||||
c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
|
||||
}
|
||||
}
|
||||
r.set(i, c);
|
||||
}
|
||||
r.simplify();
|
||||
@ -537,31 +561,34 @@ public class BigIntegerPoly implements Cloneable {
|
||||
*/
|
||||
public Vector<BigInteger> iroots() {
|
||||
/* The vector of the roots */
|
||||
Vector<BigInteger> res = new Vector<>();
|
||||
final Vector<BigInteger> res = new Vector<>();
|
||||
|
||||
/*
|
||||
* collect the zero
|
||||
*/
|
||||
if (a.firstElement().compareTo(BigInteger.ZERO) == 0)
|
||||
if (a.firstElement().compareTo(BigInteger.ZERO) == 0) {
|
||||
res.add(BigInteger.ZERO);
|
||||
}
|
||||
|
||||
/*
|
||||
* collect the divisors of the constant element (or the reduced
|
||||
* polynomial)
|
||||
*/
|
||||
int l = ldegree();
|
||||
final int l = ldegree();
|
||||
if (a.elementAt(l).compareTo(BigInteger.ZERO) != 0) {
|
||||
Vector<BigInteger> cand = BigIntegerMath.divisors(a.elementAt(l).abs());
|
||||
final Vector<BigInteger> cand = BigIntegerMath.divisors(a.elementAt(l).abs());
|
||||
|
||||
/* check the divisors (both signs) */
|
||||
for (int i = 0; i < cand.size(); i++) {
|
||||
BigInteger roo = valueOf(cand.elementAt(i));
|
||||
if (roo.compareTo(BigInteger.ZERO) == 0)
|
||||
if (roo.compareTo(BigInteger.ZERO) == 0) {
|
||||
/* found a root cand[i] */
|
||||
res.add(cand.elementAt(i));
|
||||
}
|
||||
roo = valueOf(cand.elementAt(i).negate());
|
||||
if (roo.compareTo(BigInteger.ZERO) == 0)
|
||||
if (roo.compareTo(BigInteger.ZERO) == 0) {
|
||||
res.add(cand.elementAt(i).negate());
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@ -581,15 +608,16 @@ public class BigIntegerPoly implements Cloneable {
|
||||
/*
|
||||
* The vector of the factors to be returned
|
||||
*/
|
||||
Vector<BigIntegerPoly> res = new Vector<>();
|
||||
final Vector<BigIntegerPoly> res = new Vector<>();
|
||||
|
||||
if (degree() < 2)
|
||||
if (degree() < 2) {
|
||||
return res;
|
||||
}
|
||||
|
||||
BigInteger bsco = a.firstElement().abs();
|
||||
Vector<BigInteger> b = BigIntegerMath.divisors(bsco);
|
||||
BigInteger csco = a.lastElement().abs();
|
||||
Vector<BigInteger> c = BigIntegerMath.divisors(csco);
|
||||
final BigInteger bsco = a.firstElement().abs();
|
||||
final Vector<BigInteger> b = BigIntegerMath.divisors(bsco);
|
||||
final BigInteger csco = a.lastElement().abs();
|
||||
final Vector<BigInteger> c = BigIntegerMath.divisors(csco);
|
||||
|
||||
/*
|
||||
* Generate the floating point values of roots. To have some reasonable
|
||||
@ -601,8 +629,8 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* estimate
|
||||
* and adding 6 safety digits
|
||||
*/
|
||||
RatPoly thisDec = toRatPoly();
|
||||
Vector<BigComplex> roo = thisDec.roots(6 + (int) (0.3 * bsco.bitCount()));
|
||||
final RatPoly thisDec = toRatPoly();
|
||||
final Vector<BigComplex> roo = thisDec.roots(6 + (int) (0.3 * bsco.bitCount()));
|
||||
|
||||
final BigDecimal half = new BigDecimal("0.5");
|
||||
|
||||
@ -613,9 +641,9 @@ public class BigIntegerPoly implements Cloneable {
|
||||
* coefficient.
|
||||
* Solve z*(c*z+a)=-b or c*z+a = -b/z or -b/z-c*z = some integer a.
|
||||
*/
|
||||
for (BigComplex z : roo) {
|
||||
for (BigInteger bco : b)
|
||||
for (BigInteger cco : c) {
|
||||
for (final BigComplex z : roo) {
|
||||
for (final BigInteger bco : b) {
|
||||
for (final BigInteger cco : c) {
|
||||
/*
|
||||
* the major reason to avoid the case b=0 is that this would
|
||||
* require precaution of double counting below. Note that
|
||||
@ -624,7 +652,7 @@ public class BigIntegerPoly implements Cloneable {
|
||||
*/
|
||||
if (bco.signum() != 0) {
|
||||
for (int sig = -1; sig <= 1; sig += 2) {
|
||||
BigInteger bcosig = (sig > 0) ? bco : bco.negate();
|
||||
final BigInteger bcosig = (sig > 0) ? bco : bco.negate();
|
||||
/*
|
||||
* -a = b/z+c*z has real part b*Re(z)/|z|^2+c*Re(z)
|
||||
* = Re z *( b/|z|^2+c)
|
||||
@ -634,22 +662,24 @@ public class BigIntegerPoly implements Cloneable {
|
||||
/*
|
||||
* convert to a with round-to-nearest
|
||||
*/
|
||||
BigInteger a = negA.negate().add(half).toBigInteger();
|
||||
final BigInteger a = negA.negate().add(half).toBigInteger();
|
||||
|
||||
/*
|
||||
* test the polynomial remainder. if zero, add the
|
||||
* term
|
||||
* to the results.
|
||||
*/
|
||||
BigIntegerPoly dtst = new BigIntegerPoly("" + bcosig + "," + a + "," + cco);
|
||||
final BigIntegerPoly dtst = new BigIntegerPoly("" + bcosig + "," + a + "," + cco);
|
||||
try {
|
||||
BigIntegerPoly[] rm = divideAndRemainder(dtst);
|
||||
if (rm[1].isZero())
|
||||
final BigIntegerPoly[] rm = divideAndRemainder(dtst);
|
||||
if (rm[1].isZero()) {
|
||||
res.add(dtst);
|
||||
} catch (ArithmeticException ex) {}
|
||||
}
|
||||
} catch (final ArithmeticException ex) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -679,16 +709,16 @@ public class BigIntegerPoly implements Cloneable {
|
||||
/*
|
||||
* this ought be entirely rewritten in terms of the LLL algorithm
|
||||
*/
|
||||
Vector<BigIntegerPoly> fac = new Vector<>();
|
||||
final Vector<BigIntegerPoly> fac = new Vector<>();
|
||||
|
||||
/* collect integer roots (polynomial factors of degree 1) */
|
||||
Vector<BigInteger> r = iroots();
|
||||
final Vector<BigInteger> r = iroots();
|
||||
BigIntegerPoly[] res = new BigIntegerPoly[2];
|
||||
res[0] = this;
|
||||
for (BigInteger i : r) {
|
||||
int deg = rootDeg(i);
|
||||
for (final BigInteger i : r) {
|
||||
final int deg = rootDeg(i);
|
||||
/* construct the factor x-i */
|
||||
BigIntegerPoly f = new BigIntegerPoly("" + i.negate() + ",1");
|
||||
final BigIntegerPoly f = new BigIntegerPoly("" + i.negate() + ",1");
|
||||
for (int mu = 0; mu < deg; mu++) {
|
||||
fac.add(f);
|
||||
res = res[0].divideAndRemainder(f);
|
||||
@ -698,21 +728,22 @@ public class BigIntegerPoly implements Cloneable {
|
||||
/*
|
||||
* collect factors which are polynomials of degree 2
|
||||
*/
|
||||
Vector<BigIntegerPoly> pol2 = i2roots();
|
||||
for (BigIntegerPoly i : pol2) {
|
||||
final Vector<BigIntegerPoly> pol2 = i2roots();
|
||||
for (final BigIntegerPoly i : pol2) {
|
||||
/*
|
||||
* the internal loop catches cases with higher
|
||||
* powers of individual polynomials (of actual degree 2 or 4...)
|
||||
*/
|
||||
while (res[0].degree() >= 2) {
|
||||
try {
|
||||
BigIntegerPoly[] dtst = res[0].divideAndRemainder(i);
|
||||
final BigIntegerPoly[] dtst = res[0].divideAndRemainder(i);
|
||||
if (dtst[1].isZero()) {
|
||||
fac.add(i);
|
||||
res = dtst;
|
||||
} else
|
||||
} else {
|
||||
break;
|
||||
} catch (ArithmeticException ex) {
|
||||
}
|
||||
} catch (final ArithmeticException ex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -721,8 +752,9 @@ public class BigIntegerPoly implements Cloneable {
|
||||
/*
|
||||
* add remaining factor, if not equal to 1
|
||||
*/
|
||||
if (res[0].degree() > 0 || res[0].a.firstElement().compareTo(BigInteger.ONE) != 0)
|
||||
if (res[0].degree() > 0 || res[0].a.firstElement().compareTo(BigInteger.ONE) != 0) {
|
||||
fac.add(res[0]);
|
||||
}
|
||||
return fac;
|
||||
} /* ifactor */
|
||||
|
||||
|
@ -60,17 +60,18 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(Rational a, Rational b) {
|
||||
this.pref = a;
|
||||
pref = a;
|
||||
/*
|
||||
* reject attempts to use a negative b
|
||||
*/
|
||||
if (b.signum() < 0)
|
||||
if (b.signum() < 0) {
|
||||
throw new ProviderException("Not implemented: imaginary surds");
|
||||
this.disc = b;
|
||||
}
|
||||
disc = b;
|
||||
try {
|
||||
normalize();
|
||||
normalizeG();
|
||||
} catch (Error e) {
|
||||
} catch (final Error e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -112,8 +113,8 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
*/
|
||||
@Override
|
||||
public BigSurd clone() {
|
||||
Rational fclon = pref.clone();
|
||||
Rational dclon = disc.clone();
|
||||
final Rational fclon = pref.clone();
|
||||
final Rational dclon = disc.clone();
|
||||
/*
|
||||
* the main intent here is to bypass any attempt to reduce the
|
||||
* discriminant
|
||||
@ -121,7 +122,7 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
* already done
|
||||
* in the current copy of the number.
|
||||
*/
|
||||
BigSurd cl = new BigSurd();
|
||||
final BigSurd cl = new BigSurd();
|
||||
cl.pref = fclon;
|
||||
cl.disc = dclon;
|
||||
return cl;
|
||||
@ -136,13 +137,14 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
|
||||
public BigSurdVec add(final BigSurd val) {
|
||||
// zero plus somethings yields something
|
||||
if (signum() == 0)
|
||||
if (signum() == 0) {
|
||||
return new BigSurdVec(val);
|
||||
else if (val.signum() == 0)
|
||||
} else if (val.signum() == 0) {
|
||||
return new BigSurdVec(this);
|
||||
else
|
||||
} else {
|
||||
// let the ctor of BigSurdVec to the work
|
||||
return new BigSurdVec(this, val);
|
||||
}
|
||||
} /* BigSurd.add */
|
||||
|
||||
/**
|
||||
@ -190,7 +192,7 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final int val) {
|
||||
BigInteger tmp = new BigInteger("" + val);
|
||||
final BigInteger tmp = new BigInteger("" + val);
|
||||
return multiply(tmp);
|
||||
} /* BigSurd.multiply */
|
||||
|
||||
@ -216,14 +218,15 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(final BigSurd val) throws Error {
|
||||
if (val.signum() == 0)
|
||||
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;
|
||||
final BigSurd bs = this;
|
||||
final BigInteger denominator = pref.b;
|
||||
String s = "";
|
||||
if (denominator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += "(";
|
||||
@ -233,7 +236,7 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
} else if (bs.isRational()) {
|
||||
s += bs.toRational().toString();
|
||||
} else {
|
||||
BigInteger numerator = bs.pref.a;
|
||||
final BigInteger numerator = bs.pref.a;
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += numerator.toString();
|
||||
s += "*";
|
||||
@ -262,8 +265,9 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(final BigInteger val) throws Error {
|
||||
if (val.signum() == 0)
|
||||
if (val.signum() == 0) {
|
||||
throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
|
||||
}
|
||||
return new BigSurd(pref.divide(val), disc);
|
||||
} /* BigSurd.divide */
|
||||
|
||||
@ -277,8 +281,9 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(int val) throws Error {
|
||||
if (val == 0)
|
||||
if (val == 0) {
|
||||
throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
|
||||
}
|
||||
return new BigSurd(pref.divide(val), disc);
|
||||
} /* BigSurd.divide */
|
||||
|
||||
@ -293,7 +298,7 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
* This is trying to be quick, avoiding normalize(), by toggling
|
||||
* the sign in a clone()
|
||||
*/
|
||||
BigSurd n = clone();
|
||||
final BigSurd n = clone();
|
||||
n.pref = n.pref.negate();
|
||||
return n;
|
||||
} /* BigSurd.negate */
|
||||
@ -325,16 +330,21 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
*/
|
||||
final int sig = signum();
|
||||
final int sigv = val.signum();
|
||||
if (sig < 0 && sigv >= 0)
|
||||
if (sig < 0 && sigv >= 0) {
|
||||
return -1;
|
||||
if (sig > 0 && sigv <= 0)
|
||||
}
|
||||
if (sig > 0 && sigv <= 0) {
|
||||
return 1;
|
||||
if (sig == 0 && sigv == 0)
|
||||
}
|
||||
if (sig == 0 && sigv == 0) {
|
||||
return 0;
|
||||
if (sig == 0 && sigv > 0)
|
||||
}
|
||||
if (sig == 0 && sigv > 0) {
|
||||
return -1;
|
||||
if (sig == 0 && sigv < 0)
|
||||
}
|
||||
if (sig == 0 && sigv < 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Work out the cases of equal sign. Compare absolute values by
|
||||
@ -345,16 +355,13 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
final Rational this2 = sqr();
|
||||
final Rational val2 = val.sqr();
|
||||
final int c = this2.compareTo(val2);
|
||||
if (c == 0)
|
||||
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)
|
||||
} else if (sig > 0 && c > 0 || sig < 0 && c < 0) {
|
||||
return 1;
|
||||
else
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} /* BigSurd.compareTo */
|
||||
|
||||
/**
|
||||
@ -366,10 +373,11 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (disc.compareTo(Rational.ONE) != 0 && disc.compareTo(Rational.ZERO) != 0)
|
||||
if (disc.compareTo(Rational.ONE) != 0 && disc.compareTo(Rational.ZERO) != 0) {
|
||||
return ("(" + pref.toString() + ")*(" + disc.toString() + ")^(1/2)");
|
||||
else
|
||||
} else {
|
||||
return pref.toString();
|
||||
}
|
||||
} /* BigSurd.toString */
|
||||
|
||||
/**
|
||||
@ -383,9 +391,9 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
* 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);
|
||||
final Rational p2 = pref.pow(2).multiply(disc);
|
||||
System.out.println("dv sq " + p2.toString());
|
||||
double res = p2.doubleValue();
|
||||
final double res = p2.doubleValue();
|
||||
System.out.println("dv sq " + res);
|
||||
return (pref.signum() >= 0) ? Math.sqrt(res) : -Math.sqrt(res);
|
||||
} /* BigSurd.doubleValue */
|
||||
@ -428,10 +436,11 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public Rational toRational() {
|
||||
if (isRational())
|
||||
if (isRational()) {
|
||||
return pref;
|
||||
else
|
||||
} else {
|
||||
throw new ArithmeticException("Undefined conversion " + toFancyString() + " to Rational.");
|
||||
}
|
||||
} /* BigSurd.toRational */
|
||||
|
||||
/**
|
||||
@ -463,7 +472,7 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
/*
|
||||
* square-free part of the numerator: numer = numC*some^2
|
||||
*/
|
||||
BigInteger numC = BigIntegerMath.core(disc.numer());
|
||||
final BigInteger numC = BigIntegerMath.core(disc.numer());
|
||||
/*
|
||||
* extract the perfect square of the numerator
|
||||
*/
|
||||
@ -478,14 +487,15 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
*/
|
||||
pref = pref.multiply(sqf);
|
||||
|
||||
BigInteger denC = BigIntegerMath.core(disc.denom());
|
||||
final 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
|
||||
} else {
|
||||
pref = Rational.ZERO;
|
||||
}
|
||||
} /* BigSurd.normalize */
|
||||
|
||||
/**
|
||||
@ -544,13 +554,13 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
/*
|
||||
* first the square root of the discriminant
|
||||
*/
|
||||
BigDecimal sqrdis = BigDecimalMath.sqrt(disc.BigDecimalValue(locmc), locmc);
|
||||
final 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));
|
||||
final BigDecimal res = sqrdis.multiply(pref.BigDecimalValue(mc));
|
||||
return BigDecimalMath.scalePrec(res, mc);
|
||||
} /* BigDecimalValue */
|
||||
|
||||
|
@ -69,7 +69,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
terms.add(b);
|
||||
try {
|
||||
normalize();
|
||||
} catch (Error e) {
|
||||
} catch (final Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -87,16 +87,17 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
/*
|
||||
* nothing to be done if at most one term
|
||||
*/
|
||||
if (terms.size() <= 1)
|
||||
if (terms.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<BigSurd> newter = new Vector<>();
|
||||
final Vector<BigSurd> newter = new Vector<>();
|
||||
newter.add(terms.firstElement());
|
||||
/*
|
||||
* add j-th element to the existing vector and combine were possible
|
||||
*/
|
||||
for (int j = 1; j < terms.size(); j++) {
|
||||
BigSurd todo = terms.elementAt(j);
|
||||
final BigSurd todo = terms.elementAt(j);
|
||||
boolean merged = false;
|
||||
for (int ex = 0; ex < newter.size(); ex++) {
|
||||
BigSurd v = newter.elementAt(ex);
|
||||
@ -105,16 +106,16 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* rational number is needed. Replaces v with v+todo = v*(1+r)
|
||||
* if this reduction works.
|
||||
*/
|
||||
BigSurd r = todo.divide(v);
|
||||
final BigSurd r = todo.divide(v);
|
||||
if (r.isRational()) {
|
||||
/* compute r+1 */
|
||||
Rational newpref = r.toRational().add(1);
|
||||
final Rational newpref = r.toRational().add(1);
|
||||
/*
|
||||
* eliminate accidental zeros; overwrite with v*(1+r).
|
||||
*/
|
||||
if (newpref.compareTo(Rational.ZERO) == 0)
|
||||
if (newpref.compareTo(Rational.ZERO) == 0) {
|
||||
newter.removeElementAt(ex);
|
||||
else {
|
||||
} else {
|
||||
v = v.multiply(newpref);
|
||||
newter.setElementAt(v, ex);
|
||||
}
|
||||
@ -125,8 +126,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
/*
|
||||
* append if none of the existing elements matched
|
||||
*/
|
||||
if (!merged)
|
||||
if (!merged) {
|
||||
newter.add(todo);
|
||||
}
|
||||
}
|
||||
|
||||
/* overwrite old version */
|
||||
@ -148,7 +150,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
try {
|
||||
diff = this.subtract(oth);
|
||||
return diff.signum();
|
||||
} catch (Error e) {
|
||||
} catch (final Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
@ -168,34 +170,40 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* the case of zero is unique, because no (reduced) vector of surds
|
||||
* other than the one element 0 itself can add/subtract to zero.
|
||||
*/
|
||||
if (terms.size() == 0)
|
||||
if (terms.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* if there is one term: forward to the signum function of BigSurd
|
||||
*/
|
||||
if (terms.size() == 1)
|
||||
if (terms.size() == 1) {
|
||||
return terms.firstElement().signum();
|
||||
}
|
||||
|
||||
/*
|
||||
* if all terms have a common sign: take that one offsig is the index of
|
||||
* the first "offending" term in the sense that its sign doese not agree
|
||||
* with the term[0].
|
||||
*/
|
||||
int sig0 = terms.elementAt(0).signum();
|
||||
final int sig0 = terms.elementAt(0).signum();
|
||||
int offsig = 1;
|
||||
for (; offsig < terms.size(); offsig++)
|
||||
if (terms.elementAt(offsig).signum() != sig0)
|
||||
for (; offsig < terms.size(); offsig++) {
|
||||
if (terms.elementAt(offsig).signum() != sig0) {
|
||||
break;
|
||||
if (offsig >= terms.size())
|
||||
}
|
||||
}
|
||||
if (offsig >= terms.size()) {
|
||||
return sig0;
|
||||
}
|
||||
|
||||
/*
|
||||
* if there are two terms (now known to have different sign): forward to
|
||||
* the comparison of the two elements as BigSurds
|
||||
*/
|
||||
if (terms.size() == 2)
|
||||
if (terms.size() == 2) {
|
||||
return terms.elementAt(0).compareTo(terms.elementAt(1).negate());
|
||||
}
|
||||
|
||||
/*
|
||||
* if there are three terms, move the one with the offending sign to the
|
||||
@ -206,10 +214,11 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
*/
|
||||
if (terms.size() == 3) {
|
||||
BigSurdVec lhs;
|
||||
if (offsig == 2)
|
||||
if (offsig == 2) {
|
||||
lhs = new BigSurdVec(terms.elementAt(0), terms.elementAt(1));
|
||||
else
|
||||
} 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
|
||||
@ -223,13 +232,14 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
*
|
||||
*
|
||||
*/
|
||||
if (lhs.compareTo(lhs) > 0)
|
||||
if (lhs.compareTo(lhs) > 0) {
|
||||
/*
|
||||
* dominating sign was t(0)+t(offbar)
|
||||
*/
|
||||
return terms.elementAt(0).signum();
|
||||
else
|
||||
} else {
|
||||
return terms.elementAt(offsig).signum();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -252,9 +262,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
/*
|
||||
* simple cases with one term forwarded to the BigSurd class
|
||||
*/
|
||||
if (terms.size() == 0)
|
||||
if (terms.size() == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
else if (terms.size() == 1) {
|
||||
} else if (terms.size() == 1) {
|
||||
return terms.firstElement().BigDecimalValue(mc);
|
||||
}
|
||||
|
||||
@ -263,18 +273,20 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* until we are stable to the required result. Keep the old (less
|
||||
* precise) estimate in res[0], and the newer, more precise in res[1].
|
||||
*/
|
||||
BigDecimal[] res = new BigDecimal[2];
|
||||
final BigDecimal[] res = new BigDecimal[2];
|
||||
res[0] = BigDecimal.ZERO;
|
||||
for (int addpr = 1;; addpr += 3) {
|
||||
MathContext locmc = new MathContext(mc.getPrecision() + addpr, mc.getRoundingMode());
|
||||
final MathContext locmc = new MathContext(mc.getPrecision() + addpr, mc.getRoundingMode());
|
||||
res[1] = BigDecimal.ZERO;
|
||||
for (BigSurd j : terms)
|
||||
for (final BigSurd j : terms) {
|
||||
res[1] = BigDecimalMath.addRound(res[1], j.BigDecimalValue(locmc));
|
||||
}
|
||||
if (addpr > 1) {
|
||||
BigDecimal err = res[1].subtract(res[0]).abs();
|
||||
int prec = BigDecimalMath.err2prec(res[1], err);
|
||||
if (prec > mc.getPrecision())
|
||||
final BigDecimal err = res[1].subtract(res[0]).abs();
|
||||
final int prec = BigDecimalMath.err2prec(res[1], err);
|
||||
if (prec > mc.getPrecision()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
res[0] = res[1];
|
||||
}
|
||||
@ -288,7 +300,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @return A truncated version with the precision described by mc
|
||||
*/
|
||||
public double doubleValue() {
|
||||
BigDecimal bd = BigDecimalValue(MathContext.DECIMAL128);
|
||||
final BigDecimal bd = BigDecimalValue(MathContext.DECIMAL128);
|
||||
return bd.doubleValue();
|
||||
} /* doubleValue */
|
||||
|
||||
@ -298,7 +310,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @return A truncated version with the precision described by mc
|
||||
*/
|
||||
public double floatValue() {
|
||||
BigDecimal bd = BigDecimalValue(MathContext.DECIMAL64);
|
||||
final BigDecimal bd = BigDecimalValue(MathContext.DECIMAL64);
|
||||
return bd.floatValue();
|
||||
} /* floatValue */
|
||||
|
||||
@ -311,16 +323,16 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @throws Error
|
||||
*/
|
||||
public BigSurdVec add(final BigSurdVec val) throws Error {
|
||||
BigSurdVec sum = new BigSurdVec();
|
||||
final BigSurdVec sum = new BigSurdVec();
|
||||
/*
|
||||
* concatenate the vectors and eliminate common overlaps
|
||||
*/
|
||||
for (BigSurd term : terms) {
|
||||
for (final BigSurd term : terms) {
|
||||
if (term.compareTo(BigSurd.ZERO) != 0) {
|
||||
sum.terms.add(term);
|
||||
}
|
||||
}
|
||||
for (BigSurd term : val.terms) {
|
||||
for (final BigSurd term : val.terms) {
|
||||
if (term.compareTo(BigSurd.ZERO) != 0) {
|
||||
sum.terms.add(term);
|
||||
}
|
||||
@ -338,7 +350,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @throws Error
|
||||
*/
|
||||
public BigSurdVec add(final BigSurd val) throws Error {
|
||||
BigSurdVec sum = new BigSurdVec();
|
||||
final BigSurdVec sum = new BigSurdVec();
|
||||
/*
|
||||
* concatenate the vectors and eliminate common overlaps
|
||||
*/
|
||||
@ -357,13 +369,14 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @throws Error
|
||||
*/
|
||||
public BigSurdVec subtract(final BigSurdVec val) throws Error {
|
||||
BigSurdVec sum = new BigSurdVec();
|
||||
final BigSurdVec sum = new BigSurdVec();
|
||||
/*
|
||||
* concatenate the vectors and eliminate common overlaps
|
||||
*/
|
||||
sum.terms.addAll(terms);
|
||||
for (BigSurd s : val.terms)
|
||||
for (final BigSurd s : val.terms) {
|
||||
sum.terms.add(s.negate());
|
||||
}
|
||||
sum.normalize();
|
||||
return sum;
|
||||
} /* subtract */
|
||||
@ -377,7 +390,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @throws Error
|
||||
*/
|
||||
public BigSurdVec subtract(final BigSurd val) throws Error {
|
||||
BigSurdVec sum = new BigSurdVec();
|
||||
final BigSurdVec sum = new BigSurdVec();
|
||||
/*
|
||||
* concatenate the vectors and eliminate common overlaps
|
||||
*/
|
||||
@ -397,9 +410,10 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
/*
|
||||
* accumulate the negated elements of term one by one
|
||||
*/
|
||||
BigSurdVec resul = new BigSurdVec();
|
||||
for (BigSurd s : terms)
|
||||
final BigSurdVec resul = new BigSurdVec();
|
||||
for (final BigSurd s : terms) {
|
||||
resul.terms.add(s.negate());
|
||||
}
|
||||
/*
|
||||
* no normalization step here, because the negation of all terms does
|
||||
* not introduce new common factors
|
||||
@ -419,12 +433,15 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* Binomial expansion. First the sum of the terms squared, then 2 times
|
||||
* the mixed products.
|
||||
*/
|
||||
BigSurdVec resul = new BigSurdVec();
|
||||
for (int i = 0; i < terms.size(); i++)
|
||||
final BigSurdVec resul = new BigSurdVec();
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
resul.terms.add(new BigSurd(terms.elementAt(i).sqr(), Rational.ONE));
|
||||
for (int i = 0; i < terms.size() - 1; i++)
|
||||
for (int j = i + 1; j < terms.size(); j++)
|
||||
}
|
||||
for (int i = 0; i < terms.size() - 1; i++) {
|
||||
for (int j = i + 1; j < terms.size(); j++) {
|
||||
resul.terms.add(terms.elementAt(i).multiply(terms.elementAt(j)).multiply(2));
|
||||
}
|
||||
}
|
||||
resul.normalize();
|
||||
return resul;
|
||||
} /* sqr */
|
||||
@ -439,28 +456,30 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurdVec multiply(final BigSurd val) throws Error {
|
||||
BigSurdVec resul = new BigSurdVec();
|
||||
for (BigSurd s : terms)
|
||||
final BigSurdVec resul = new BigSurdVec();
|
||||
for (final BigSurd s : terms) {
|
||||
resul.terms.add(s.multiply(val));
|
||||
}
|
||||
resul.normalize();
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
public BigSurdVec multiply(final BigSurdVec val) throws Error {
|
||||
BigSurdVec resul = new BigSurdVec();
|
||||
for (BigSurd s : terms) {
|
||||
for (final BigSurd s : terms) {
|
||||
resul.terms.add(s);
|
||||
}
|
||||
for (BigSurd s : val.terms) {
|
||||
for (final BigSurd s : val.terms) {
|
||||
resul = resul.multiply(s);
|
||||
}
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
public BigSurdVec divide(final BigSurd val) throws Error {
|
||||
BigSurdVec resul = new BigSurdVec();
|
||||
for (BigSurd s : terms)
|
||||
final BigSurdVec resul = new BigSurdVec();
|
||||
for (final BigSurd s : terms) {
|
||||
resul.terms.add(s.divide(val));
|
||||
}
|
||||
resul.normalize();
|
||||
return resul;
|
||||
} /* multiply */
|
||||
@ -468,7 +487,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
public BigSurdVec divide(final BigSurdVec val) throws Error {
|
||||
BigSurdVec resul = new BigSurdVec();
|
||||
resul.terms = terms;
|
||||
for (BigSurd s : val.terms) {
|
||||
for (final BigSurd s : val.terms) {
|
||||
resul = resul.divide(s);
|
||||
}
|
||||
return resul;
|
||||
@ -482,7 +501,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
*/
|
||||
public boolean isRational() {
|
||||
boolean val = false;
|
||||
for (BigSurd s : terms) {
|
||||
for (final BigSurd s : terms) {
|
||||
val = s.isRational();
|
||||
if (val == false) {
|
||||
break;
|
||||
@ -499,7 +518,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
*/
|
||||
public boolean isBigInteger() {
|
||||
boolean val = false;
|
||||
for (BigSurd s : terms) {
|
||||
for (final BigSurd s : terms) {
|
||||
val = s.isBigInteger();
|
||||
if (val == false) {
|
||||
break;
|
||||
@ -515,9 +534,10 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
*/
|
||||
public Rational toRational() {
|
||||
Rational rat = Rational.ZERO;
|
||||
if (isRational() == false)
|
||||
if (isRational() == false) {
|
||||
throw new ArithmeticException("Undefined conversion " + toString() + " to Rational.");
|
||||
for (BigSurd s : terms) {
|
||||
}
|
||||
for (final BigSurd s : terms) {
|
||||
rat = rat.add(s.pref);
|
||||
}
|
||||
return rat;
|
||||
@ -530,9 +550,10 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
*/
|
||||
public BigInteger toBigInteger() {
|
||||
BigDecimal tmp = BigDecimal.ZERO.setScale(Utils.scale, Utils.scaleMode);
|
||||
if (isBigInteger() == false)
|
||||
if (isBigInteger() == false) {
|
||||
throw new ArithmeticException("Undefined conversion " + toString() + " to Rational.");
|
||||
for (BigSurd s : terms) {
|
||||
}
|
||||
for (final BigSurd s : terms) {
|
||||
tmp = BigDecimalMath.addRound(tmp, s.pref.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)));
|
||||
}
|
||||
return tmp.toBigInteger();
|
||||
@ -545,7 +566,7 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
*/
|
||||
public BigDecimal toBigDecimal() {
|
||||
BigDecimal tmp = BigDecimal.ZERO.setScale(Utils.scale, Utils.scaleMode);
|
||||
for (BigSurd s : terms) {
|
||||
for (final BigSurd s : terms) {
|
||||
tmp = BigDecimalMath.addRound(tmp, s.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)));
|
||||
}
|
||||
return tmp;
|
||||
@ -563,14 +584,15 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
/*
|
||||
* simple cases with one term forwarded to the BigSurd class
|
||||
*/
|
||||
if (terms.size() == 0)
|
||||
if (terms.size() == 0) {
|
||||
return new String("0");
|
||||
else {
|
||||
} else {
|
||||
String s = new String();
|
||||
for (int t = 0; t < terms.size(); t++) {
|
||||
BigSurd bs = terms.elementAt(t);
|
||||
if (bs.signum() > 0)
|
||||
final BigSurd bs = terms.elementAt(t);
|
||||
if (bs.signum() > 0) {
|
||||
s += "+";
|
||||
}
|
||||
s += bs.toString();
|
||||
}
|
||||
return s;
|
||||
@ -578,9 +600,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
} /* toString */
|
||||
|
||||
public String toFancyString() {
|
||||
if (terms.size() == 0)
|
||||
if (terms.size() == 0) {
|
||||
return new String("0");
|
||||
else {
|
||||
} else {
|
||||
BigInteger denominator = BigInteger.ONE;
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
denominator = denominator.multiply(terms.elementAt(i).pref.b);
|
||||
@ -590,15 +612,16 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
s += "(";
|
||||
}
|
||||
for (int t = 0; t < terms.size(); t++) {
|
||||
BigSurd bs = terms.elementAt(t);
|
||||
if (bs.signum() > 0 && t > 0)
|
||||
final BigSurd bs = terms.elementAt(t);
|
||||
if (bs.signum() > 0 && t > 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.multiply(denominator).numer();
|
||||
final BigInteger numerator = bs.pref.multiply(denominator).numer();
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += numerator.toString();
|
||||
s += "*";
|
||||
|
@ -38,20 +38,22 @@ public class Euler {
|
||||
while (n >= a.size()) {
|
||||
BigInteger val = BigInteger.ZERO;
|
||||
boolean sigPos = true;
|
||||
int thisn = a.size();
|
||||
final 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)
|
||||
if (sigPos) {
|
||||
val = val.add(f);
|
||||
else
|
||||
} else {
|
||||
val = val.subtract(f);
|
||||
}
|
||||
sigPos = !sigPos;
|
||||
}
|
||||
if (thisn % 2 == 0)
|
||||
if (thisn % 2 == 0) {
|
||||
val = val.subtract(BigInteger.ONE);
|
||||
else
|
||||
} else {
|
||||
val = val.add(BigInteger.ONE);
|
||||
}
|
||||
a.add(val);
|
||||
}
|
||||
}
|
||||
|
@ -36,16 +36,18 @@ public class EulerPhi {
|
||||
* @return phi(n)
|
||||
*/
|
||||
public BigInteger at(BigInteger n) {
|
||||
if (n.compareTo(BigInteger.ZERO) <= 0)
|
||||
if (n.compareTo(BigInteger.ZERO) <= 0) {
|
||||
throw new ArithmeticException("negative argument " + n + " of EulerPhi");
|
||||
Ifactor prFact = new Ifactor(n);
|
||||
}
|
||||
final Ifactor prFact = new Ifactor(n);
|
||||
BigInteger phi = n;
|
||||
if (n.compareTo(BigInteger.ONE) > 0)
|
||||
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);
|
||||
final BigInteger p = new BigInteger(prFact.primeexp.elementAt(i).toString());
|
||||
final BigInteger p_1 = p.subtract(BigInteger.ONE);
|
||||
phi = phi.multiply(p_1).divide(p);
|
||||
}
|
||||
}
|
||||
return phi;
|
||||
} /* at */
|
||||
|
||||
@ -57,8 +59,8 @@ public class EulerPhi {
|
||||
* @since 2006-08-14
|
||||
*/
|
||||
public static void main(String[] args) throws ArithmeticException {
|
||||
EulerPhi a = new EulerPhi();
|
||||
int n = (new Integer(args[0])).intValue();
|
||||
final EulerPhi a = new EulerPhi();
|
||||
final int n = (new Integer(args[0])).intValue();
|
||||
System.out.println("phi(" + n + ") = " + a.at(n));
|
||||
}
|
||||
} /* EulerPhi */
|
||||
|
@ -23,9 +23,9 @@ public class Harmonic {
|
||||
* For values of n less than 1, zero is returned.
|
||||
*/
|
||||
public Rational at(int n) {
|
||||
if (n < 1)
|
||||
if (n < 1) {
|
||||
return (new Rational(0, 1));
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* start with 1 as the result
|
||||
*/
|
||||
@ -34,8 +34,9 @@ public class Harmonic {
|
||||
/*
|
||||
* add 1/i for i=2..n
|
||||
*/
|
||||
for (int i = 2; i <= n; i++)
|
||||
for (int i = 2; i <= n; i++) {
|
||||
a = a.add(new Rational(1, i));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
primeexp = new Vector<>();
|
||||
if (number > 1) {
|
||||
int primindx = 0;
|
||||
Prime primes = new Prime();
|
||||
final Prime primes = new Prime();
|
||||
/*
|
||||
* Test division against all primes.
|
||||
*/
|
||||
@ -57,12 +57,13 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
/*
|
||||
* primindx=0 refers to 2, =1 to 3, =2 to 5, =3 to 7 etc
|
||||
*/
|
||||
int p = primes.at(primindx).intValue();
|
||||
final int p = primes.at(primindx).intValue();
|
||||
while (number % p == 0) {
|
||||
ex++;
|
||||
number /= p;
|
||||
if (number == 1)
|
||||
if (number == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ex > 0) {
|
||||
primeexp.add(new Integer(p));
|
||||
@ -92,18 +93,19 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
primeexp.add(new Integer(0));
|
||||
} else {
|
||||
int primindx = 0;
|
||||
Prime primes = new Prime();
|
||||
final Prime primes = new Prime();
|
||||
/*
|
||||
* Test for division against all primes.
|
||||
*/
|
||||
while (number.compareTo(BigInteger.ONE) == 1) {
|
||||
int ex = 0;
|
||||
BigInteger p = primes.at(primindx);
|
||||
final BigInteger p = primes.at(primindx);
|
||||
while (number.remainder(p).compareTo(BigInteger.ZERO) == 0) {
|
||||
ex++;
|
||||
number = number.divide(p);
|
||||
if (number.compareTo(BigInteger.ONE) == 0)
|
||||
if (number.compareTo(BigInteger.ONE) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ex > 0) {
|
||||
primeexp.add(new Integer(p.intValue()));
|
||||
@ -128,19 +130,20 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
primeexp = new Vector<>(2 * pows.size());
|
||||
if (pows.size() > 0) {
|
||||
n = BigInteger.ONE;
|
||||
Prime primes = new Prime();
|
||||
final Prime primes = new Prime();
|
||||
/*
|
||||
* Build the full number by the product of all powers of the primes.
|
||||
*/
|
||||
for (int primindx = 0; primindx < pows.size(); primindx++) {
|
||||
int ex = pows.elementAt(primindx).intValue();
|
||||
final int ex = pows.elementAt(primindx).intValue();
|
||||
final BigInteger p = primes.at(primindx);
|
||||
n = n.multiply(p.pow(ex));
|
||||
primeexp.add(new Integer(p.intValue()));
|
||||
primeexp.add(new Integer(ex));
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
n = BigInteger.ZERO;
|
||||
}
|
||||
} /* Ifactor */
|
||||
|
||||
/**
|
||||
@ -167,7 +170,7 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* Vector<Integer> p = (Vector<Integer>)primeexp.clone();
|
||||
*
|
||||
*/
|
||||
Ifactor cl = new Ifactor(0);
|
||||
final Ifactor cl = new Ifactor(0);
|
||||
cl.n = new BigInteger("" + n);
|
||||
return cl;
|
||||
} /* Ifactor.clone */
|
||||
@ -267,7 +270,7 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* @return the product, gcd or lcm of both numbers.
|
||||
*/
|
||||
protected Ifactor multGcdLcm(final Ifactor oth, int type) {
|
||||
Ifactor prod = new Ifactor(0);
|
||||
final Ifactor prod = new Ifactor(0);
|
||||
/*
|
||||
* skip the case where 0*something =0, falling thru to the empty
|
||||
* representation for 0
|
||||
@ -278,19 +281,19 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* Cases of lcm(1, something) return something.
|
||||
* Cases of gcd(1, something) return 1.
|
||||
*/
|
||||
if (primeexp.firstElement().intValue() == 1 && type == 0)
|
||||
if (primeexp.firstElement().intValue() == 1 && type == 0) {
|
||||
return oth;
|
||||
else if (primeexp.firstElement().intValue() == 1 && type == 2)
|
||||
} else if (primeexp.firstElement().intValue() == 1 && type == 2) {
|
||||
return oth;
|
||||
else if (primeexp.firstElement().intValue() == 1 && type == 1)
|
||||
} else if (primeexp.firstElement().intValue() == 1 && type == 1) {
|
||||
return this;
|
||||
else if (oth.primeexp.firstElement().intValue() == 1 && type == 0)
|
||||
} else if (oth.primeexp.firstElement().intValue() == 1 && type == 0) {
|
||||
return this;
|
||||
else if (oth.primeexp.firstElement().intValue() == 1 && type == 2)
|
||||
} else if (oth.primeexp.firstElement().intValue() == 1 && type == 2) {
|
||||
return this;
|
||||
else if (oth.primeexp.firstElement().intValue() == 1 && type == 1)
|
||||
} else if (oth.primeexp.firstElement().intValue() == 1 && type == 1) {
|
||||
return oth;
|
||||
else {
|
||||
} else {
|
||||
int idxThis = 0;
|
||||
int idxOth = 0;
|
||||
switch (type) {
|
||||
@ -417,10 +420,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
/*
|
||||
* avoid refactorization if oth is zero...
|
||||
*/
|
||||
if (oth.compareTo(BigInteger.ZERO) != 0)
|
||||
if (oth.compareTo(BigInteger.ZERO) != 0) {
|
||||
return new Ifactor(n.add(oth));
|
||||
else
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
} /* Ifactor.add */
|
||||
|
||||
/**
|
||||
@ -434,22 +438,23 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
/*
|
||||
* three simple cases first
|
||||
*/
|
||||
if (exponent < 0)
|
||||
if (exponent < 0) {
|
||||
throw new ArithmeticException("Cannot raise " + toString() + " to negative " + exponent);
|
||||
else if (exponent == 0)
|
||||
} else if (exponent == 0) {
|
||||
return new Ifactor(1);
|
||||
else if (exponent == 1)
|
||||
} else if (exponent == 1) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* general case, the vector with the prime factor powers, which are
|
||||
* component-wise
|
||||
* exponentiation of the individual prime factor powers.
|
||||
*/
|
||||
Ifactor pows = new Ifactor(0);
|
||||
final Ifactor pows = new Ifactor(0);
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
Integer p = primeexp.elementAt(i);
|
||||
int ex = primeexp.elementAt(i + 1).intValue();
|
||||
final Integer p = primeexp.elementAt(i);
|
||||
final int ex = primeexp.elementAt(i + 1).intValue();
|
||||
pows.primeexp.add(p);
|
||||
pows.primeexp.add(new Integer(ex * exponent));
|
||||
}
|
||||
@ -469,24 +474,25 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
public Rational root(final int r) throws ArithmeticException, Error {
|
||||
if (r == 0)
|
||||
if (r == 0) {
|
||||
throw new ArithmeticException("Cannot pull zeroth root of " + toString());
|
||||
else if (r < 0) {
|
||||
} else if (r < 0) {
|
||||
/*
|
||||
* a^(-1/b)= 1/(a^(1/b))
|
||||
*/
|
||||
final Rational invRoot = root(-r);
|
||||
return Rational.ONE.divide(invRoot);
|
||||
} else {
|
||||
BigInteger pows = BigInteger.ONE;
|
||||
final BigInteger pows = BigInteger.ONE;
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
/*
|
||||
* all exponents must be multiples of r to succeed (that is, to
|
||||
* stay in the range of rational results).
|
||||
*/
|
||||
int ex = primeexp.elementAt(i + 1).intValue();
|
||||
if (ex % r != 0)
|
||||
final int ex = primeexp.elementAt(i + 1).intValue();
|
||||
if (ex % r != 0) {
|
||||
throw new ArithmeticException("Cannot pull " + r + "th root of " + toString());
|
||||
}
|
||||
|
||||
pows.multiply(new BigInteger("" + primeexp.elementAt(i)).pow(ex / r));
|
||||
}
|
||||
@ -512,18 +518,19 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* multiplied
|
||||
* by 1 or by a product that contains the factors p1..py.
|
||||
*/
|
||||
Vector<BigInteger> d = new Vector<>();
|
||||
if (n.compareTo(BigInteger.ZERO) == 0)
|
||||
final Vector<BigInteger> d = new Vector<>();
|
||||
if (n.compareTo(BigInteger.ZERO) == 0) {
|
||||
return d;
|
||||
}
|
||||
d.add(BigInteger.ONE);
|
||||
if (n.compareTo(BigInteger.ONE) > 0) {
|
||||
/* Computes sigmaIncopml(p1^e*p2^e2...*py^ey) */
|
||||
Ifactor dp = dropPrime();
|
||||
final Ifactor dp = dropPrime();
|
||||
|
||||
/* get ez */
|
||||
final int ez = primeexp.lastElement().intValue();
|
||||
|
||||
Vector<BigInteger> partd = dp.divisors();
|
||||
final Vector<BigInteger> partd = dp.divisors();
|
||||
|
||||
/* obtain pz by lookup in the prime list */
|
||||
final BigInteger pz = new BigInteger(primeexp.elementAt(primeexp.size() - 2).toString());
|
||||
@ -532,12 +539,14 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* the output contains all products of the form partd[]*pz^ez, ez>0,
|
||||
* and with the exception of the 1, all these are appended.
|
||||
*/
|
||||
for (int i = 1; i < partd.size(); i++)
|
||||
for (int i = 1; i < partd.size(); i++) {
|
||||
d.add(partd.elementAt(i));
|
||||
}
|
||||
for (int e = 1; e <= ez; e++) {
|
||||
final BigInteger pzez = pz.pow(e);
|
||||
for (int i = 0; i < partd.size(); i++)
|
||||
for (int i = 0; i < partd.size(); i++) {
|
||||
d.add(partd.elementAt(i).multiply(pzez));
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(d);
|
||||
@ -563,29 +572,29 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* the question is whether keeping a factorization is worth the effort
|
||||
* or whether one should simply multiply these to return a BigInteger...
|
||||
*/
|
||||
if (n.compareTo(BigInteger.ONE) == 0)
|
||||
if (n.compareTo(BigInteger.ONE) == 0) {
|
||||
return ONE;
|
||||
else if (n.compareTo(BigInteger.ZERO) == 0)
|
||||
} else if (n.compareTo(BigInteger.ZERO) == 0) {
|
||||
return ZERO;
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* multiplicative: sigma_k(p^e) = [p^(k*(e+1))-1]/[p^k-1]
|
||||
* sigma_0(p^e) = e+1.
|
||||
*/
|
||||
Ifactor resul = Ifactor.ONE;
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
int ex = primeexp.elementAt(i + 1).intValue();
|
||||
if (k == 0)
|
||||
final int ex = primeexp.elementAt(i + 1).intValue();
|
||||
if (k == 0) {
|
||||
resul = resul.multiply(ex + 1);
|
||||
else {
|
||||
Integer p = primeexp.elementAt(i);
|
||||
BigInteger num = (new BigInteger(p.toString())).pow(k * (ex + 1)).subtract(BigInteger.ONE);
|
||||
BigInteger deno = (new BigInteger(p.toString())).pow(k).subtract(BigInteger.ONE);
|
||||
} else {
|
||||
final Integer p = primeexp.elementAt(i);
|
||||
final BigInteger num = (new BigInteger(p.toString())).pow(k * (ex + 1)).subtract(BigInteger.ONE);
|
||||
final BigInteger deno = (new BigInteger(p.toString())).pow(k).subtract(BigInteger.ONE);
|
||||
/*
|
||||
* This division is of course exact, no remainder
|
||||
* The costly prime factorization is hidden here.
|
||||
*/
|
||||
Ifactor f = new Ifactor(num.divide(deno));
|
||||
final Ifactor f = new Ifactor(num.divide(deno));
|
||||
resul = resul.multiply(f);
|
||||
}
|
||||
}
|
||||
@ -608,8 +617,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
/*
|
||||
* the cases n==1 or n ==0
|
||||
*/
|
||||
if (n.compareTo(BigInteger.ONE) <= 0)
|
||||
if (n.compareTo(BigInteger.ONE) <= 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* The cases n>1
|
||||
@ -617,13 +627,13 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* the vector with the new prime factor powers, which contain the
|
||||
* old prime factor powers up to but not including the last one.
|
||||
*/
|
||||
Ifactor pows = new Ifactor(0);
|
||||
final Ifactor pows = new Ifactor(0);
|
||||
pows.n = BigInteger.ONE;
|
||||
for (int i = 0; i < primeexp.size() - 2; i += 2) {
|
||||
pows.primeexp.add(primeexp.elementAt(i));
|
||||
pows.primeexp.add(primeexp.elementAt(i + 1));
|
||||
BigInteger p = new BigInteger(primeexp.elementAt(i).toString());
|
||||
int ex = primeexp.elementAt(i + 1).intValue();
|
||||
final BigInteger p = new BigInteger(primeexp.elementAt(i).toString());
|
||||
final int ex = primeexp.elementAt(i + 1).intValue();
|
||||
pows.n = pows.n.multiply(p.pow(ex));
|
||||
}
|
||||
return pows;
|
||||
@ -639,8 +649,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* check the exponents, located at the odd-indexed positions
|
||||
*/
|
||||
for (int i = 1; i < primeexp.size(); i += 2) {
|
||||
if (primeexp.elementAt(i).intValue() % 2 != 0)
|
||||
if (primeexp.elementAt(i).intValue() % 2 != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} /* Ifactor.issquare */
|
||||
@ -652,8 +663,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
*/
|
||||
public int bigomega() {
|
||||
int resul = 0;
|
||||
for (int i = 1; i < primeexp.size(); i += 2)
|
||||
for (int i = 1; i < primeexp.size(); i += 2) {
|
||||
resul += primeexp.elementAt(i).intValue();
|
||||
}
|
||||
return (resul);
|
||||
} /* Ifactor.bigomega */
|
||||
|
||||
@ -675,9 +687,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
*/
|
||||
public BigInteger core() {
|
||||
BigInteger resul = BigInteger.ONE;
|
||||
for (int i = 0; i < primeexp.size(); i += 2)
|
||||
if (primeexp.elementAt(i + 1).intValue() % 2 != 0)
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
if (primeexp.elementAt(i + 1).intValue() % 2 != 0) {
|
||||
resul = resul.multiply(new BigInteger(primeexp.elementAt(i).toString()));
|
||||
}
|
||||
}
|
||||
return resul;
|
||||
} /* Ifactor.core */
|
||||
|
||||
@ -690,17 +704,19 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* @return the moebius function.
|
||||
*/
|
||||
public int moebius() {
|
||||
if (n.compareTo(BigInteger.ONE) <= 0)
|
||||
if (n.compareTo(BigInteger.ONE) <= 0) {
|
||||
return 1;
|
||||
}
|
||||
/* accumulate number of different primes in k */
|
||||
int k = 1;
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
final int e = primeexp.elementAt(i + 1).intValue();
|
||||
if (e > 1)
|
||||
if (e > 1) {
|
||||
return 0;
|
||||
else if (e == 1)
|
||||
} else if (e == 1) {
|
||||
/* accumulates (-1)^k */
|
||||
k *= -1;
|
||||
}
|
||||
|
||||
}
|
||||
return (k);
|
||||
@ -714,10 +730,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* @return the larger of the two values.
|
||||
*/
|
||||
public Ifactor max(final Ifactor oth) {
|
||||
if (n.compareTo(oth.n) >= 0)
|
||||
if (n.compareTo(oth.n) >= 0) {
|
||||
return this;
|
||||
else
|
||||
} else {
|
||||
return oth;
|
||||
}
|
||||
} /* Ifactor.max */
|
||||
|
||||
/**
|
||||
@ -728,10 +745,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* @return the smaller of the two values.
|
||||
*/
|
||||
public Ifactor min(final Ifactor oth) {
|
||||
if (n.compareTo(oth.n) <= 0)
|
||||
if (n.compareTo(oth.n) <= 0) {
|
||||
return this;
|
||||
else
|
||||
} else {
|
||||
return oth;
|
||||
}
|
||||
} /* Ifactor.min */
|
||||
|
||||
/**
|
||||
@ -743,8 +761,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
*/
|
||||
public static Ifactor max(final Vector<Ifactor> set) {
|
||||
Ifactor resul = set.elementAt(0);
|
||||
for (int i = 1; i < set.size(); i++)
|
||||
for (int i = 1; i < set.size(); i++) {
|
||||
resul = resul.max(set.elementAt(i));
|
||||
}
|
||||
return resul;
|
||||
} /* Ifactor.max */
|
||||
|
||||
@ -757,8 +776,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
*/
|
||||
public static Ifactor min(final Vector<Ifactor> set) {
|
||||
Ifactor resul = set.elementAt(0);
|
||||
for (int i = 1; i < set.size(); i++)
|
||||
for (int i = 1; i < set.size(); i++) {
|
||||
resul = resul.min(set.elementAt(i));
|
||||
}
|
||||
return resul;
|
||||
} /* Ifactor.min */
|
||||
|
||||
@ -784,17 +804,19 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
@Override
|
||||
public String toString() {
|
||||
String resul = new String(n.toString() + ":");
|
||||
if (n.compareTo(BigInteger.ONE) == 0)
|
||||
if (n.compareTo(BigInteger.ONE) == 0) {
|
||||
resul += "1";
|
||||
else {
|
||||
} else {
|
||||
boolean firstMul = true;
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
if (!firstMul)
|
||||
if (!firstMul) {
|
||||
resul += "*";
|
||||
if (primeexp.elementAt(i + 1).intValue() > 1)
|
||||
}
|
||||
if (primeexp.elementAt(i + 1).intValue() > 1) {
|
||||
resul += primeexp.elementAt(i).toString() + "^" + primeexp.elementAt(i + 1).toString();
|
||||
else
|
||||
} else {
|
||||
resul += primeexp.elementAt(i).toString();
|
||||
}
|
||||
firstMul = false;
|
||||
}
|
||||
}
|
||||
@ -807,7 +829,7 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
* java -cp . org.nevec.rjm.Ifactor n<br>
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
BigInteger n = new BigInteger(args[0]);
|
||||
final BigInteger n = new BigInteger(args[0]);
|
||||
System.out.println(new Ifactor(n));
|
||||
} /* Ifactor.main */
|
||||
} /* Ifactor */
|
||||
|
@ -63,9 +63,9 @@ public class PartitionsP {
|
||||
private void growto(BigInteger n) {
|
||||
while (a.size() <= n.intValue()) {
|
||||
BigInteger per = new BigInteger("0");
|
||||
BigInteger cursiz = new BigInteger("" + a.size());
|
||||
final 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));
|
||||
final BigInteger tmp = a.elementAt(k).multiply(BigIntegerMath.sigma(a.size() - k));
|
||||
per = per.add(tmp);
|
||||
}
|
||||
a.add(per.divide(cursiz));
|
||||
@ -81,8 +81,8 @@ public class PartitionsP {
|
||||
* @since 2008-10-15
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
PartitionsP a = new PartitionsP();
|
||||
int n = (new Integer(args[0])).intValue();
|
||||
final PartitionsP a = new PartitionsP();
|
||||
final int n = (new Integer(args[0])).intValue();
|
||||
System.out.println("P(" + n + ")=" + a.at(n));
|
||||
}
|
||||
}
|
||||
|
@ -86,38 +86,34 @@ public class Prime {
|
||||
/*
|
||||
* numbers less than 2 are not prime
|
||||
*/
|
||||
if (n.compareTo(two) == -1)
|
||||
if (n.compareTo(two) == -1) {
|
||||
return false;
|
||||
/*
|
||||
* 2 is prime
|
||||
*/
|
||||
else if (n.compareTo(two) == 0)
|
||||
} else if (n.compareTo(two) == 0) {
|
||||
return true;
|
||||
/*
|
||||
* even numbers >2 are not prime
|
||||
*/
|
||||
else if (n.remainder(two).compareTo(BigInteger.ZERO) == 0)
|
||||
} else if (n.remainder(two).compareTo(BigInteger.ZERO) == 0) {
|
||||
return false;
|
||||
else {
|
||||
} 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);
|
||||
final int s = q.getLowestSetBit();
|
||||
final BigInteger d = q.shiftRight(s);
|
||||
|
||||
/*
|
||||
* test whether a^d = 1 (mod n)
|
||||
*/
|
||||
if (a.modPow(d, n).compareTo(BigInteger.ONE) == 0)
|
||||
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)
|
||||
if (a.modPow(d.shiftLeft(r), n).compareTo(q) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -140,28 +136,29 @@ public class Prime {
|
||||
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)
|
||||
final 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)
|
||||
} else if (l == 0) {
|
||||
return -1;
|
||||
}
|
||||
mrLim++;
|
||||
}
|
||||
/*
|
||||
* cannot test candidates larger than the last in the mr list
|
||||
*/
|
||||
if (mrLim == mr.length)
|
||||
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)
|
||||
for (int p = 0; p <= mrLim; p++) {
|
||||
if (isSPP(n, at(p)) == false) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -197,9 +194,11 @@ public class Prime {
|
||||
*/
|
||||
growto(n);
|
||||
BigInteger r = new BigInteger("0");
|
||||
for (int i = 0; i < a.size(); i++)
|
||||
if (a.elementAt(i).compareTo(n) <= 0)
|
||||
for (int i = 0; i < a.size(); i++) {
|
||||
if (a.elementAt(i).compareTo(n) <= 0) {
|
||||
r = r.add(BigInteger.ONE);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -213,8 +212,9 @@ public class Prime {
|
||||
*/
|
||||
public BigInteger nextprime(BigInteger n) {
|
||||
/* if n <=1, return 2 */
|
||||
if (n.compareTo(BigInteger.ONE) <= 0)
|
||||
if (n.compareTo(BigInteger.ONE) <= 0) {
|
||||
return (a.elementAt(0));
|
||||
}
|
||||
|
||||
/*
|
||||
* If the currently largest element in the list is too small, increase
|
||||
@ -224,9 +224,11 @@ public class Prime {
|
||||
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)
|
||||
for (int i = 0; i < a.size(); i++) {
|
||||
if (a.elementAt(i).compareTo(n) == 1) {
|
||||
return (a.elementAt(i));
|
||||
}
|
||||
}
|
||||
return (a.lastElement());
|
||||
}
|
||||
|
||||
@ -240,20 +242,24 @@ public class Prime {
|
||||
*/
|
||||
public BigInteger prevprime(BigInteger n) {
|
||||
/* if n <=2, return 0 */
|
||||
if (n.compareTo(BigInteger.ONE) <= 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)
|
||||
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)
|
||||
for (int i = 0; i < a.size(); i++) {
|
||||
if (a.elementAt(i).compareTo(n) >= 0) {
|
||||
return (a.elementAt(i - 1));
|
||||
}
|
||||
}
|
||||
return (a.lastElement());
|
||||
}
|
||||
|
||||
@ -272,8 +278,9 @@ public class Prime {
|
||||
/*
|
||||
* Test the list of known primes only up to sqrt(n)
|
||||
*/
|
||||
if (a.get(p).multiply(a.get(p)).compareTo(nMax) == 1)
|
||||
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
|
||||
@ -285,8 +292,9 @@ public class Prime {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isp)
|
||||
if (isp) {
|
||||
a.add(nMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,11 +307,12 @@ public class Prime {
|
||||
* @since 2006-08-14
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
Prime a = new Prime();
|
||||
int n = (new Integer(args[0])).intValue();
|
||||
final Prime a = new Prime();
|
||||
final int n = (new Integer(args[0])).intValue();
|
||||
if (n >= 1) {
|
||||
if (n >= 2)
|
||||
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)));
|
||||
|
@ -43,8 +43,9 @@ class RatPoly {
|
||||
*/
|
||||
public RatPoly(final Vector<Rational> L) {
|
||||
a = new Vector<>();
|
||||
for (int i = 0; i < L.size(); i++)
|
||||
for (int i = 0; i < L.size(); i++) {
|
||||
a.add(L.elementAt(i).clone());
|
||||
}
|
||||
simplify();
|
||||
} /* ctor */
|
||||
|
||||
@ -56,10 +57,10 @@ class RatPoly {
|
||||
*/
|
||||
public RatPoly(final String L) throws NumberFormatException {
|
||||
a = new Vector<>();
|
||||
Scanner sc = new Scanner(L);
|
||||
final Scanner sc = new Scanner(L);
|
||||
sc.useDelimiter(",");
|
||||
while (sc.hasNext()) {
|
||||
String tok = sc.next();
|
||||
final String tok = sc.next();
|
||||
a.add(new Rational(tok));
|
||||
}
|
||||
simplify();
|
||||
@ -103,16 +104,18 @@ class RatPoly {
|
||||
BigInteger Nmax = BigInteger.ONE.negate();
|
||||
for (int j = 0; j < A.size(); j++) {
|
||||
if (A.elementAt(j).compareTo(BigInteger.ZERO) <= 0) {
|
||||
if (Nmax.compareTo(BigInteger.ZERO) < 0)
|
||||
if (Nmax.compareTo(BigInteger.ZERO) < 0) {
|
||||
Nmax = A.elementAt(j).negate();
|
||||
else
|
||||
} else {
|
||||
Nmax = Nmax.min(A.elementAt(j).negate());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Nmax.compareTo(BigInteger.ZERO) < 0)
|
||||
if (Nmax.compareTo(BigInteger.ZERO) < 0) {
|
||||
throw new ArithmeticException("Infinite Number of Terms in Series " + Nmax.toString());
|
||||
}
|
||||
|
||||
int nmax = Nmax.intValue() - 1;
|
||||
final int nmax = Nmax.intValue() - 1;
|
||||
init(A, B, nmax);
|
||||
} /* ctor */
|
||||
|
||||
@ -130,15 +133,15 @@ class RatPoly {
|
||||
*/
|
||||
protected void init(final Vector<BigInteger> A, final Vector<BigInteger> B, int nmax) throws Error {
|
||||
a = new Vector<>();
|
||||
Factorial f = new Factorial();
|
||||
final Factorial f = new Factorial();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
Rational c = new Rational(1, 1);
|
||||
for (int j = 0; j < A.size(); j++) {
|
||||
Rational aEl = new Rational(A.elementAt(j));
|
||||
final Rational aEl = new Rational(A.elementAt(j));
|
||||
c = c.multiply(aEl.Pochhammer(n));
|
||||
}
|
||||
for (int j = 0; j < B.size(); j++) {
|
||||
Rational bEl = new Rational(B.elementAt(j));
|
||||
final Rational bEl = new Rational(B.elementAt(j));
|
||||
c = c.divide(bEl.Pochhammer(n));
|
||||
}
|
||||
c = c.divide(f.at(n));
|
||||
@ -155,7 +158,7 @@ class RatPoly {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public RatPoly clone() {
|
||||
RatPoly clo = new RatPoly();
|
||||
final RatPoly clo = new RatPoly();
|
||||
clo.a = (Vector<Rational>) a.clone();
|
||||
return clo;
|
||||
} /* clone */
|
||||
@ -169,10 +172,11 @@ class RatPoly {
|
||||
* @return the polynomial coefficient in front of x^n.
|
||||
*/
|
||||
public Rational at(final int n) {
|
||||
if (n < a.size())
|
||||
if (n < a.size()) {
|
||||
return (a.elementAt(n));
|
||||
else
|
||||
} else {
|
||||
return (new Rational(0, 1));
|
||||
}
|
||||
} /* at */
|
||||
|
||||
/**
|
||||
@ -187,8 +191,9 @@ class RatPoly {
|
||||
public BigComplex valueOf(BigComplex x, MathContext mc) {
|
||||
/* result is initialized to zero */
|
||||
BigComplex f = new BigComplex();
|
||||
for (int i = degree(); i >= 0; i--)
|
||||
for (int i = degree(); i >= 0; i--) {
|
||||
f = f.multiply(x, mc).add(a.elementAt(i).BigDecimalValue(mc));
|
||||
}
|
||||
return f;
|
||||
} /* valueOf */
|
||||
|
||||
@ -202,8 +207,9 @@ class RatPoly {
|
||||
public Rational valueOf(Rational x) {
|
||||
/* result is initialized to zero */
|
||||
Rational f = new Rational(0, 1);
|
||||
for (int i = degree(); i >= 0; i--)
|
||||
for (int i = degree(); i >= 0; i--) {
|
||||
f = f.multiply(x).add(a.elementAt(i));
|
||||
}
|
||||
return f;
|
||||
} /* valueOf */
|
||||
|
||||
@ -240,14 +246,15 @@ class RatPoly {
|
||||
* @param value the new value of the coefficient.
|
||||
*/
|
||||
public void set(final int n, final Rational value) {
|
||||
if (n < a.size())
|
||||
if (n < a.size()) {
|
||||
a.set(n, value);
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* fill intermediate powers with coefficients of zero
|
||||
*/
|
||||
while (a.size() < n)
|
||||
while (a.size() < n) {
|
||||
a.add(new Rational(0, 1));
|
||||
}
|
||||
a.add(value);
|
||||
}
|
||||
} /* set */
|
||||
@ -265,7 +272,7 @@ class RatPoly {
|
||||
* the new value of the coefficient.
|
||||
*/
|
||||
public void set(final int n, final BigInteger value) {
|
||||
Rational val2 = new Rational(value, BigInteger.ONE);
|
||||
final Rational val2 = new Rational(value, BigInteger.ONE);
|
||||
set(n, val2);
|
||||
} /* set */
|
||||
|
||||
@ -282,7 +289,7 @@ class RatPoly {
|
||||
* the new value of the coefficient.
|
||||
*/
|
||||
public void set(final int n, final int value) {
|
||||
Rational val2 = new Rational(value, 1);
|
||||
final Rational val2 = new Rational(value, 1);
|
||||
set(n, val2);
|
||||
} /* set */
|
||||
|
||||
@ -293,9 +300,10 @@ class RatPoly {
|
||||
*/
|
||||
public void setExp(final int nmax) {
|
||||
a.clear();
|
||||
Factorial factorial = new Factorial();
|
||||
for (int n = 0; n <= nmax; n++)
|
||||
final Factorial factorial = new Factorial();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
set(n, new Rational(BigInteger.ONE, factorial.at(n)));
|
||||
}
|
||||
} /* setExp */
|
||||
|
||||
/**
|
||||
@ -336,9 +344,11 @@ class RatPoly {
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public int ldegree() {
|
||||
for (int n = 0; n < a.size(); n++)
|
||||
if (a.elementAt(n).compareTo(BigInteger.ZERO) != 0)
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
if (a.elementAt(n).compareTo(BigInteger.ZERO) != 0) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} /* ldegree */
|
||||
|
||||
@ -352,10 +362,12 @@ class RatPoly {
|
||||
* factor.
|
||||
*/
|
||||
public RatPoly multiply(final Rational val) {
|
||||
RatPoly resul = new RatPoly();
|
||||
if (val.compareTo(BigInteger.ZERO) != 0)
|
||||
for (int n = 0; n < a.size(); n++)
|
||||
final RatPoly resul = new RatPoly();
|
||||
if (val.compareTo(BigInteger.ZERO) != 0) {
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
resul.set(n, a.elementAt(n).multiply(val));
|
||||
}
|
||||
}
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
@ -370,10 +382,12 @@ class RatPoly {
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public RatPoly multiply(final BigInteger val) {
|
||||
RatPoly resul = new RatPoly();
|
||||
if (val.compareTo(BigInteger.ZERO) != 0)
|
||||
for (int n = 0; n < a.size(); n++)
|
||||
final RatPoly resul = new RatPoly();
|
||||
if (val.compareTo(BigInteger.ZERO) != 0) {
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
resul.set(n, a.elementAt(n).multiply(val));
|
||||
}
|
||||
}
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
@ -385,7 +399,7 @@ class RatPoly {
|
||||
* @return the product of this with the other polynomial
|
||||
*/
|
||||
public RatPoly multiply(final RatPoly val) {
|
||||
RatPoly resul = new RatPoly();
|
||||
final RatPoly resul = new RatPoly();
|
||||
/*
|
||||
* the degree of the result is the sum of the two degrees.
|
||||
*/
|
||||
@ -410,15 +424,16 @@ class RatPoly {
|
||||
*/
|
||||
public RatPoly pow(final int n) throws ArithmeticException {
|
||||
RatPoly resul = new RatPoly("1");
|
||||
if (n < 0)
|
||||
if (n < 0) {
|
||||
throw new ArithmeticException("negative polynomial power " + n);
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* this ought probably be done with some binary representation
|
||||
* of the power and a smaller number of multiplications.
|
||||
*/
|
||||
for (int i = 1; i <= n; i++)
|
||||
for (int i = 1; i <= n; i++) {
|
||||
resul = resul.multiply(this);
|
||||
}
|
||||
resul.simplify();
|
||||
return resul;
|
||||
}
|
||||
@ -447,7 +462,7 @@ class RatPoly {
|
||||
* scale the polynomial by division through the expansion coefficient of
|
||||
* the absolute term
|
||||
*/
|
||||
RatPoly red = divide(a.elementAt(0));
|
||||
final RatPoly red = divide(a.elementAt(0));
|
||||
|
||||
/*
|
||||
* and remove the leading term (now equal to 1)
|
||||
@ -477,14 +492,14 @@ class RatPoly {
|
||||
* @since 2008-10-25
|
||||
*/
|
||||
public RatPoly add(final RatPoly val) {
|
||||
RatPoly resul = new RatPoly();
|
||||
final RatPoly resul = new RatPoly();
|
||||
/*
|
||||
* the degree of the result is the larger of the two degrees (before
|
||||
* simplify() at least).
|
||||
*/
|
||||
final int nmax = (degree() > val.degree()) ? degree() : val.degree();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
Rational coef = at(n).add(val.at(n));
|
||||
final Rational coef = at(n).add(val.at(n));
|
||||
resul.set(n, coef);
|
||||
}
|
||||
resul.simplify();
|
||||
@ -500,14 +515,14 @@ class RatPoly {
|
||||
* @since 2008-10-25
|
||||
*/
|
||||
public RatPoly subtract(final RatPoly val) {
|
||||
RatPoly resul = new RatPoly();
|
||||
final RatPoly resul = new RatPoly();
|
||||
/*
|
||||
* the degree of the result is the larger of the two degrees (before
|
||||
* simplify() at least).
|
||||
*/
|
||||
final int nmax = (degree() > val.degree()) ? degree() : val.degree();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
Rational coef = at(n).subtract(val.at(n));
|
||||
final Rational coef = at(n).subtract(val.at(n));
|
||||
resul.set(n, coef);
|
||||
}
|
||||
resul.simplify();
|
||||
@ -525,12 +540,14 @@ class RatPoly {
|
||||
*/
|
||||
public RatPoly divide(final Rational val) throws Error {
|
||||
if (val.compareTo(Rational.ZERO) != 0) {
|
||||
RatPoly resul = new RatPoly();
|
||||
for (int n = 0; n < a.size(); n++)
|
||||
final RatPoly resul = new RatPoly();
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
resul.set(n, a.elementAt(n).divide(val));
|
||||
}
|
||||
return resul;
|
||||
} else
|
||||
} else {
|
||||
throw new ArithmeticException("Cannot divide " + toPString() + " through zero.");
|
||||
}
|
||||
} /* divide */
|
||||
|
||||
/**
|
||||
@ -544,8 +561,8 @@ class RatPoly {
|
||||
* @throws Error
|
||||
*/
|
||||
public RatPoly divide(final RatPoly val, int nmax) throws Error {
|
||||
RatPoly num = this;
|
||||
RatPoly denom = val;
|
||||
final RatPoly num = this;
|
||||
final RatPoly denom = val;
|
||||
|
||||
/*
|
||||
* divide by a common smallest power/degree
|
||||
@ -553,11 +570,12 @@ class RatPoly {
|
||||
while (num.at(0).compareTo(BigInteger.ZERO) == 0 && denom.at(0).compareTo(BigInteger.ZERO) == 0) {
|
||||
num.a.remove(0);
|
||||
denom.a.remove(0);
|
||||
if (num.size() <= 1 || denom.size() <= 1)
|
||||
if (num.size() <= 1 || denom.size() <= 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RatPoly resul = new RatPoly();
|
||||
final RatPoly resul = new RatPoly();
|
||||
/*
|
||||
* todo: If the polynomial division is exact, we could leave
|
||||
* the loop earlier, indeed
|
||||
@ -587,20 +605,21 @@ class RatPoly {
|
||||
* @since 2012-03-01
|
||||
*/
|
||||
public RatPoly[] divideAndRemainder(final RatPoly val) throws Error {
|
||||
RatPoly[] ret = new RatPoly[2];
|
||||
final RatPoly[] ret = new RatPoly[2];
|
||||
/*
|
||||
* remove any high-order zeros
|
||||
*/
|
||||
RatPoly valSimpl = val.clone();
|
||||
final RatPoly valSimpl = val.clone();
|
||||
valSimpl.simplify();
|
||||
RatPoly thisSimpl = clone();
|
||||
final RatPoly thisSimpl = clone();
|
||||
thisSimpl.simplify();
|
||||
|
||||
/*
|
||||
* catch the case with val equal to zero
|
||||
*/
|
||||
if (valSimpl.degree() == 0 && valSimpl.a.firstElement().compareTo(Rational.ZERO) == 0)
|
||||
if (valSimpl.degree() == 0 && valSimpl.a.firstElement().compareTo(Rational.ZERO) == 0) {
|
||||
throw new ArithmeticException("Division through zero polynomial");
|
||||
}
|
||||
/*
|
||||
* degree of this smaller than degree of val: remainder is this
|
||||
*/
|
||||
@ -628,10 +647,10 @@ class RatPoly {
|
||||
/*
|
||||
* any remainder left ?
|
||||
*/
|
||||
if (ret[1].degree() < valSimpl.degree())
|
||||
if (ret[1].degree() < valSimpl.degree()) {
|
||||
;
|
||||
else {
|
||||
RatPoly rem[] = ret[1].divideAndRemainder(val);
|
||||
} else {
|
||||
final RatPoly rem[] = ret[1].divideAndRemainder(val);
|
||||
ret[0] = ret[0].add(rem[0]);
|
||||
ret[1] = rem[1];
|
||||
}
|
||||
@ -651,16 +670,18 @@ class RatPoly {
|
||||
public String toString() {
|
||||
String str = new String();
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
if (n == 0)
|
||||
if (n == 0) {
|
||||
str += a.elementAt(n).toString();
|
||||
else
|
||||
} else {
|
||||
str += "," + a.elementAt(n).toString();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* print at least a sole zero
|
||||
*/
|
||||
if (str.length() == 0)
|
||||
if (str.length() == 0) {
|
||||
str = "0";
|
||||
}
|
||||
return str;
|
||||
} /* toString */
|
||||
|
||||
@ -677,21 +698,24 @@ class RatPoly {
|
||||
final BigInteger num = a.elementAt(n).a;
|
||||
if (num.compareTo(BigInteger.ZERO) != 0) {
|
||||
str += " ";
|
||||
if (num.compareTo(BigInteger.ZERO) > 0)
|
||||
if (num.compareTo(BigInteger.ZERO) > 0) {
|
||||
str += "+";
|
||||
}
|
||||
str += a.elementAt(n).toString();
|
||||
if (n > 0) {
|
||||
str += "*x";
|
||||
if (n > 1)
|
||||
if (n > 1) {
|
||||
str += "^" + n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* print at least a sole zero
|
||||
*/
|
||||
if (str.length() == 0)
|
||||
if (str.length() == 0) {
|
||||
str = "0";
|
||||
}
|
||||
return str;
|
||||
} /* toPString */
|
||||
|
||||
@ -703,12 +727,14 @@ class RatPoly {
|
||||
*/
|
||||
private void simplify() {
|
||||
int n = a.size() - 1;
|
||||
if (n >= 0)
|
||||
if (n >= 0) {
|
||||
while (a.elementAt(n).compareTo(BigInteger.ZERO) == 0) {
|
||||
a.remove(n);
|
||||
if (--n < 0)
|
||||
if (--n < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* simplify */
|
||||
|
||||
/**
|
||||
@ -718,13 +744,13 @@ class RatPoly {
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public RatPoly derive() {
|
||||
if (a.size() <= 1)
|
||||
if (a.size() <= 1) {
|
||||
/*
|
||||
* derivative of the constant is just zero
|
||||
*/
|
||||
return new RatPoly();
|
||||
else {
|
||||
RatPoly d = new RatPoly();
|
||||
} else {
|
||||
final RatPoly d = new RatPoly();
|
||||
for (int i = 1; i <= degree(); i++) {
|
||||
final Rational c = a.elementAt(i).multiply(i);
|
||||
d.set(i - 1, c);
|
||||
@ -742,7 +768,7 @@ class RatPoly {
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public RatPoly monic() throws Error {
|
||||
RatPoly m = new RatPoly();
|
||||
final RatPoly m = new RatPoly();
|
||||
final int d = degree();
|
||||
for (int i = 0; i <= d; i++) {
|
||||
final Rational c = a.elementAt(i).divide(a.elementAt(d));
|
||||
@ -764,7 +790,7 @@ class RatPoly {
|
||||
/*
|
||||
* Start with the polynomial 0
|
||||
*/
|
||||
RatPoly r = new RatPoly();
|
||||
final RatPoly r = new RatPoly();
|
||||
for (int i = 1; i <= maxdeg; i++) {
|
||||
Rational c = new Rational();
|
||||
for (int d = 1; d <= i && d < a.size(); d++) {
|
||||
@ -792,12 +818,13 @@ class RatPoly {
|
||||
/*
|
||||
* Start with the polynomial 0
|
||||
*/
|
||||
RatPoly r = new RatPoly();
|
||||
final RatPoly r = new RatPoly();
|
||||
for (int i = 1; i <= maxdeg; i++) {
|
||||
Rational c = new Rational();
|
||||
for (int d = 1; d <= i && d < a.size(); d++) {
|
||||
if (i % d == 0)
|
||||
if (i % d == 0) {
|
||||
c = c.add(a.elementAt(d));
|
||||
}
|
||||
}
|
||||
r.set(i, c);
|
||||
}
|
||||
@ -815,11 +842,12 @@ class RatPoly {
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public RatPoly binomialT(int maxdeg) {
|
||||
RatPoly r = new RatPoly();
|
||||
final RatPoly r = new RatPoly();
|
||||
for (int i = 0; i <= maxdeg; i++) {
|
||||
Rational c = new Rational(0, 1);
|
||||
for (int j = 0; j <= i && j < a.size(); j++)
|
||||
for (int j = 0; j <= i && j < a.size(); j++) {
|
||||
c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
|
||||
}
|
||||
r.set(i, c);
|
||||
}
|
||||
r.simplify();
|
||||
@ -836,14 +864,16 @@ class RatPoly {
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public RatPoly binomialTInv(int maxdeg) {
|
||||
RatPoly r = new RatPoly();
|
||||
final RatPoly r = new RatPoly();
|
||||
for (int i = 0; i <= maxdeg; i++) {
|
||||
Rational c = new Rational(0, 1);
|
||||
for (int j = 0; j <= i && j < a.size(); j++)
|
||||
if ((j + i) % 2 != 0)
|
||||
for (int j = 0; j <= i && j < a.size(); j++) {
|
||||
if ((j + i) % 2 != 0) {
|
||||
c = c.subtract(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
|
||||
else
|
||||
} else {
|
||||
c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
|
||||
}
|
||||
}
|
||||
r.set(i, c);
|
||||
}
|
||||
r.simplify();
|
||||
@ -865,9 +895,10 @@ class RatPoly {
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public RatPoly trunc(int newdeg) {
|
||||
RatPoly t = new RatPoly();
|
||||
for (int i = 0; i <= newdeg; i++)
|
||||
final RatPoly t = new RatPoly();
|
||||
for (int i = 0; i <= newdeg; i++) {
|
||||
t.set(i, at(i));
|
||||
}
|
||||
t.simplify();
|
||||
return t;
|
||||
} /* trunc */
|
||||
@ -883,10 +914,10 @@ class RatPoly {
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public Vector<BigComplex> roots(int digits) throws Error {
|
||||
RatPoly mon = monic();
|
||||
final RatPoly mon = monic();
|
||||
|
||||
Random rand = new Random();
|
||||
MathContext mc = new MathContext(digits + 3, RoundingMode.DOWN);
|
||||
final Random rand = new Random();
|
||||
final MathContext mc = new MathContext(digits + 3, RoundingMode.DOWN);
|
||||
|
||||
Vector<BigComplex> res = new Vector<>();
|
||||
|
||||
@ -894,9 +925,10 @@ class RatPoly {
|
||||
double randRad = 0.;
|
||||
for (int i = 0; i <= d; i++) {
|
||||
/* scale coefficient at maximum degree */
|
||||
double absi = Math.abs(mon.at(i).doubleValue());
|
||||
if (absi > randRad)
|
||||
final double absi = Math.abs(mon.at(i).doubleValue());
|
||||
if (absi > randRad) {
|
||||
randRad = absi;
|
||||
}
|
||||
}
|
||||
randRad += 1.0;
|
||||
|
||||
@ -904,8 +936,8 @@ class RatPoly {
|
||||
* initial values randomly in radius 1+randRad
|
||||
*/
|
||||
for (int i = 0; i < d; i++) {
|
||||
double rad = randRad * rand.nextDouble();
|
||||
double phi = 2.0 * 3.14159 * rand.nextDouble();
|
||||
final double rad = randRad * rand.nextDouble();
|
||||
final double phi = 2.0 * 3.14159 * rand.nextDouble();
|
||||
res.add(i, new BigComplex(rad * Math.cos(phi), rad * Math.sin(phi)));
|
||||
}
|
||||
|
||||
@ -918,7 +950,7 @@ class RatPoly {
|
||||
for (; !convr;)// ORIGINAL LINE: for(int itr =0 ; ! convr ; itr++)
|
||||
{
|
||||
convr = true;
|
||||
Vector<BigComplex> resPlus = new Vector<>();
|
||||
final Vector<BigComplex> resPlus = new Vector<>();
|
||||
for (int v = 0; v < d; v++) {
|
||||
/*
|
||||
* evaluate f(x)/(x-root1)/(x-root2)/... (x-rootdegr), Newton
|
||||
@ -927,19 +959,22 @@ class RatPoly {
|
||||
BigComplex thisx = res.elementAt(v);
|
||||
BigComplex nv = mon.valueOf(thisx, mc);
|
||||
for (int j = 0; j < d; j++) {
|
||||
if (j != v)
|
||||
if (j != v) {
|
||||
nv = nv.divide(thisx.subtract(res.elementAt(j)), mc);
|
||||
}
|
||||
}
|
||||
|
||||
/* is this value converged ? */
|
||||
if (nv.abs(mc).doubleValue() > thisx.abs(mc).doubleValue() * Math.pow(10.0, -digits))
|
||||
if (nv.abs(mc).doubleValue() > thisx.abs(mc).doubleValue() * Math.pow(10.0, -digits)) {
|
||||
convr = false;
|
||||
}
|
||||
|
||||
thisx = thisx.subtract(nv);
|
||||
|
||||
/* If unstable, start over */
|
||||
if (thisx.abs(MathContext.DECIMAL32).doubleValue() > randRad)
|
||||
if (thisx.abs(MathContext.DECIMAL32).doubleValue() > randRad) {
|
||||
return roots(digits);
|
||||
}
|
||||
|
||||
resPlus.add(thisx);
|
||||
}
|
||||
@ -959,9 +994,9 @@ class RatPoly {
|
||||
*/
|
||||
public Vector<BigInteger> iroots() {
|
||||
/* The vector of the roots */
|
||||
Vector<BigInteger> res = new Vector<>();
|
||||
final Vector<BigInteger> res = new Vector<>();
|
||||
|
||||
int lowd = ldegree();
|
||||
final int lowd = ldegree();
|
||||
if (lowd == 0 && a.elementAt(0).compareTo(BigInteger.ZERO) == 0) {
|
||||
/*
|
||||
* Case of polynomial identical to zero:
|
||||
@ -977,28 +1012,29 @@ class RatPoly {
|
||||
* start with denominator of first non-zero coefficient.
|
||||
*/
|
||||
BigInteger lcmDeno = a.elementAt(lowd).b;
|
||||
for (int i = lowd + 1; i < degree(); i++)
|
||||
for (int i = lowd + 1; i < degree(); i++) {
|
||||
lcmDeno = BigIntegerMath.lcm(lcmDeno, a.elementAt(i).b);
|
||||
}
|
||||
|
||||
/*
|
||||
* and eventually get the integer polynomial by ignoring the
|
||||
* denominators
|
||||
*/
|
||||
Vector<BigInteger> ipo = new Vector<>();
|
||||
final Vector<BigInteger> ipo = new Vector<>();
|
||||
for (int i = 0; i < a.size(); i++) {
|
||||
BigInteger d = a.elementAt(i).a.multiply(lcmDeno).divide(a.elementAt(i).b);
|
||||
final BigInteger d = a.elementAt(i).a.multiply(lcmDeno).divide(a.elementAt(i).b);
|
||||
ipo.add(d);
|
||||
}
|
||||
|
||||
BigIntegerPoly p = new BigIntegerPoly(ipo);
|
||||
final BigIntegerPoly p = new BigIntegerPoly(ipo);
|
||||
/*
|
||||
* collect the integer roots (multiple roots only once). Since we
|
||||
* removed the zero already above, cand does not contain zeros.
|
||||
*/
|
||||
Vector<BigInteger> cand = p.iroots();
|
||||
final Vector<BigInteger> cand = p.iroots();
|
||||
for (int i = 0; i < cand.size(); i++) {
|
||||
final BigInteger r = cand.elementAt(i);
|
||||
int deg = p.rootDeg(r);
|
||||
final int deg = p.rootDeg(r);
|
||||
res.add(r);
|
||||
res.add(new BigInteger("" + deg));
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* does not yet test for a denominator equal to zero
|
||||
*/
|
||||
public Rational(String str, int radix) {
|
||||
int hasslah = str.indexOf("/");
|
||||
final int hasslah = str.indexOf("/");
|
||||
if (hasslah == -1) {
|
||||
a = new BigInteger(str, radix);
|
||||
b = new BigInteger("1", radix);
|
||||
@ -159,8 +159,8 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* protected access means this does not work return new
|
||||
* Rational(a.clone(), b.clone()) ;
|
||||
*/
|
||||
BigInteger aclon = new BigInteger("" + a);
|
||||
BigInteger bclon = new BigInteger("" + b);
|
||||
final BigInteger aclon = new BigInteger("" + a);
|
||||
final BigInteger bclon = new BigInteger("" + b);
|
||||
return new Rational(aclon, bclon);
|
||||
} /* Rational.clone */
|
||||
|
||||
@ -172,8 +172,8 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return the product of this with the val.
|
||||
*/
|
||||
public Rational multiply(final Rational val) {
|
||||
BigInteger num = a.multiply(val.a);
|
||||
BigInteger deno = b.multiply(val.b);
|
||||
final BigInteger num = a.multiply(val.a);
|
||||
final BigInteger deno = b.multiply(val.b);
|
||||
/*
|
||||
* Normalization to an coprime format will be done inside the ctor() and
|
||||
* is not duplicated here.
|
||||
@ -189,7 +189,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return the product of this with the value.
|
||||
*/
|
||||
public Rational multiply(final BigInteger val) {
|
||||
Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
final Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
return (multiply(val2));
|
||||
} /* Rational.multiply */
|
||||
|
||||
@ -201,7 +201,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return the product of this with the value.
|
||||
*/
|
||||
public Rational multiply(final int val) {
|
||||
BigInteger tmp = new BigInteger("" + val);
|
||||
final BigInteger tmp = new BigInteger("" + val);
|
||||
return multiply(tmp);
|
||||
} /* Rational.multiply */
|
||||
|
||||
@ -214,15 +214,17 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* exponent is 0, the value 1 is returned.
|
||||
*/
|
||||
public Rational pow(int exponent) {
|
||||
if (exponent == 0)
|
||||
if (exponent == 0) {
|
||||
return new Rational(1, 1);
|
||||
}
|
||||
|
||||
BigInteger num = a.pow(Math.abs(exponent));
|
||||
BigInteger deno = b.pow(Math.abs(exponent));
|
||||
if (exponent > 0)
|
||||
final BigInteger num = a.pow(Math.abs(exponent));
|
||||
final BigInteger deno = b.pow(Math.abs(exponent));
|
||||
if (exponent > 0) {
|
||||
return (new Rational(num, deno));
|
||||
else
|
||||
} else {
|
||||
return (new Rational(deno, num));
|
||||
}
|
||||
} /* Rational.pow */
|
||||
|
||||
/**
|
||||
@ -237,10 +239,12 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
*/
|
||||
public Rational pow(BigInteger exponent) throws Error {
|
||||
/* test for overflow */
|
||||
if (exponent.compareTo(MAX_INT) == 1)
|
||||
if (exponent.compareTo(MAX_INT) == 1) {
|
||||
throw new Error(Errors.NUMBER_TOO_LARGE);
|
||||
if (exponent.compareTo(MIN_INT) == -1)
|
||||
}
|
||||
if (exponent.compareTo(MIN_INT) == -1) {
|
||||
throw new Error(Errors.NUMBER_TOO_SMALL);
|
||||
}
|
||||
|
||||
/* promote to the simpler interface above */
|
||||
return pow(exponent.intValue());
|
||||
@ -259,15 +263,18 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
*/
|
||||
public Rational root(BigInteger r) throws Error {
|
||||
/* test for overflow */
|
||||
if (r.compareTo(MAX_INT) == 1)
|
||||
if (r.compareTo(MAX_INT) == 1) {
|
||||
throw new Error(Errors.NUMBER_TOO_LARGE);
|
||||
if (r.compareTo(MIN_INT) == -1)
|
||||
}
|
||||
if (r.compareTo(MIN_INT) == -1) {
|
||||
throw new Error(Errors.NUMBER_TOO_SMALL);
|
||||
}
|
||||
|
||||
int rthroot = r.intValue();
|
||||
final int rthroot = r.intValue();
|
||||
/* cannot pull root of a negative value with even-valued root */
|
||||
if (compareTo(ZERO) == -1 && (rthroot % 2) == 0)
|
||||
if (compareTo(ZERO) == -1 && (rthroot % 2) == 0) {
|
||||
throw new Error(Errors.NEGATIVE_PARAMETER);
|
||||
}
|
||||
|
||||
/*
|
||||
* extract a sign such that we calculate |n|^(1/r), still r carrying any
|
||||
@ -278,13 +285,14 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
/*
|
||||
* delegate the main work to ifactor#root()
|
||||
*/
|
||||
Ifactor num = new Ifactor(a.abs());
|
||||
Ifactor deno = new Ifactor(b);
|
||||
final Ifactor num = new Ifactor(a.abs());
|
||||
final Ifactor deno = new Ifactor(b);
|
||||
final Rational resul = num.root(rthroot).divide(deno.root(rthroot));
|
||||
if (flipsign)
|
||||
if (flipsign) {
|
||||
return resul.negate();
|
||||
else
|
||||
} else {
|
||||
return resul;
|
||||
}
|
||||
} /* Rational.root */
|
||||
|
||||
/**
|
||||
@ -298,14 +306,15 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
public Rational pow(Rational exponent) throws Error {
|
||||
if (exponent.a.compareTo(BigInteger.ZERO) == 0)
|
||||
if (exponent.a.compareTo(BigInteger.ZERO) == 0) {
|
||||
return new Rational(1, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* calculate (a/b)^(exponent.a/exponent.b) as
|
||||
* ((a/b)^exponent.a)^(1/exponent.b) = tmp^(1/exponent.b)
|
||||
*/
|
||||
Rational tmp = pow(exponent.a);
|
||||
final Rational tmp = pow(exponent.a);
|
||||
return tmp.root(exponent.b);
|
||||
} /* Rational.pow */
|
||||
|
||||
@ -318,10 +327,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @throws Error
|
||||
*/
|
||||
public Rational divide(final Rational val) throws Error {
|
||||
if (val.compareTo(Rational.ZERO) == 0)
|
||||
if (val.compareTo(Rational.ZERO) == 0) {
|
||||
throw new Error(Errors.DIVISION_BY_ZERO);
|
||||
BigInteger num = a.multiply(val.b);
|
||||
BigInteger deno = b.multiply(val.a);
|
||||
}
|
||||
final BigInteger num = a.multiply(val.b);
|
||||
final BigInteger deno = b.multiply(val.a);
|
||||
/*
|
||||
* Reduction to a coprime format is done inside the ctor, and not
|
||||
* repeated here.
|
||||
@ -338,9 +348,10 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @throws Error
|
||||
*/
|
||||
public Rational divide(BigInteger val) throws Error {
|
||||
if (val.compareTo(BigInteger.ZERO) == 0)
|
||||
if (val.compareTo(BigInteger.ZERO) == 0) {
|
||||
throw new Error(Errors.DIVISION_BY_ZERO);
|
||||
Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
}
|
||||
final Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
return (divide(val2));
|
||||
} /* Rational.divide */
|
||||
|
||||
@ -353,9 +364,10 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @throws Error
|
||||
*/
|
||||
public Rational divide(int val) throws Error {
|
||||
if (val == 0)
|
||||
if (val == 0) {
|
||||
throw new Error(Errors.DIVISION_BY_ZERO);
|
||||
Rational val2 = new Rational(val, 1);
|
||||
}
|
||||
final Rational val2 = new Rational(val, 1);
|
||||
return (divide(val2));
|
||||
} /* Rational.divide */
|
||||
|
||||
@ -367,8 +379,8 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return this+val.
|
||||
*/
|
||||
public Rational add(Rational val) {
|
||||
BigInteger num = a.multiply(val.b).add(b.multiply(val.a));
|
||||
BigInteger deno = b.multiply(val.b);
|
||||
final BigInteger num = a.multiply(val.b).add(b.multiply(val.a));
|
||||
final BigInteger deno = b.multiply(val.b);
|
||||
return (new Rational(num, deno));
|
||||
} /* Rational.add */
|
||||
|
||||
@ -380,7 +392,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return this+val.
|
||||
*/
|
||||
public Rational add(BigInteger val) {
|
||||
Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
final Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
return (add(val2));
|
||||
} /* Rational.add */
|
||||
|
||||
@ -393,7 +405,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since May 26 2010
|
||||
*/
|
||||
public Rational add(int val) {
|
||||
BigInteger val2 = a.add(b.multiply(new BigInteger("" + val)));
|
||||
final BigInteger val2 = a.add(b.multiply(new BigInteger("" + val)));
|
||||
return new Rational(val2, b);
|
||||
} /* Rational.add */
|
||||
|
||||
@ -414,7 +426,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return this - val.
|
||||
*/
|
||||
public Rational subtract(Rational val) {
|
||||
Rational val2 = val.negate();
|
||||
final Rational val2 = val.negate();
|
||||
return (add(val2));
|
||||
} /* Rational.subtract */
|
||||
|
||||
@ -426,7 +438,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return this - val.
|
||||
*/
|
||||
public Rational subtract(BigInteger val) {
|
||||
Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
final Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
return (subtract(val2));
|
||||
} /* Rational.subtract */
|
||||
|
||||
@ -438,7 +450,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @return this - val.
|
||||
*/
|
||||
public Rational subtract(int val) {
|
||||
Rational val2 = new Rational(val, 1);
|
||||
final Rational val2 = new Rational(val, 1);
|
||||
return (subtract(val2));
|
||||
} /* Rational.subtract */
|
||||
|
||||
@ -455,8 +467,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @throws Error
|
||||
*/
|
||||
public static Rational binomial(Rational n, BigInteger m) throws Error {
|
||||
if (m.compareTo(BigInteger.ZERO) == 0)
|
||||
if (m.compareTo(BigInteger.ZERO) == 0) {
|
||||
return Rational.ONE;
|
||||
}
|
||||
Rational bin = n;
|
||||
for (BigInteger i = new BigInteger("2"); i.compareTo(m) != 1; i = i.add(BigInteger.ONE)) {
|
||||
bin = bin.multiply(n.subtract(i.subtract(BigInteger.ONE))).divide(i);
|
||||
@ -477,8 +490,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @throws Error
|
||||
*/
|
||||
public static Rational binomial(Rational n, int m) throws Error {
|
||||
if (m == 0)
|
||||
if (m == 0) {
|
||||
return Rational.ONE;
|
||||
}
|
||||
Rational bin = n;
|
||||
for (int i = 2; i <= m; i++) {
|
||||
bin = bin.multiply(n.subtract(i - 1)).divide(i);
|
||||
@ -499,13 +513,14 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @throws Error
|
||||
*/
|
||||
public static Rational hankelSymb(Rational n, int k) throws Error {
|
||||
if (k == 0)
|
||||
if (k == 0) {
|
||||
return Rational.ONE;
|
||||
else if (k < 0)
|
||||
} else if (k < 0) {
|
||||
throw new Error(Errors.NEGATIVE_PARAMETER);
|
||||
}
|
||||
Rational nkhalf = n.subtract(k).add(Rational.HALF);
|
||||
nkhalf = nkhalf.Pochhammer(2 * k);
|
||||
Factorial f = new Factorial();
|
||||
final Factorial f = new Factorial();
|
||||
return nkhalf.divide(f.at(k));
|
||||
} /* Rational.binomial */
|
||||
|
||||
@ -545,12 +560,13 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
/*
|
||||
* is already integer: return the numerator
|
||||
*/
|
||||
if (b.compareTo(BigInteger.ONE) == 0)
|
||||
if (b.compareTo(BigInteger.ONE) == 0) {
|
||||
return a;
|
||||
else if (a.compareTo(BigInteger.ZERO) > 0)
|
||||
} else if (a.compareTo(BigInteger.ZERO) > 0) {
|
||||
return a.divide(b);
|
||||
else
|
||||
} else {
|
||||
return a.divide(b).subtract(BigInteger.ONE);
|
||||
}
|
||||
} /* Rational.floor */
|
||||
|
||||
/**
|
||||
@ -563,12 +579,13 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
/*
|
||||
* is already integer: return the numerator
|
||||
*/
|
||||
if (b.compareTo(BigInteger.ONE) == 0)
|
||||
if (b.compareTo(BigInteger.ONE) == 0) {
|
||||
return a;
|
||||
else if (a.compareTo(BigInteger.ZERO) > 0)
|
||||
} else if (a.compareTo(BigInteger.ZERO) > 0) {
|
||||
return a.divide(b).add(BigInteger.ONE);
|
||||
else
|
||||
} else {
|
||||
return a.divide(b);
|
||||
}
|
||||
} /* Rational.ceil */
|
||||
|
||||
/**
|
||||
@ -580,10 +597,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
/*
|
||||
* is already integer: return the numerator
|
||||
*/
|
||||
if (b.compareTo(BigInteger.ONE) == 0)
|
||||
if (b.compareTo(BigInteger.ONE) == 0) {
|
||||
return a;
|
||||
else
|
||||
} else {
|
||||
return a.divide(b);
|
||||
}
|
||||
} /* Rational.trunc */
|
||||
|
||||
/**
|
||||
@ -626,10 +644,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (b.compareTo(BigInteger.ONE) != 0)
|
||||
if (b.compareTo(BigInteger.ONE) != 0) {
|
||||
return (a.toString() + "/" + b.toString());
|
||||
else
|
||||
} else {
|
||||
return a.toString();
|
||||
}
|
||||
} /* Rational.toString */
|
||||
|
||||
/**
|
||||
@ -644,7 +663,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* separate invocation a.doubleValue() or b.doubleValue(), we divide
|
||||
* first in a BigDecimal environment and convert the result.
|
||||
*/
|
||||
BigDecimal adivb = (new BigDecimal(a)).divide(new BigDecimal(b), MathContext.DECIMAL128);
|
||||
final BigDecimal adivb = (new BigDecimal(a)).divide(new BigDecimal(b), MathContext.DECIMAL128);
|
||||
return adivb.doubleValue();
|
||||
} /* Rational.doubleValue */
|
||||
|
||||
@ -655,7 +674,7 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since 2009-08-06
|
||||
*/
|
||||
public float floatValue() {
|
||||
BigDecimal adivb = (new BigDecimal(a)).divide(new BigDecimal(b), MathContext.DECIMAL128);
|
||||
final BigDecimal adivb = (new BigDecimal(a)).divide(new BigDecimal(b), MathContext.DECIMAL128);
|
||||
return adivb.floatValue();
|
||||
} /* Rational.floatValue */
|
||||
|
||||
@ -672,8 +691,8 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
/*
|
||||
* numerator and denominator individually rephrased
|
||||
*/
|
||||
BigDecimal n = new BigDecimal(a);
|
||||
BigDecimal d = new BigDecimal(b);
|
||||
final BigDecimal n = new BigDecimal(a);
|
||||
final BigDecimal d = new BigDecimal(b);
|
||||
/*
|
||||
* the problem with n.divide(d,mc) is that the apparent precision might
|
||||
* be smaller than what is set by mc if the value has a precise
|
||||
@ -692,11 +711,12 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
*/
|
||||
public String toFString(int digits) {
|
||||
if (b.compareTo(BigInteger.ONE) != 0) {
|
||||
MathContext mc = new MathContext(digits, RoundingMode.DOWN);
|
||||
BigDecimal f = (new BigDecimal(a)).divide(new BigDecimal(b), mc);
|
||||
final MathContext mc = new MathContext(digits, RoundingMode.DOWN);
|
||||
final BigDecimal f = (new BigDecimal(a)).divide(new BigDecimal(b), mc);
|
||||
return (f.toString());
|
||||
} else
|
||||
} else {
|
||||
return a.toString();
|
||||
}
|
||||
} /* Rational.toFString */
|
||||
|
||||
/**
|
||||
@ -708,10 +728,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since 2008-10-19
|
||||
*/
|
||||
public Rational max(final Rational val) {
|
||||
if (compareTo(val) > 0)
|
||||
if (compareTo(val) > 0) {
|
||||
return this;
|
||||
else
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
} /* Rational.max */
|
||||
|
||||
/**
|
||||
@ -723,10 +744,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since 2008-10-19
|
||||
*/
|
||||
public Rational min(final Rational val) {
|
||||
if (compareTo(val) < 0)
|
||||
if (compareTo(val) < 0) {
|
||||
return this;
|
||||
else
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
} /* Rational.min */
|
||||
|
||||
/**
|
||||
@ -738,18 +760,19 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since 2008-10-25
|
||||
*/
|
||||
public Rational Pochhammer(final BigInteger n) {
|
||||
if (n.compareTo(BigInteger.ZERO) < 0)
|
||||
if (n.compareTo(BigInteger.ZERO) < 0) {
|
||||
return null;
|
||||
else if (n.compareTo(BigInteger.ZERO) == 0)
|
||||
} else if (n.compareTo(BigInteger.ZERO) == 0) {
|
||||
return Rational.ONE;
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* initialize results with the current value
|
||||
*/
|
||||
Rational res = new Rational(a, b);
|
||||
BigInteger i = BigInteger.ONE;
|
||||
for (; i.compareTo(n) < 0; i = i.add(BigInteger.ONE))
|
||||
for (; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
|
||||
res = res.multiply(add(i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
} /* Rational.pochhammer */
|
||||
@ -784,8 +807,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since 2010-05-26
|
||||
*/
|
||||
public boolean isInteger() {
|
||||
if (!isBigInteger())
|
||||
if (!isBigInteger()) {
|
||||
return false;
|
||||
}
|
||||
return (a.compareTo(MAX_INT) <= 0 && a.compareTo(MIN_INT) >= 0);
|
||||
} /* Rational.isInteger */
|
||||
|
||||
@ -797,8 +821,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since 2011-02-13
|
||||
*/
|
||||
int intValue() throws Error {
|
||||
if (!isInteger())
|
||||
if (!isInteger()) {
|
||||
throw new Error(Errors.CONVERSION_ERROR);
|
||||
}
|
||||
return a.intValue();
|
||||
}
|
||||
|
||||
@ -810,8 +835,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
* @since 2012-03-02
|
||||
*/
|
||||
BigInteger BigIntegerValue() throws Error {
|
||||
if (!isBigInteger())
|
||||
if (!isBigInteger()) {
|
||||
throw new Error(Errors.CONVERSION_ERROR);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
@ -845,8 +871,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
|
||||
*/
|
||||
static public BigInteger lcmDenom(final Rational[] vals) {
|
||||
BigInteger l = BigInteger.ONE;
|
||||
for (int v = 0; v < vals.length; v++)
|
||||
l = BigIntegerMath.lcm(l, vals[v].b);
|
||||
for (final Rational val : vals) {
|
||||
l = BigIntegerMath.lcm(l, val.b);
|
||||
}
|
||||
return l;
|
||||
} /* Rational.lcmDenom */
|
||||
|
||||
|
@ -37,43 +37,45 @@ public class Wigner3j {
|
||||
static public void main(String args[]) throws Error {
|
||||
if (args[0].compareTo("6j") == 0) {
|
||||
try {
|
||||
String m1 = "6";
|
||||
String t1 = "1 2 -3 -1 5 6";
|
||||
String t2 = "4 -5 3 -4 -2 -6";
|
||||
final String m1 = "6";
|
||||
final String t1 = "1 2 -3 -1 5 6";
|
||||
final String t2 = "4 -5 3 -4 -2 -6";
|
||||
String j = "";
|
||||
for (int i = 1; i <= 6; i++)
|
||||
for (int i = 1; i <= 6; i++) {
|
||||
j += args[i] + " ";
|
||||
BigSurdVec w = wigner3j(m1, t1, t2, j);
|
||||
}
|
||||
final BigSurdVec w = wigner3j(m1, t1, t2, j);
|
||||
System.out.println(w.toString());
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
} else if (args[0].compareTo("9j") == 0) {
|
||||
try {
|
||||
String m1 = "9";
|
||||
String t1 = "1 3 2 4 6 5 7 9 8";
|
||||
String t2 = "2 8 5 6 3 9 7 4 1";
|
||||
final String m1 = "9";
|
||||
final String t1 = "1 3 2 4 6 5 7 9 8";
|
||||
final String t2 = "2 8 5 6 3 9 7 4 1";
|
||||
String j = "";
|
||||
for (int i = 1; i <= 9; i++)
|
||||
for (int i = 1; i <= 9; i++) {
|
||||
j += args[i] + " ";
|
||||
BigSurdVec w = wigner3j(m1, t1, t2, j);
|
||||
}
|
||||
final BigSurdVec w = wigner3j(m1, t1, t2, j);
|
||||
System.out.println(w.toString());
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
} else if (args[0].compareTo("3jm") == 0) {
|
||||
int j1 = (new Integer(args[1])).intValue();
|
||||
int j2 = (new Integer(args[2])).intValue();
|
||||
int j3 = (new Integer(args[3])).intValue();
|
||||
int m1 = (new Integer(args[4])).intValue();
|
||||
int m2 = (new Integer(args[5])).intValue();
|
||||
int m3 = (new Integer(args[6])).intValue();
|
||||
final int j1 = (new Integer(args[1])).intValue();
|
||||
final int j2 = (new Integer(args[2])).intValue();
|
||||
final int j3 = (new Integer(args[3])).intValue();
|
||||
final int m1 = (new Integer(args[4])).intValue();
|
||||
final int m2 = (new Integer(args[5])).intValue();
|
||||
final int m3 = (new Integer(args[6])).intValue();
|
||||
try {
|
||||
BigSurd w = wigner3jm(j1, j2, j3, m1, m2, m3);
|
||||
System.out.println(w.toString());
|
||||
w = w.multiply(new BigSurd(j3 + 1, 1));
|
||||
System.out.println("CG factor sqrt" + (j3 + 1) + "sign " + ((j2 - j2 - m3) / 2) + " " + w.toString());
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
@ -108,12 +110,12 @@ public class Wigner3j {
|
||||
* @throws Error
|
||||
*/
|
||||
static public BigSurd wigner3jm(int j1, int j2, int j3, int m1, int m2, int m3) throws Error {
|
||||
Rational J1 = new Rational(j1, 2);
|
||||
Rational J2 = new Rational(j2, 2);
|
||||
Rational J3 = new Rational(j3, 2);
|
||||
Rational M1 = new Rational(m1, 2);
|
||||
Rational M2 = new Rational(m2, 2);
|
||||
Rational M3 = new Rational(m3, 2);
|
||||
final Rational J1 = new Rational(j1, 2);
|
||||
final Rational J2 = new Rational(j2, 2);
|
||||
final Rational J3 = new Rational(j3, 2);
|
||||
final Rational M1 = new Rational(m1, 2);
|
||||
final Rational M2 = new Rational(m2, 2);
|
||||
final Rational M3 = new Rational(m3, 2);
|
||||
return wigner3jm(J1, J2, J3, M1, M2, M3);
|
||||
} /* wigner3jm */
|
||||
|
||||
@ -148,7 +150,7 @@ public class Wigner3j {
|
||||
* The rest of the line is ignored.
|
||||
*/
|
||||
Scanner s = new Scanner(m1);
|
||||
int m = s.nextInt();
|
||||
final int m = s.nextInt();
|
||||
if (m % 3 != 0) {
|
||||
s.close();
|
||||
throw new IllegalArgumentException("Angular momenta " + m + " not a multiple of three.");
|
||||
@ -158,8 +160,8 @@ public class Wigner3j {
|
||||
* Scan the numbers in the line "j". Excess numbers beyond what has been
|
||||
* announced in the "m" line are ignored.
|
||||
*/
|
||||
int[] jvec = new int[m];
|
||||
int[] tvec = new int[2 * m];
|
||||
final int[] jvec = new int[m];
|
||||
final int[] tvec = new int[2 * m];
|
||||
|
||||
s.close();
|
||||
|
||||
@ -183,14 +185,16 @@ public class Wigner3j {
|
||||
*/
|
||||
s = new Scanner(t1);
|
||||
int ti = 0;
|
||||
while (s.hasNextInt())
|
||||
while (s.hasNextInt()) {
|
||||
tvec[ti++] = s.nextInt();
|
||||
}
|
||||
|
||||
s.close();
|
||||
|
||||
s = new Scanner(t2);
|
||||
while (s.hasNextInt())
|
||||
while (s.hasNextInt()) {
|
||||
tvec[ti++] = s.nextInt();
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic sanity checks. All indices in the first two lines address a
|
||||
@ -205,18 +209,19 @@ public class Wigner3j {
|
||||
throw new IllegalArgumentException("triad-count " + ti + " not twice j-count " + ji);
|
||||
}
|
||||
|
||||
int[] jfreq = new int[m];
|
||||
for (ji = 0; ji < jfreq.length; ji++)
|
||||
final int[] jfreq = new int[m];
|
||||
for (ji = 0; ji < jfreq.length; ji++) {
|
||||
jfreq[ji] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* maintain a 0-based index which shows where the j-value has its first
|
||||
* and second occurrence in the flattened list of triads.
|
||||
*/
|
||||
int[][] jhash = new int[m][2];
|
||||
final int[][] jhash = new int[m][2];
|
||||
|
||||
for (ti = 0; ti < 2 * m; ti++) {
|
||||
int t = tvec[ti];
|
||||
final int t = tvec[ti];
|
||||
if (t == 0 || Math.abs(t) > jvec.length) {
|
||||
s.close();
|
||||
throw new IllegalArgumentException("Triad index " + t + " out of bounds");
|
||||
@ -233,7 +238,7 @@ public class Wigner3j {
|
||||
* Move on from the 2j+1 values of the input to the j-values. Subtract
|
||||
* one and divide through 2.
|
||||
*/
|
||||
Rational[] J = new Rational[jvec.length];
|
||||
final Rational[] J = new Rational[jvec.length];
|
||||
for (ji = 0; ji < jvec.length; ji++) {
|
||||
J[ji] = new Rational(jvec[ji] - 1, 2);
|
||||
}
|
||||
@ -242,14 +247,15 @@ public class Wigner3j {
|
||||
* Convert the 1-based indices to 0-based indices, loosing the sign
|
||||
* information.
|
||||
*/
|
||||
int[] triadidx = new int[tvec.length];
|
||||
for (ti = 0; ti < tvec.length; ti++)
|
||||
final int[] triadidx = new int[tvec.length];
|
||||
for (ti = 0; ti < tvec.length; ti++) {
|
||||
triadidx[ti] = Math.abs(tvec[ti]) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The M-values are all null (undetermined) at the start.
|
||||
*/
|
||||
Rational[] M = new Rational[J.length];
|
||||
final Rational[] M = new Rational[J.length];
|
||||
s.close();
|
||||
return wigner3j(tvec, J, M, triadidx);
|
||||
} /* wigner3j */
|
||||
@ -286,10 +292,12 @@ public class Wigner3j {
|
||||
*/
|
||||
for (int t = 0; t < triadidx.length; t += 3) {
|
||||
/* Ensure |J[t]-J[t+1]| <= J[t+2] <= J[t]+J[t+1] */
|
||||
if (J[triadidx[t]].subtract(J[triadidx[t + 1]]).abs().compareTo(J[triadidx[t + 2]]) > 0)
|
||||
if (J[triadidx[t]].subtract(J[triadidx[t + 1]]).abs().compareTo(J[triadidx[t + 2]]) > 0) {
|
||||
return res;
|
||||
if (J[triadidx[t]].add(J[triadidx[t + 1]]).compareTo(J[triadidx[t + 2]]) < 0)
|
||||
}
|
||||
if (J[triadidx[t]].add(J[triadidx[t + 1]]).compareTo(J[triadidx[t + 2]]) < 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -310,14 +318,14 @@ public class Wigner3j {
|
||||
* others values are set in the triad. or it is still to
|
||||
* maintain its own explicit loop.
|
||||
*/
|
||||
int triadn = i / 3;
|
||||
int triadr = i % 3;
|
||||
final int triadn = i / 3;
|
||||
final int triadr = i % 3;
|
||||
/*
|
||||
* the neighbors in the triad have indices triadn*3+ (tiradr+1)
|
||||
* mod 3 and triadn*3+(triadr+2) mod3
|
||||
*/
|
||||
int nei1 = 3 * triadn + (triadr + 1) % 3;
|
||||
int nei2 = 3 * triadn + (triadr + 2) % 3;
|
||||
final int nei1 = 3 * triadn + (triadr + 1) % 3;
|
||||
final int nei2 = 3 * triadn + (triadr + 2) % 3;
|
||||
|
||||
/*
|
||||
* found a candidate for which the two other values are already
|
||||
@ -331,11 +339,13 @@ public class Wigner3j {
|
||||
* rough work load estimator: basically (2J1+1)*(2J2+1)
|
||||
*/
|
||||
Rational wt = J[triadidx[i]].multiply(2).add(1);
|
||||
if (M[triadidx[nei1]] == null)
|
||||
if (M[triadidx[nei1]] == null) {
|
||||
wt = wt.multiply(J[triadidx[nei1]].multiply(2).add(1));
|
||||
if (M[triadidx[nei2]] == null)
|
||||
}
|
||||
if (M[triadidx[nei2]] == null) {
|
||||
wt = wt.multiply(J[triadidx[nei2]].multiply(2).add(1));
|
||||
int thiswt = wt.intValue();
|
||||
}
|
||||
final int thiswt = wt.intValue();
|
||||
if (freeM < 0 || thiswt < freeMrank) {
|
||||
freeM = i;
|
||||
freeMrank = thiswt;
|
||||
@ -349,24 +359,26 @@ public class Wigner3j {
|
||||
* found an m-value which has not yet been summed over.
|
||||
*/
|
||||
if (M[triadidx[freeM]] == null) {
|
||||
Rational[] childM = new Rational[M.length];
|
||||
for (int ji = 0; ji < M.length; ji++)
|
||||
if (M[ji] != null)
|
||||
final Rational[] childM = new Rational[M.length];
|
||||
for (int ji = 0; ji < M.length; ji++) {
|
||||
if (M[ji] != null) {
|
||||
childM[ji] = M[ji];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* two cases: value is fixed implicitly because already two
|
||||
* others values are set in the triad. or it is still to
|
||||
* maintain its own explicit loop.
|
||||
*/
|
||||
int triadn = freeM / 3;
|
||||
int triadr = freeM % 3;
|
||||
final int triadn = freeM / 3;
|
||||
final int triadr = freeM % 3;
|
||||
/*
|
||||
* the neighbors in the triad have indices triadn*3+ (triadr+1)
|
||||
* mod 3 and triadn*3+(triadr+2) mod3
|
||||
*/
|
||||
int nei1 = 3 * triadn + (triadr + 1) % 3;
|
||||
int nei2 = 3 * triadn + (triadr + 2) % 3;
|
||||
final int nei1 = 3 * triadn + (triadr + 1) % 3;
|
||||
final int nei2 = 3 * triadn + (triadr + 2) % 3;
|
||||
if (M[triadidx[nei1]] == null || M[triadidx[nei2]] == null) {
|
||||
/*
|
||||
* The J-value is J[triadidx[freeM]]. Loop from -J to +J,
|
||||
@ -390,12 +402,14 @@ public class Wigner3j {
|
||||
* negate if these are the second occurrences of the J in
|
||||
* the triads
|
||||
*/
|
||||
if (tvec[nei1] < 0)
|
||||
if (tvec[nei1] < 0) {
|
||||
m1 = m1.negate();
|
||||
if (tvec[nei2] < 0)
|
||||
}
|
||||
if (tvec[nei2] < 0) {
|
||||
m2 = m2.negate();
|
||||
}
|
||||
/* m3 = -(m1+m2) */
|
||||
Rational newm = tvec[freeM] > 0 ? m1.add(m2).negate() : m1.add(m2);
|
||||
final Rational newm = tvec[freeM] > 0 ? m1.add(m2).negate() : m1.add(m2);
|
||||
/*
|
||||
* No contribution if the m-value enforced by the other two
|
||||
* entries is outside the range -|J|..|J| enforced by its
|
||||
@ -429,34 +443,40 @@ public class Wigner3j {
|
||||
* negate if these are associated with in-flowing vectors in the
|
||||
* triads
|
||||
*/
|
||||
if (tvec[ji] < 0)
|
||||
if (tvec[ji] < 0) {
|
||||
m1 = m1.negate();
|
||||
if (tvec[ji + 1] < 0)
|
||||
}
|
||||
if (tvec[ji + 1] < 0) {
|
||||
m2 = m2.negate();
|
||||
if (tvec[ji + 2] < 0)
|
||||
}
|
||||
if (tvec[ji + 2] < 0) {
|
||||
m3 = m3.negate();
|
||||
}
|
||||
res = res.multiply(wigner3jm(J[triadidx[ji]], J[triadidx[ji + 1]], J[triadidx[ji + 2]], m1, m2, m3));
|
||||
|
||||
/*
|
||||
* if a partial product yields zero, the total product is zero, too,
|
||||
* and offers an early exit.
|
||||
*/
|
||||
if (res.signum() == 0)
|
||||
if (res.signum() == 0) {
|
||||
return BigSurdVec.ZERO;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The overal sign is product_{J-Mpairs} (-1)^(J-M). This is an integer
|
||||
* because all the J-M are integer.
|
||||
*/
|
||||
Rational sig = new Rational();
|
||||
for (int ji = 0; ji < J.length; ji++)
|
||||
for (int ji = 0; ji < J.length; ji++) {
|
||||
sig = sig.add(J[ji]).subtract(M[ji]);
|
||||
}
|
||||
/*
|
||||
* sign depends on the sum being even or odd. We assume that "sig" is
|
||||
* integer and look only at the numerator
|
||||
*/
|
||||
if (sig.a.abs().testBit(0))
|
||||
if (sig.a.abs().testBit(0)) {
|
||||
res = res.negate();
|
||||
}
|
||||
return res;
|
||||
} /* wigner3j */
|
||||
|
||||
@ -487,36 +507,42 @@ public class Wigner3j {
|
||||
/*
|
||||
* Check that m1+m2+m3 = 0
|
||||
*/
|
||||
if (m1.add(m2).add(m3).signum() != 0)
|
||||
if (m1.add(m2).add(m3).signum() != 0) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that j1+j2+j3 is integer
|
||||
*/
|
||||
if (j1.add(j2).add(j3).isBigInteger() == false)
|
||||
if (j1.add(j2).add(j3).isBigInteger() == false) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that |j1-j2|<=j3 <= |j1+j2|
|
||||
*/
|
||||
Rational j1m2 = j1.subtract(j2);
|
||||
if (j1m2.abs().compareTo(j3) > 0)
|
||||
final Rational j1m2 = j1.subtract(j2);
|
||||
if (j1m2.abs().compareTo(j3) > 0) {
|
||||
return BigSurd.ZERO;
|
||||
Rational j1p2 = j1.add(j2);
|
||||
if (j1p2.abs().compareTo(j3) < 0)
|
||||
}
|
||||
final Rational j1p2 = j1.add(j2);
|
||||
if (j1p2.abs().compareTo(j3) < 0) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that |m_i| <= j_i
|
||||
*/
|
||||
if (m1.abs().compareTo(j1) > 0 || m2.abs().compareTo(j2) > 0 || m3.abs().compareTo(j3) > 0)
|
||||
if (m1.abs().compareTo(j1) > 0 || m2.abs().compareTo(j2) > 0 || m3.abs().compareTo(j3) > 0) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that m_i-j_i are integer.
|
||||
*/
|
||||
if (!m1.subtract(j1).isBigInteger() || !m2.subtract(j2).isBigInteger() || !m3.subtract(j3).isBigInteger())
|
||||
if (!m1.subtract(j1).isBigInteger() || !m2.subtract(j2).isBigInteger() || !m3.subtract(j3).isBigInteger()) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* (-)^(j1-j2-m3)*delta(-m3,m1+m2)*sqrt[ (j3+j1-j2)! (j3-j1+j2)!
|
||||
@ -548,28 +574,31 @@ public class Wigner3j {
|
||||
jj1m2k += k;
|
||||
}
|
||||
|
||||
Factorial f = new Factorial();
|
||||
final 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));
|
||||
if (k % 2 == 0)
|
||||
final 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
|
||||
} else {
|
||||
sumk = sumk.subtract(new Rational(BigInteger.ONE, d));
|
||||
}
|
||||
j1j2jk--;
|
||||
j1m1k--;
|
||||
j2m2k--;
|
||||
jj2m1k++;
|
||||
jj1m2k++;
|
||||
if (j1j2jk < 0 || j1m1k < 0 || j2m2k < 0)
|
||||
if (j1j2jk < 0 || j1m1k < 0 || j2m2k < 0) {
|
||||
break;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
/*
|
||||
* sign factor (-1)^(j1-j2-m3)
|
||||
*/
|
||||
if (j1m2.subtract(m3).intValue() % 2 != 0)
|
||||
if (j1m2.subtract(m3).intValue() % 2 != 0) {
|
||||
sumk = sumk.negate();
|
||||
}
|
||||
|
||||
k = j1m2.add(j3).intValue();
|
||||
BigInteger s = f.at(k);
|
||||
@ -591,7 +620,7 @@ public class Wigner3j {
|
||||
s = s.multiply(f.at(k));
|
||||
k = j1p2.add(j3).intValue();
|
||||
k++;
|
||||
Rational disc = new Rational(s, f.at(k));
|
||||
final Rational disc = new Rational(s, f.at(k));
|
||||
return new BigSurd(sumk, disc);
|
||||
} /* wigner3jm */
|
||||
|
||||
|
@ -79,12 +79,12 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
searJ.setLayoutOrientation(JList.HORIZONTAL_WRAP);
|
||||
searJ.addListSelectionListener(this);
|
||||
|
||||
Font defFont = new Font("Monospaced", Font.PLAIN, 11);
|
||||
final Font defFont = new Font("Monospaced", Font.PLAIN, 11);
|
||||
|
||||
fram.setBackground(new Color(250, 250, 250));
|
||||
fram.setForeground(new Color(0, 0, 0));
|
||||
Color fg = new Color(0, 200, 0);
|
||||
Color bg = new Color(10, 10, 10);
|
||||
final Color fg = new Color(0, 200, 0);
|
||||
final Color bg = new Color(10, 10, 10);
|
||||
|
||||
gridbag = new GridBagLayout();
|
||||
fram.setLayout(gridbag);
|
||||
@ -138,8 +138,8 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public void compute() throws Error {
|
||||
String tr = inpGtria.getText();
|
||||
String[] trias = new String[4];
|
||||
final String tr = inpGtria.getText();
|
||||
final String[] trias = new String[4];
|
||||
|
||||
/*
|
||||
* Read the trias configuration from inpGtria into trias[0..2], skipping
|
||||
@ -149,9 +149,10 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
for (int l = 0; l < 3;) {
|
||||
try {
|
||||
trias[l] = s.nextLine().trim();
|
||||
if (!trias[l].startsWith("#"))
|
||||
if (!trias[l].startsWith("#")) {
|
||||
l++;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
s.close();
|
||||
outG.setText("ERROR: less than 3 lines in the triad definition");
|
||||
return;
|
||||
@ -163,28 +164,28 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
/*
|
||||
* Read the J values from inpGjval into trias[3] in a loop
|
||||
*/
|
||||
String j = inpGjval.getText();
|
||||
final String j = inpGjval.getText();
|
||||
s = new Scanner(j);
|
||||
while (true) {
|
||||
try {
|
||||
trias[3] = s.nextLine().trim();
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
s.close();
|
||||
return;
|
||||
}
|
||||
if (!trias[3].startsWith("#")) {
|
||||
try {
|
||||
BigSurdVec w = Wigner3j.wigner3j(trias[0], trias[1], trias[2], trias[3]);
|
||||
final BigSurdVec w = Wigner3j.wigner3j(trias[0], trias[1], trias[2], trias[3]);
|
||||
outG.append(w.toString() + " = " + w.doubleValue());
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
outG.append(e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
outG.append(" # J = ");
|
||||
Scanner num = new Scanner(trias[3]);
|
||||
final Scanner num = new Scanner(trias[3]);
|
||||
while (num.hasNextInt()) {
|
||||
int twoj1 = num.nextInt();
|
||||
Rational jfrac = new Rational(twoj1 - 1, 2);
|
||||
final int twoj1 = num.nextInt();
|
||||
final Rational jfrac = new Rational(twoj1 - 1, 2);
|
||||
outG.append(jfrac.toString() + " ");
|
||||
}
|
||||
outG.append("\n");
|
||||
@ -202,7 +203,7 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String lin = e.getActionCommand();
|
||||
final String lin = e.getActionCommand();
|
||||
/*
|
||||
* debugging System.out.println("Ac"+e.paramString()) ;
|
||||
* System.out.println(lin) ;
|
||||
@ -211,7 +212,7 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
outG.setText("");
|
||||
try {
|
||||
compute();
|
||||
} catch (Error e1) {
|
||||
} catch (final Error e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
@ -327,7 +328,7 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Wigner3jGUI g = new Wigner3jGUI();
|
||||
final Wigner3jGUI g = new Wigner3jGUI();
|
||||
g.init();
|
||||
} /* main */
|
||||
|
||||
|
@ -16,26 +16,26 @@ public class BMPFile extends Component {
|
||||
// --- Private variable declaration
|
||||
// --- Bitmap file header
|
||||
@SuppressWarnings("unused")
|
||||
private byte bitmapFileHeader[] = new byte[14];
|
||||
private byte bfType[] = { 'B', 'M' };
|
||||
private final byte bitmapFileHeader[] = new byte[14];
|
||||
private final byte bfType[] = { 'B', 'M' };
|
||||
private int bfSize = 0;
|
||||
private int bfReserved1 = 0;
|
||||
private int bfReserved2 = 0;
|
||||
private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
|
||||
private final int bfReserved1 = 0;
|
||||
private final int bfReserved2 = 0;
|
||||
private final int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
|
||||
// --- Bitmap info header
|
||||
@SuppressWarnings("unused")
|
||||
private byte bitmapInfoHeader[] = new byte[40];
|
||||
private int biSize = BITMAPINFOHEADER_SIZE;
|
||||
private final byte bitmapInfoHeader[] = new byte[40];
|
||||
private final 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 final int biPlanes = 1;
|
||||
private final int biBitCount = 24;
|
||||
private final int biCompression = 0;
|
||||
private int biSizeImage = 0x030000;
|
||||
private int biXPelsPerMeter = 0x0;
|
||||
private int biYPelsPerMeter = 0x0;
|
||||
private int biClrUsed = 0;
|
||||
private int biClrImportant = 0;
|
||||
private final int biXPelsPerMeter = 0x0;
|
||||
private final int biYPelsPerMeter = 0x0;
|
||||
private final int biClrUsed = 0;
|
||||
private final int biClrImportant = 0;
|
||||
// --- Bitmap raw data
|
||||
private int bitmap[];
|
||||
// --- File section
|
||||
@ -49,7 +49,7 @@ public class BMPFile extends Component {
|
||||
fo = new FileOutputStream(parFilename);
|
||||
save(parImage, parWidth, parHeight);
|
||||
fo.close();
|
||||
} catch (Exception saveEx) {
|
||||
} catch (final Exception saveEx) {
|
||||
saveEx.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -68,7 +68,7 @@ public class BMPFile extends Component {
|
||||
writeBitmapFileHeader();
|
||||
writeBitmapInfoHeader();
|
||||
writeBitmap();
|
||||
} catch (Exception saveEx) {
|
||||
} catch (final Exception saveEx) {
|
||||
saveEx.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -81,10 +81,10 @@ public class BMPFile extends Component {
|
||||
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);
|
||||
final PixelGrabber pg = new PixelGrabber(parImage, 0, 0, parWidth, parHeight, bitmap, 0, parWidth);
|
||||
try {
|
||||
pg.grabPixels();
|
||||
} catch (InterruptedException e) {
|
||||
} catch (final InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return (false);
|
||||
}
|
||||
@ -113,11 +113,13 @@ public class BMPFile extends Component {
|
||||
int lastRowIndex;
|
||||
int pad;
|
||||
int padCount;
|
||||
byte rgb[] = new byte[3];
|
||||
final byte rgb[] = new byte[3];
|
||||
size = (biWidth * biHeight) - 1;
|
||||
pad = 4 - ((biWidth * 3) % 4);
|
||||
if (pad == 4) // <==== Bug correction
|
||||
if (pad == 4)
|
||||
{
|
||||
pad = 0; // <==== Bug correction
|
||||
}
|
||||
rowCount = 1;
|
||||
padCount = 0;
|
||||
rowIndex = size - biWidth;
|
||||
@ -137,14 +139,15 @@ public class BMPFile extends Component {
|
||||
rowCount = 1;
|
||||
rowIndex = lastRowIndex - biWidth;
|
||||
lastRowIndex = rowIndex;
|
||||
} else
|
||||
} else {
|
||||
rowCount++;
|
||||
}
|
||||
rowIndex++;
|
||||
}
|
||||
// --- Update the size of the file
|
||||
bfSize += padCount - pad;
|
||||
biSizeImage += padCount - pad;
|
||||
} catch (Exception wb) {
|
||||
} catch (final Exception wb) {
|
||||
wb.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -160,7 +163,7 @@ public class BMPFile extends Component {
|
||||
fo.write(intToWord(bfReserved1));
|
||||
fo.write(intToWord(bfReserved2));
|
||||
fo.write(intToDWord(bfOffBits));
|
||||
} catch (Exception wbfh) {
|
||||
} catch (final Exception wbfh) {
|
||||
wbfh.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -184,7 +187,7 @@ public class BMPFile extends Component {
|
||||
fo.write(intToDWord(biYPelsPerMeter));
|
||||
fo.write(intToDWord(biClrUsed));
|
||||
fo.write(intToDWord(biClrImportant));
|
||||
} catch (Exception wbih) {
|
||||
} catch (final Exception wbih) {
|
||||
wbih.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -196,7 +199,7 @@ public class BMPFile extends Component {
|
||||
*
|
||||
*/
|
||||
private byte[] intToWord(int parValue) {
|
||||
byte retValue[] = new byte[2];
|
||||
final byte retValue[] = new byte[2];
|
||||
retValue[0] = (byte) (parValue & 0x00FF);
|
||||
retValue[1] = (byte) ((parValue >> 8) & 0x00FF);
|
||||
return (retValue);
|
||||
@ -209,7 +212,7 @@ public class BMPFile extends Component {
|
||||
*
|
||||
*/
|
||||
private byte[] intToDWord(int parValue) {
|
||||
byte retValue[] = new byte[4];
|
||||
final byte retValue[] = new byte[4];
|
||||
retValue[0] = (byte) (parValue & 0x00FF);
|
||||
retValue[1] = (byte) ((parValue >> 8) & 0x000000FF);
|
||||
retValue[2] = (byte) ((parValue >> 16) & 0x000000FF);
|
||||
|
10
src/org/warp/picalculator/KeyboardTest.java
Normal file
10
src/org/warp/picalculator/KeyboardTest.java
Normal file
@ -0,0 +1,10 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import org.warp.picalculator.gui.screens.KeyboardDebugScreen;
|
||||
|
||||
public class KeyboardTest {
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
new Main(new KeyboardDebugScreen());
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import org.warp.picalculator.device.Keyboard;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.screens.LoadingScreen;
|
||||
import org.warp.picalculator.gui.screens.Screen;
|
||||
|
||||
import com.pi4j.wiringpi.Gpio;
|
||||
|
||||
@ -12,42 +13,44 @@ public class Main {
|
||||
public static final boolean zoomed = true;
|
||||
public static Main instance;
|
||||
public static boolean haxMode = true;
|
||||
public static String[] args;
|
||||
|
||||
public Main() throws InterruptedException {
|
||||
public Main(String[] args) throws InterruptedException {
|
||||
this(new LoadingScreen(), args);
|
||||
}
|
||||
|
||||
public Main(Screen screen, String[] args) {
|
||||
instance = this;
|
||||
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
|
||||
Thread.currentThread().setName("Main thread");
|
||||
this.args = args;
|
||||
beforeStart();
|
||||
new PIDisplay(new LoadingScreen());
|
||||
new DisplayManager(screen);
|
||||
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")) {
|
||||
if (Utils.isRunningOnRaspberry() && !Utils.isInArray("-noraspi", args)) {
|
||||
Gpio.wiringPiSetupPhys();
|
||||
Gpio.pinMode(12, Gpio.PWM_OUTPUT);
|
||||
} else {
|
||||
screenPos = new int[]{0,0};
|
||||
screenPos = new int[] { 0, 0 };
|
||||
Utils.debugOn = true;
|
||||
}
|
||||
Utils.debugThirdScreen = Utils.debugOn & false;
|
||||
PIDisplay.setBrightness(0.5f);
|
||||
}
|
||||
|
||||
|
||||
public void afterStart() {
|
||||
DisplayManager.setBrightness(0.5f);
|
||||
Keyboard.startKeyboard();
|
||||
}
|
||||
|
||||
|
||||
public void beforeShutdown() {
|
||||
Keyboard.stopKeyboard();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
new Main();
|
||||
new Main(args);
|
||||
}
|
||||
}
|
||||
|
@ -1,57 +1,85 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
import org.warp.picalculator.gui.graphicengine.Drawable;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWSkin;
|
||||
import org.warp.picalculator.gui.graphicengine.gpu.GPUDisplay;
|
||||
import org.warp.picalculator.gui.graphicengine.gpu.GPURenderer;
|
||||
import org.warp.picalculator.gui.screens.LoadingScreen;
|
||||
import org.warp.picalculator.gui.screens.KeyboardDebugScreen;
|
||||
import org.warp.picalculator.gui.screens.MarioScreen;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TestGPU {
|
||||
|
||||
public static final GPUDisplay d = new GPUDisplay();
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
new Main(new KeyboardDebugScreen());
|
||||
if (true) return;
|
||||
Utils.debugOn = true;
|
||||
Utils.debugThirdScreen = false;
|
||||
d.create();
|
||||
|
||||
Scene s = new Scene(d);
|
||||
|
||||
final Scene s = new Scene(d);
|
||||
}
|
||||
|
||||
|
||||
private static class Scene implements Drawable {
|
||||
|
||||
private RAWFont[] fonts;
|
||||
private int[] textures;
|
||||
|
||||
private GPURenderer r;
|
||||
private Display d;
|
||||
|
||||
public Scene(Display d) {
|
||||
private RAWFont exampleFont;
|
||||
private final RAWSkin exampleSkin;
|
||||
|
||||
private final GPURenderer r;
|
||||
private final Display d;
|
||||
|
||||
public Scene(Display d) throws IOException {
|
||||
this.d = d;
|
||||
this.r = (GPURenderer) d.getRenderer();
|
||||
r = (GPURenderer) d.getRenderer();
|
||||
|
||||
exampleFont = d.loadFont("ex");
|
||||
|
||||
exampleSkin = d.loadSkin("skin.png");
|
||||
|
||||
d.start(this);
|
||||
|
||||
// fonts = new RAWFont[1];
|
||||
// textures = new int[100];
|
||||
// fonts[0] = new RAWFont();
|
||||
// fonts[0].create("big");
|
||||
new Thread(()->{
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(60000);
|
||||
} catch (InterruptedException e) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
Utils.printSystemResourcesUsage();
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.exit(0);
|
||||
}).start();
|
||||
|
||||
d.waitUntilExit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
exampleSkin.use(d);
|
||||
r.glClearColor(0xFFD0FDCF);
|
||||
r.glClear(d.getWidth(), d.getHeight());
|
||||
r.glColor3f(1.0f, 1.0f, 1.0f);
|
||||
r.glFillRect(2, 2, 160, 160, 0, 0, 16, 16);
|
||||
exampleFont.use(d);
|
||||
r.glColor3f(1, 0, 0);
|
||||
r.glDrawStringLeft(10, 170, "Prova! 123456789");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,17 @@
|
||||
package org.warp.picalculator;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
@ -12,7 +20,7 @@ import java.util.List;
|
||||
|
||||
import org.nevec.rjm.BigDecimalMath;
|
||||
import org.nevec.rjm.Rational;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.math.functions.AnteriorFunction;
|
||||
import org.warp.picalculator.math.functions.Division;
|
||||
@ -45,7 +53,7 @@ public class Utils {
|
||||
public static boolean debugThirdScreen;
|
||||
|
||||
public static Cloner cloner = new Cloner();
|
||||
|
||||
|
||||
public static final class DebugStream extends StringWriter {
|
||||
|
||||
public void println(String str) {
|
||||
@ -61,7 +69,7 @@ public class Utils {
|
||||
|
||||
public static boolean isInArray(String ch, String[] a) {
|
||||
boolean contains = false;
|
||||
for (String c : a) {
|
||||
for (final String c : a) {
|
||||
if (c.equals(ch)) {
|
||||
contains = true;
|
||||
break;
|
||||
@ -70,13 +78,13 @@ public class Utils {
|
||||
return contains;
|
||||
}
|
||||
|
||||
private static final String[] regexNormalSymbols = new String[]{"\\", ".", "[", "]", "{", "}", "(", ")", "*", "+", "-", "?", "^", "$", "|"};
|
||||
|
||||
private static final String[] regexNormalSymbols = new String[] { "\\", ".", "[", "]", "{", "}", "(", ")", "*", "+", "-", "?", "^", "$", "|" };
|
||||
|
||||
public static String ArrayToRegex(String[] array) {
|
||||
String regex = null;
|
||||
for (String symbol : array) {
|
||||
for (final String symbol : array) {
|
||||
boolean contained = false;
|
||||
for (String smb : regexNormalSymbols) {
|
||||
for (final String smb : regexNormalSymbols) {
|
||||
if (smb.equals(symbol)) {
|
||||
contained = true;
|
||||
break;
|
||||
@ -100,17 +108,17 @@ public class Utils {
|
||||
}
|
||||
|
||||
public static String[] concat(String[] a, String[] b) {
|
||||
int aLen = a.length;
|
||||
int bLen = b.length;
|
||||
String[] c = new String[aLen + bLen];
|
||||
final int aLen = a.length;
|
||||
final int bLen = b.length;
|
||||
final 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];
|
||||
final int aLen = a.length;
|
||||
final String[] c = new String[aLen + 1];
|
||||
System.arraycopy(a, 0, c, 0, aLen);
|
||||
c[aLen] = b;
|
||||
return c;
|
||||
@ -213,7 +221,7 @@ public class Utils {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean areThereEmptyMultiplications(ArrayList<Function> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division) {
|
||||
@ -249,7 +257,7 @@ public class Utils {
|
||||
|
||||
public static boolean areThereOtherSettedUpFunctions(ArrayList<Function> fl) {
|
||||
for (int i = 0; i < fl.size(); i++) {
|
||||
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Expression || fl.get(i) instanceof AnteriorFunction || fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division)) {
|
||||
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Expression || fl.get(i) instanceof AnteriorFunction || fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division)) {
|
||||
if (fl.get(i) instanceof AnteriorFunction) {
|
||||
if (((AnteriorFunction) fl.get(i)).getVariable() == null) {
|
||||
return true;
|
||||
@ -269,7 +277,7 @@ public class Utils {
|
||||
public static Rational getRational(BigDecimal str) {
|
||||
try {
|
||||
return getRational(str.toString());
|
||||
} catch (Error e) {
|
||||
} catch (final Error e) {
|
||||
//E' IMPOSSIBILE CHE VENGA THROWATO UN ERRORE
|
||||
return new Rational("0");
|
||||
}
|
||||
@ -278,17 +286,17 @@ public class Utils {
|
||||
public static Rational getRational(String str) throws Error {
|
||||
try {
|
||||
return new Rational(str);
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch (final 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));
|
||||
final 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
|
||||
final long sign = bits >>> 63;
|
||||
final long exponent = ((bits >>> 52) ^ (sign << 11)) - 1023;
|
||||
final long fraction = bits << 12; // bits are "reversed" but that's
|
||||
// not a problem
|
||||
|
||||
long a = 1L;
|
||||
long b = 1L;
|
||||
@ -298,13 +306,15 @@ public class Utils {
|
||||
b *= 2;
|
||||
}
|
||||
|
||||
if (exponent > 0)
|
||||
if (exponent > 0) {
|
||||
a *= 1 << exponent;
|
||||
else
|
||||
} else {
|
||||
b *= 1 << -exponent;
|
||||
}
|
||||
|
||||
if (sign == 1)
|
||||
if (sign == 1) {
|
||||
a *= -1;
|
||||
}
|
||||
|
||||
if (b == 0) {
|
||||
a = 0;
|
||||
@ -313,11 +323,11 @@ public class Utils {
|
||||
|
||||
return new Rational(new BigInteger(a + ""), new BigInteger(b + ""));
|
||||
} else {
|
||||
BigDecimal original = new BigDecimal(str);
|
||||
final BigDecimal original = new BigDecimal(str);
|
||||
|
||||
BigInteger numerator = original.unscaledValue();
|
||||
final BigInteger numerator = original.unscaledValue();
|
||||
|
||||
BigInteger denominator = BigDecimalMath.pow(BigDecimal.TEN, new BigDecimal(original.scale())).toBigIntegerExact();
|
||||
final BigInteger denominator = BigDecimalMath.pow(BigDecimal.TEN, new BigDecimal(original.scale())).toBigIntegerExact();
|
||||
|
||||
return new Rational(numerator, denominator);
|
||||
}
|
||||
@ -332,7 +342,7 @@ public class Utils {
|
||||
if (variables.size() != variables2.size()) {
|
||||
return false;
|
||||
} else {
|
||||
for (Variable v : variables) {
|
||||
for (final Variable v : variables) {
|
||||
if (!variables2.contains(v)) {
|
||||
return false;
|
||||
}
|
||||
@ -343,17 +353,17 @@ public class Utils {
|
||||
|
||||
public static void writeSquareRoot(Function 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;
|
||||
|
||||
final int w1 = var.getWidth();
|
||||
final int h1 = var.getHeight();
|
||||
final int wsegno = 5;
|
||||
final int hsegno = h1 + 2;
|
||||
|
||||
var.draw(x + wsegno, y + (hsegno - h1));
|
||||
|
||||
PIDisplay.renderer.glDrawLine(x + 1, y + hsegno - 3, x + 3, y + hsegno - 1);
|
||||
PIDisplay.renderer.glDrawLine(x + 3, y + (hsegno - 1) / 2 + 1, x + 3, y + hsegno - 1);
|
||||
PIDisplay.renderer.glDrawLine(x + 4, y, x + 4, y + (hsegno - 1) / 2);
|
||||
PIDisplay.renderer.glDrawLine(x + 4, y, x + 4 + 1 + w1 + 1, y);
|
||||
DisplayManager.renderer.glDrawLine(x + 1, y + hsegno - 3, x + 3, y + hsegno - 1);
|
||||
DisplayManager.renderer.glDrawLine(x + 3, y + (hsegno - 1) / 2 + 1, x + 3, y + hsegno - 1);
|
||||
DisplayManager.renderer.glDrawLine(x + 4, y, x + 4, y + (hsegno - 1) / 2);
|
||||
DisplayManager.renderer.glDrawLine(x + 4, y, x + 4 + 1 + w1 + 1, y);
|
||||
}
|
||||
|
||||
public static final int getFontHeight() {
|
||||
@ -365,7 +375,7 @@ public class Utils {
|
||||
}
|
||||
|
||||
public static final RAWFont getFont(boolean small, boolean zoomed) {
|
||||
return PIDisplay.fonts[getFontIndex(small, zoomed)];
|
||||
return DisplayManager.fonts[getFontIndex(small, zoomed)];
|
||||
}
|
||||
|
||||
public static final int getFontIndex(boolean small, boolean zoomed) {
|
||||
@ -387,56 +397,56 @@ public class Utils {
|
||||
public static final int getFontHeight(boolean small) {
|
||||
return getFontHeight(small, Main.zoomed);
|
||||
}
|
||||
|
||||
|
||||
public static final int getFontHeight(boolean small, boolean zoomed) {
|
||||
if (small) {
|
||||
if (zoomed) {
|
||||
return PIDisplay.glyphsHeight[3];
|
||||
return DisplayManager.glyphsHeight[3];
|
||||
} else {
|
||||
return PIDisplay.glyphsHeight[1];
|
||||
return DisplayManager.glyphsHeight[1];
|
||||
}
|
||||
} else {
|
||||
if (zoomed) {
|
||||
return PIDisplay.glyphsHeight[2];
|
||||
return DisplayManager.glyphsHeight[2];
|
||||
} else {
|
||||
return PIDisplay.glyphsHeight[0];
|
||||
return DisplayManager.glyphsHeight[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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];
|
||||
}
|
||||
// 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();
|
||||
final byte[] buffer = new byte[(int) size];
|
||||
final 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();
|
||||
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];
|
||||
final int len = bytes.length;
|
||||
final int[] realbytes = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
realbytes[i] = Byte.toUnsignedInt(bytes[i]);
|
||||
}
|
||||
return realbytes;
|
||||
}
|
||||
|
||||
|
||||
public static boolean allSolved(List<Function> expressions) throws Error {
|
||||
for (Function itm : expressions) {
|
||||
for (final Function itm : expressions) {
|
||||
if (itm.isSolved() == false) {
|
||||
return false;
|
||||
}
|
||||
@ -445,29 +455,33 @@ public class Utils {
|
||||
}
|
||||
|
||||
public static Function[][] joinFunctionsResults(List<Function> l1, List<Function> l2) {
|
||||
int size1 = l1.size();
|
||||
int size2 = l2.size();
|
||||
final int size1 = l1.size();
|
||||
final int size2 = l2.size();
|
||||
int cur1 = 0;
|
||||
int cur2 = 0;
|
||||
int total = l1.size()*l2.size();
|
||||
Function[][] results = new Function[total][2];
|
||||
final int total = l1.size() * l2.size();
|
||||
final Function[][] results = new Function[total][2];
|
||||
for (int i = 0; i < total; i++) {
|
||||
results[i] = new Function[]{l1.get(cur1), l2.get(cur2)};
|
||||
results[i] = new Function[] { l1.get(cur1), l2.get(cur2) };
|
||||
if (i % size2 == 0) {
|
||||
cur1+=1;
|
||||
cur1 += 1;
|
||||
}
|
||||
if (i % size1 == 0) {
|
||||
cur2+=1;
|
||||
cur2 += 1;
|
||||
}
|
||||
if (cur1 >= size1) {
|
||||
cur1 = 0;
|
||||
}
|
||||
if (cur2 >= size2) {
|
||||
cur2 = 0;
|
||||
}
|
||||
if (cur1 >= size1) cur1 = 0;
|
||||
if (cur2 >= size2) cur2 = 0;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static boolean isNegative(Function b) {
|
||||
if (b instanceof Negative) {
|
||||
return true;
|
||||
return true;
|
||||
} else if (b instanceof Number && ((Number) b).getTerm().compareTo(BigDecimal.ZERO) < 0) {
|
||||
return true;
|
||||
}
|
||||
@ -477,28 +491,97 @@ public class Utils {
|
||||
public static CharSequence multipleChars(String string, int i) {
|
||||
String result = "";
|
||||
for (int j = 0; j < i; j++) {
|
||||
result+=string;
|
||||
result += string;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isIntegerValue(BigDecimal bd) {
|
||||
return bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0;
|
||||
return bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0;
|
||||
}
|
||||
|
||||
public static <T> String arrayToString(T... data) {
|
||||
String sdata = "";
|
||||
for (T o : data) {
|
||||
sdata += ","+o.toString();
|
||||
for (final T o : data) {
|
||||
sdata += "," + o.toString();
|
||||
}
|
||||
return sdata.substring(1);
|
||||
}
|
||||
|
||||
public static String arrayToString(boolean... data) {
|
||||
String sdata = "";
|
||||
for (boolean o : data) {
|
||||
sdata += (o)?1:0;
|
||||
for (final boolean o : data) {
|
||||
sdata += (o) ? 1 : 0;
|
||||
}
|
||||
return sdata;
|
||||
}
|
||||
|
||||
public static void printSystemResourcesUsage() {
|
||||
System.out.println("============");
|
||||
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) {
|
||||
method.setAccessible(true);
|
||||
if (method.getName().startsWith("get") && Modifier.isPublic(method.getModifiers())) {
|
||||
Object value;
|
||||
try {
|
||||
value = method.invoke(operatingSystemMXBean);
|
||||
} catch (Exception e) {
|
||||
value = e;
|
||||
} // try
|
||||
boolean percent = false;
|
||||
boolean mb = false;
|
||||
String displayName = method.getName();
|
||||
String displayValue = value.toString();
|
||||
if (displayName.endsWith("CpuLoad")) {
|
||||
percent = true;
|
||||
}
|
||||
if (displayName.endsWith("MemorySize")) {
|
||||
mb = true;
|
||||
}
|
||||
ArrayList<String> arr = new ArrayList<>();
|
||||
arr.add("getFreePhysicalMemorySize");
|
||||
arr.add("getProcessCpuLoad");
|
||||
arr.add("getSystemCpuLoad");
|
||||
arr.add("getTotalPhysicalMemorySize");
|
||||
if (arr.contains(displayName)) {
|
||||
if (percent) {
|
||||
try {
|
||||
System.out.println(displayName + " = " + (((int)(Float.parseFloat(displayValue) * 10000f))/100f) + "%");
|
||||
}catch(Exception ex) {
|
||||
System.out.println(displayName + " = " + displayValue);
|
||||
}
|
||||
} else if (mb) {
|
||||
try {
|
||||
System.out.println(displayName + " = " + (Long.parseLong(displayValue) / 1024L / 1024L) + " MB");
|
||||
}catch(Exception ex) {
|
||||
System.out.println(displayName + " = " + displayValue);
|
||||
}
|
||||
} else {
|
||||
System.out.println(displayName + " = " + displayValue);
|
||||
}
|
||||
}
|
||||
} // if
|
||||
} // for
|
||||
System.out.println("============");
|
||||
}
|
||||
|
||||
public static boolean isRunningOnRaspberry() {
|
||||
if (System.getProperty("os.name").equals("Linux")) {
|
||||
final File file = new File("/etc", "os-release");
|
||||
try (FileInputStream fis = new FileInputStream(file);
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis))) {
|
||||
String string;
|
||||
while ((string = bufferedReader.readLine()) != null) {
|
||||
if (string.toLowerCase().contains("raspbian")) {
|
||||
if (string.toLowerCase().contains("name")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,7 @@ import java.awt.event.KeyEvent;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.device.chip.ParallelToSerial;
|
||||
import org.warp.picalculator.device.chip.SerialToParallel;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.screens.KeyboardDebugScreen;
|
||||
import org.warp.picalculator.gui.screens.MarioScreen;
|
||||
import org.warp.picalculator.gui.screens.Screen;
|
||||
@ -16,7 +15,7 @@ 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;
|
||||
@ -29,21 +28,20 @@ public class Keyboard {
|
||||
|
||||
private static volatile boolean[][] precedentStates = new boolean[8][8];
|
||||
public static volatile boolean[][] debugKeysDown = new boolean[8][8];
|
||||
public static volatile KeyEvent debugKeyEvent;
|
||||
|
||||
public static volatile int debugKeyCode = -1;
|
||||
|
||||
public static void startKeyboard() {
|
||||
Thread kt = new Thread(()->{
|
||||
final Thread kt = new Thread(() -> {
|
||||
if (Utils.debugOn) {
|
||||
try {
|
||||
while(true) {
|
||||
if (debugKeyEvent != null) {
|
||||
debugKeyPressed(debugKeyEvent);
|
||||
debugKeyEvent = null;
|
||||
while (true) {
|
||||
if (debugKeyCode != -1) {
|
||||
debugKeyPressed(debugKeyCode);
|
||||
debugKeyCode = -1;
|
||||
}
|
||||
Thread.sleep(50);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
} catch (final InterruptedException e) {}
|
||||
} else {
|
||||
Gpio.pinMode(CLK_INH_pin, Gpio.OUTPUT);
|
||||
Gpio.pinMode(RCK_pin, Gpio.OUTPUT);
|
||||
@ -51,36 +49,36 @@ public class Keyboard {
|
||||
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);
|
||||
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*/);
|
||||
|
||||
final SerialToParallel chip1 = new SerialToParallel(RCK_pin, SCK_and_CLK_pin /*SCK*/, SER_pin);
|
||||
final ParallelToSerial chip2 = new ParallelToSerial(SH_LD_pin, CLK_INH_pin, QH_pin, SCK_and_CLK_pin/*CLK*/);
|
||||
|
||||
KeyboardDebugScreen.log("Started keyboard system");
|
||||
|
||||
while(true) {
|
||||
|
||||
while (true) {
|
||||
boolean[] data;
|
||||
for (int col = 0; col < 8; col++) {
|
||||
data = new boolean[8];
|
||||
data[col] = true;
|
||||
chip1.write(data);
|
||||
|
||||
|
||||
data = chip2.read();
|
||||
KeyboardDebugScreen.ks[col] = data;
|
||||
|
||||
|
||||
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));
|
||||
KeyboardDebugScreen.log("Pressed button at "+(row+1) +", "+(col+1));
|
||||
keyPressedRaw(row+1, col+1);
|
||||
System.out.println("Pressed button at " + (row + 1) + ", " + (col + 1));
|
||||
KeyboardDebugScreen.log("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);
|
||||
KeyboardDebugScreen.log("Released button at "+(row+1) +", "+(col+1));
|
||||
keyReleasedRaw(row + 1, col + 1);
|
||||
KeyboardDebugScreen.log("Released button at " + (row + 1) + ", " + (col + 1));
|
||||
}
|
||||
precedentStates[row][col] = data[row];
|
||||
}
|
||||
@ -94,8 +92,8 @@ public class Keyboard {
|
||||
kt.start();
|
||||
}
|
||||
|
||||
private static void debugKeyPressed(KeyEvent arg0) {
|
||||
switch (arg0.getKeyCode()) {
|
||||
private static void debugKeyPressed(int keyCode) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
Keyboard.keyPressed(Key.POWER);
|
||||
break;
|
||||
@ -177,6 +175,7 @@ public class Keyboard {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_ENTER:
|
||||
case KeyEvent.VK_ENTER:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.SIMPLIFY);
|
||||
@ -187,7 +186,7 @@ public class Keyboard {
|
||||
}
|
||||
int row = 2;
|
||||
int col = 1;
|
||||
Keyboard.debugKeysDown[row-1][col-1] = true;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = true;
|
||||
break;
|
||||
case KeyEvent.VK_1:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
@ -265,6 +264,7 @@ public class Keyboard {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_ADD:
|
||||
case KeyEvent.VK_ADD:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.PLUS);
|
||||
@ -274,6 +274,7 @@ public class Keyboard {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_SUBTRACT:
|
||||
case KeyEvent.VK_SUBTRACT:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.MINUS);
|
||||
@ -281,6 +282,7 @@ public class Keyboard {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_MULTIPLY:
|
||||
case KeyEvent.VK_MULTIPLY:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.MULTIPLY);
|
||||
@ -288,6 +290,7 @@ public class Keyboard {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_DIVIDE:
|
||||
case KeyEvent.VK_DIVIDE:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.DIVIDE);
|
||||
@ -302,6 +305,7 @@ public class Keyboard {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_DELETE:
|
||||
case KeyEvent.VK_DELETE:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.RESET);
|
||||
@ -309,28 +313,31 @@ public class Keyboard {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_LEFT:
|
||||
case KeyEvent.VK_LEFT:
|
||||
//LEFT
|
||||
row = 2;
|
||||
col = 3;
|
||||
Keyboard.debugKeysDown[row-1][col-1] = true;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = true;
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LEFT);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_RIGHT:
|
||||
case KeyEvent.VK_RIGHT:
|
||||
//RIGHT
|
||||
row = 2;
|
||||
col = 5;
|
||||
Keyboard.debugKeysDown[row-1][col-1] = true;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = true;
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.RIGHT);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_NUMPAD4:
|
||||
case KeyEvent.VK_NUMPAD4:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.HISTORY_BACK);
|
||||
@ -338,6 +345,7 @@ public class Keyboard {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_NUMPAD6:
|
||||
case KeyEvent.VK_NUMPAD6:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.HISTORY_FORWARD);
|
||||
@ -352,21 +360,26 @@ public class Keyboard {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_SHIFT:
|
||||
case KeyEvent.VK_SHIFT:
|
||||
Keyboard.keyPressed(Key.SHIFT);
|
||||
break;
|
||||
case KeyEvent.VK_A:
|
||||
Keyboard.keyPressed(Key.ALPHA);
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_NUMPAD1:
|
||||
case KeyEvent.VK_NUMPAD1:
|
||||
Keyboard.keyPressed(Key.SQRT);
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_NUMPAD2:
|
||||
case KeyEvent.VK_NUMPAD2:
|
||||
Keyboard.keyPressed(Key.ROOT);
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_NUMPAD3:
|
||||
case KeyEvent.VK_NUMPAD3:
|
||||
Keyboard.keyPressed(Key.POWER_OF_2);
|
||||
break;
|
||||
case com.jogamp.newt.event.KeyEvent.VK_NUMPAD5:
|
||||
case KeyEvent.VK_NUMPAD5:
|
||||
Keyboard.keyPressed(Key.POWER_OF_x);
|
||||
break;
|
||||
@ -375,12 +388,12 @@ public class Keyboard {
|
||||
|
||||
public static boolean isKeyDown(int row, int col) {
|
||||
if (Utils.debugOn == false) {
|
||||
return precedentStates[row-1][col-1];
|
||||
return precedentStates[row - 1][col - 1];
|
||||
} else {
|
||||
return debugKeysDown[row-1][col-1];
|
||||
return debugKeysDown[row - 1][col - 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void keyReleasedRaw(int row, int col) {
|
||||
KeyboardDebugScreen.keyX = row;
|
||||
KeyboardDebugScreen.keyY = col;
|
||||
@ -395,7 +408,7 @@ public class Keyboard {
|
||||
if (row == 1 && col == 1) {
|
||||
keyPressed(Key.SHIFT);
|
||||
} else if (row == 1 && col == 2) {
|
||||
keyPressed(Key.ALPHA);
|
||||
keyPressed(Key.ALPHA);
|
||||
} else if (row == 1 && col == 7) {
|
||||
if (shift) {
|
||||
keyPressed(Key.BRIGHTNESS_CYCLE_REVERSE);
|
||||
@ -580,7 +593,7 @@ public class Keyboard {
|
||||
} else {
|
||||
keyPressed(Key.LEFT);
|
||||
}
|
||||
} else if (row ==2 && col == 5) {
|
||||
} else if (row == 2 && col == 5) {
|
||||
if (shift) {
|
||||
keyPressed(Key.NONE);
|
||||
} else if (alpha) {
|
||||
@ -664,8 +677,7 @@ public class Keyboard {
|
||||
System.out.println("PREMUTO >");
|
||||
keyPressed(Key.HISTORY_FORWARD);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else {}
|
||||
}
|
||||
|
||||
public static void stopKeyboard() {
|
||||
@ -680,15 +692,15 @@ public class Keyboard {
|
||||
}
|
||||
|
||||
public static void keyPressed(Key k) {
|
||||
if (PIDisplay.INSTANCE != null) {
|
||||
Screen scr = PIDisplay.INSTANCE.getScreen();
|
||||
if (DisplayManager.INSTANCE != null) {
|
||||
final Screen scr = DisplayManager.INSTANCE.getScreen();
|
||||
boolean refresh = false;
|
||||
if(scr != null && scr.initialized && scr.keyPressed(k)) {
|
||||
if (scr != null && scr.initialized && scr.keyPressed(k)) {
|
||||
refresh = true;
|
||||
} else {
|
||||
switch (k) {
|
||||
case POWER:
|
||||
PIDisplay.display.destroy();
|
||||
DisplayManager.display.destroy();
|
||||
break;
|
||||
case NONE:
|
||||
break;
|
||||
@ -696,20 +708,20 @@ public class Keyboard {
|
||||
letterPressed('X');
|
||||
break;
|
||||
case BRIGHTNESS_CYCLE:
|
||||
PIDisplay.cycleBrightness(false);
|
||||
DisplayManager.cycleBrightness(false);
|
||||
refresh = true;
|
||||
break;
|
||||
case BRIGHTNESS_CYCLE_REVERSE:
|
||||
PIDisplay.INSTANCE.setScreen(new MarioScreen()); //TODO: rimuovere: prova
|
||||
PIDisplay.cycleBrightness(true);
|
||||
DisplayManager.INSTANCE.setScreen(new MarioScreen()); //TODO: rimuovere: prova
|
||||
DisplayManager.cycleBrightness(true);
|
||||
refresh = true;
|
||||
break;
|
||||
case HISTORY_BACK:
|
||||
PIDisplay.INSTANCE.goBack();
|
||||
DisplayManager.INSTANCE.goBack();
|
||||
refresh = true;
|
||||
break;
|
||||
case HISTORY_FORWARD:
|
||||
PIDisplay.INSTANCE.goForward();
|
||||
DisplayManager.INSTANCE.goForward();
|
||||
refresh = true;
|
||||
break;
|
||||
default:
|
||||
@ -736,20 +748,20 @@ public class Keyboard {
|
||||
refresh = true;
|
||||
}
|
||||
if (refresh) {
|
||||
PIDisplay.display.repaint();
|
||||
// PIDisplay.display.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void letterPressed(char L) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void keyReleased(Key k) {
|
||||
boolean refresh = false;
|
||||
if (PIDisplay.INSTANCE != null) {
|
||||
Screen scr = PIDisplay.INSTANCE.getScreen();
|
||||
if(scr != null && scr.initialized && scr.keyReleased(k)) {
|
||||
if (DisplayManager.INSTANCE != null) {
|
||||
final Screen scr = DisplayManager.INSTANCE.getScreen();
|
||||
if (scr != null && scr.initialized && scr.keyReleased(k)) {
|
||||
refresh = true;
|
||||
} else {
|
||||
switch (k) {
|
||||
@ -760,26 +772,17 @@ public class Keyboard {
|
||||
}
|
||||
}
|
||||
if (refresh) {
|
||||
PIDisplay.display.repaint();
|
||||
// PIDisplay.display.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Key {
|
||||
POWER, debug_DEG, debug_RAD, debug_GRA, SHIFT, ALPHA, NONE,
|
||||
HISTORY_BACK, HISTORY_FORWARD, SURD_MODE, DRG_CYCLE,
|
||||
LETTER_X, LETTER_Y, SIMPLIFY, SOLVE, BRIGHTNESS_CYCLE,
|
||||
BRIGHTNESS_CYCLE_REVERSE, DOT, NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7, NUM8, NUM9,
|
||||
PARENTHESIS_OPEN, PARENTHESIS_CLOSE, PLUS, MINUS, 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,
|
||||
SINE, COSINE, TANGENT, ARCSINE, ARCCOSINE, ARCTANGENT, PI
|
||||
POWER, debug_DEG, debug_RAD, debug_GRA, SHIFT, ALPHA, NONE, HISTORY_BACK, HISTORY_FORWARD, SURD_MODE, DRG_CYCLE, LETTER_X, LETTER_Y, SIMPLIFY, SOLVE, BRIGHTNESS_CYCLE, BRIGHTNESS_CYCLE_REVERSE, DOT, NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7, NUM8, NUM9, PARENTHESIS_OPEN, PARENTHESIS_CLOSE, PLUS, MINUS, 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, SINE, COSINE, TANGENT, ARCSINE, ARCCOSINE, ARCTANGENT, PI
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
@ -3,11 +3,11 @@ 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;
|
||||
|
||||
private final int SH_LD;
|
||||
private final int CLK_INH;
|
||||
private final int QH;
|
||||
private final int CLK;
|
||||
|
||||
public ParallelToSerial(int SH_LD_pin, int CLK_INH_pin, int QH_pin, int CLK_pin) {
|
||||
SH_LD = SH_LD_pin;
|
||||
@ -17,19 +17,19 @@ public class ParallelToSerial {
|
||||
}
|
||||
|
||||
public boolean[] read() {
|
||||
boolean[] data = new boolean[8];
|
||||
final 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;
|
||||
data[i] = Gpio.digitalRead(QH) == Gpio.HIGH ? true : false;
|
||||
}
|
||||
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -3,28 +3,28 @@ 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
|
||||
|
||||
private final int RCK; //Storage register clock pin (latch pin)
|
||||
private final int SCK; //Shift register clock pin
|
||||
private final 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);
|
||||
}
|
||||
}
|
||||
|
494
src/org/warp/picalculator/gui/DisplayManager.java
Normal file
494
src/org/warp/picalculator/gui/DisplayManager.java
Normal file
@ -0,0 +1,494 @@
|
||||
package org.warp.picalculator.gui;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.device.Keyboard;
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
import org.warp.picalculator.gui.graphicengine.Drawable;
|
||||
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.gui.graphicengine.gpu.GPUDisplay;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWSkin;
|
||||
import org.warp.picalculator.gui.screens.Screen;
|
||||
|
||||
import com.pi4j.wiringpi.Gpio;
|
||||
|
||||
public final class DisplayManager implements Drawable {
|
||||
public static DisplayManager INSTANCE;
|
||||
private static float brightness;
|
||||
|
||||
public static final Display display = chooseGraphicEngine();
|
||||
public static Renderer renderer;
|
||||
|
||||
private static RAWSkin skin;
|
||||
public static RAWFont[] fonts;
|
||||
|
||||
public static String error = null;
|
||||
public String[] errorStackTrace = null;
|
||||
public final static int[] glyphsHeight = new int[] { 9, 6, 12, 9 };
|
||||
|
||||
public static Screen screen;
|
||||
public static String displayDebugString = "";
|
||||
|
||||
public DisplayManager(Screen screen) {
|
||||
setScreen(screen);
|
||||
INSTANCE = this;
|
||||
loop();
|
||||
}
|
||||
/*
|
||||
* 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();
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
private static Display chooseGraphicEngine() {
|
||||
Display d;
|
||||
d = new GPUDisplay();
|
||||
if (d.isSupported()) return d;
|
||||
d = new CPUDisplay();
|
||||
if (d.isSupported()) return d;
|
||||
throw new UnsupportedOperationException("No graphic engines available.");
|
||||
}
|
||||
|
||||
public void setScreen(Screen screen) {
|
||||
if (screen.initialized == false) {
|
||||
if (screen.canBeInHistory) {
|
||||
DisplayManager.currentSession = 0;
|
||||
for (int i = DisplayManager.sessions.length - 1; i >= 1; i--) {
|
||||
DisplayManager.sessions[i] = DisplayManager.sessions[i - 1];
|
||||
}
|
||||
DisplayManager.sessions[0] = screen;
|
||||
} else {
|
||||
DisplayManager.currentSession = -1;
|
||||
}
|
||||
}
|
||||
screen.d = this;
|
||||
try {
|
||||
screen.create();
|
||||
DisplayManager.screen = screen;
|
||||
if (screen.initialized == false) {
|
||||
screen.initialize();
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void replaceScreen(Screen screen) {
|
||||
if (screen.initialized == false) {
|
||||
if (screen.canBeInHistory) {
|
||||
DisplayManager.sessions[DisplayManager.currentSession] = screen;
|
||||
} else {
|
||||
DisplayManager.currentSession = -1;
|
||||
for (int i = 0; i < DisplayManager.sessions.length - 2; i++) {
|
||||
DisplayManager.sessions[i] = DisplayManager.sessions[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
screen.d = this;
|
||||
try {
|
||||
screen.create();
|
||||
DisplayManager.screen = screen;
|
||||
if (screen.initialized == false) {
|
||||
screen.initialize();
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canGoBack() {
|
||||
if (DisplayManager.currentSession == -1) {
|
||||
return DisplayManager.sessions[0] != null;
|
||||
}
|
||||
if (DisplayManager.screen != DisplayManager.sessions[DisplayManager.currentSession]) {
|
||||
|
||||
} else if (DisplayManager.currentSession + 1 < DisplayManager.sessions.length) {
|
||||
if (DisplayManager.sessions[DisplayManager.currentSession + 1] != null) {
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (DisplayManager.sessions[DisplayManager.currentSession] != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void goBack() {
|
||||
if (canGoBack()) {
|
||||
if (DisplayManager.currentSession >= 0 && DisplayManager.screen != DisplayManager.sessions[DisplayManager.currentSession]) {} else {
|
||||
DisplayManager.currentSession += 1;
|
||||
}
|
||||
DisplayManager.screen = DisplayManager.sessions[DisplayManager.currentSession];
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canGoForward() {
|
||||
if (DisplayManager.currentSession <= 0) { // -1 e 0
|
||||
return false;
|
||||
}
|
||||
if (DisplayManager.screen != DisplayManager.sessions[DisplayManager.currentSession]) {
|
||||
|
||||
} else if (DisplayManager.currentSession > 0) {
|
||||
if (DisplayManager.sessions[DisplayManager.currentSession - 1] != null) {
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (DisplayManager.sessions[DisplayManager.currentSession] != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void goForward() {
|
||||
if (canGoForward()) {
|
||||
if (DisplayManager.screen != DisplayManager.sessions[DisplayManager.currentSession]) {
|
||||
|
||||
} else {
|
||||
DisplayManager.currentSession -= 1;
|
||||
}
|
||||
DisplayManager.screen = DisplayManager.sessions[DisplayManager.currentSession];
|
||||
}
|
||||
}
|
||||
|
||||
public Screen getScreen() {
|
||||
return DisplayManager.screen;
|
||||
}
|
||||
|
||||
private void load_skin() throws IOException {
|
||||
skin = display.loadSkin("skin.png");
|
||||
}
|
||||
|
||||
private void load_fonts() throws IOException {
|
||||
fonts = new RAWFont[7];
|
||||
fonts[0] = display.loadFont("big");
|
||||
fonts[1] = display.loadFont("small");
|
||||
fonts[2] = display.loadFont("ex");
|
||||
fonts[3] = display.loadFont("big");
|
||||
fonts[4] = display.loadFont("32");
|
||||
fonts[5] = display.loadFont("square");
|
||||
}
|
||||
|
||||
private void draw_init() {
|
||||
renderer.glClear(display.getWidth(), display.getHeight());
|
||||
}
|
||||
|
||||
private void draw_status() {
|
||||
renderer.glColor(0xFFc5c2af);
|
||||
renderer.glFillColor(0, 0, display.getWidth(), 20);
|
||||
renderer.glColor3i(0, 0, 0);
|
||||
renderer.glDrawLine(0, 20, display.getWidth() - 1, 20);
|
||||
renderer.glColor3i(255, 255, 255);
|
||||
skin.use(display);
|
||||
if (Keyboard.shift) {
|
||||
renderer.glFillRect(2 + 18 * 0, 2, 16, 16, 16 * 2, 16 * 0, 16, 16);
|
||||
} else {
|
||||
renderer.glFillRect(2 + 18 * 0, 2, 16, 16, 16 * 3, 16 * 0, 16, 16);
|
||||
}
|
||||
if (Keyboard.alpha) {
|
||||
renderer.glFillRect(2 + 18 * 1, 2, 16, 16, 16 * 0, 16 * 0, 16, 16);
|
||||
} else {
|
||||
renderer.glFillRect(2 + 18 * 1, 2, 16, 16, 16 * 1, 16 * 0, 16, 16);
|
||||
}
|
||||
/*
|
||||
if (Calculator.angleMode == 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 == 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 == 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;
|
||||
|
||||
final int brightness = (int) (Math.ceil(DisplayManager.brightness * 9));
|
||||
if (brightness <= 10) {
|
||||
renderer.glFillRect(Main.screenSize[0] - (padding + 16), 2, 16, 16, 16 * brightness, 16 * 1, 16, 16);
|
||||
} else {
|
||||
Utils.debug.println("Brightness error");
|
||||
}
|
||||
|
||||
padding += 18 + 6;
|
||||
|
||||
final boolean canGoBack = canGoBack();
|
||||
final boolean canGoForward = canGoForward();
|
||||
|
||||
if (Main.haxMode) {
|
||||
renderer.glFillRect(Main.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 18, 16 * 0, 16, 16);
|
||||
padding += 18 + 6;
|
||||
}
|
||||
|
||||
if (canGoBack && canGoForward) {
|
||||
renderer.glFillRect(Main.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 14, 16 * 0, 16, 16);
|
||||
} else if (canGoBack) {
|
||||
renderer.glFillRect(Main.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 15, 16 * 0, 16, 16);
|
||||
} else if (canGoForward) {
|
||||
renderer.glFillRect(Main.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 16, 16 * 0, 16, 16);
|
||||
} else {
|
||||
renderer.glFillRect(Main.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 17, 16 * 0, 16, 16);
|
||||
}
|
||||
|
||||
padding += 18;
|
||||
|
||||
screen.renderStatusbar();
|
||||
}
|
||||
|
||||
private void draw_screen() {
|
||||
screen.render();
|
||||
}
|
||||
|
||||
private void draw_bottom() {
|
||||
renderer.glDrawStringLeft(2, 90, displayDebugString);
|
||||
|
||||
Utils.getFont(false, true).use(DisplayManager.display);
|
||||
DisplayManager.renderer.glColor4i(255, 0, 0, 40);
|
||||
DisplayManager.renderer.glDrawStringLeft(5 + 1, Main.screenSize[1] - 20 + 1, "WORK IN PROGRESS.");
|
||||
DisplayManager.renderer.glColor4i(255, 0, 0, 80);
|
||||
DisplayManager.renderer.glDrawStringLeft(5, Main.screenSize[1] - 20, "WORK IN PROGRESS.");
|
||||
}
|
||||
|
||||
private void draw_world() {
|
||||
renderer.glColor3i(255, 255, 255);
|
||||
|
||||
if (error != null) {
|
||||
Utils.getFont(false, false).use(display);
|
||||
renderer.glColor3i(129, 28, 22);
|
||||
renderer.glDrawStringRight(Main.screenSize[0] - 2, Main.screenSize[1] - DisplayManager.glyphsHeight[1] - 2, "ANDREA CAVALLI'S CALCULATOR");
|
||||
renderer.glColor3i(149, 32, 26);
|
||||
renderer.glDrawStringCenter((Main.screenSize[0] / 2), 22, error);
|
||||
renderer.glColor3i(164, 34, 28);
|
||||
int i = 22;
|
||||
for (final String stackPart : errorStackTrace) {
|
||||
renderer.glDrawStringLeft(2, 22 + i, stackPart);
|
||||
i += 11;
|
||||
}
|
||||
fonts[0].use(display);
|
||||
renderer.glColor3i(129, 28, 22);
|
||||
renderer.glDrawStringCenter((Main.screenSize[0] / 2), 11, "UNEXPECTED EXCEPTION");
|
||||
} else {
|
||||
fonts[0].use(display);
|
||||
draw_screen();
|
||||
draw_status();
|
||||
draw_bottom();
|
||||
}
|
||||
}
|
||||
|
||||
private void draw() {
|
||||
draw_init();
|
||||
draw_world();
|
||||
}
|
||||
|
||||
private long precTime = -1;
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
float dt = 0;
|
||||
final long newtime = System.nanoTime();
|
||||
if (precTime == -1) {
|
||||
dt = 0;
|
||||
} else {
|
||||
dt = (float) ((newtime - precTime) / 1000000000d);
|
||||
}
|
||||
precTime = newtime;
|
||||
/*
|
||||
* Calcoli
|
||||
*/
|
||||
checkDisplayResized();
|
||||
|
||||
screen.beforeRender(dt);
|
||||
|
||||
if (dt >= 0.03 || screen.mustBeRefreshed()) {
|
||||
draw();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkDisplayResized() {
|
||||
if (display.wasResized()) {
|
||||
Main.screenSize[0] = display.getWidth();
|
||||
Main.screenSize[1] = display.getHeight();
|
||||
}
|
||||
};
|
||||
|
||||
public void loop() {
|
||||
try {
|
||||
load_skin();
|
||||
load_fonts();
|
||||
display.create();
|
||||
renderer = display.getRenderer();
|
||||
|
||||
try {
|
||||
screen.initialize();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
//Debug thread
|
||||
Thread dbgthrd = new Thread(() -> {
|
||||
try {
|
||||
while (true) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.out.println("============");
|
||||
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) {
|
||||
method.setAccessible(true);
|
||||
if (method.getName().startsWith("get") && Modifier.isPublic(method.getModifiers())) {
|
||||
Object value;
|
||||
try {
|
||||
value = method.invoke(operatingSystemMXBean);
|
||||
} catch (Exception e) {
|
||||
value = e;
|
||||
} // try
|
||||
boolean percent = false;
|
||||
boolean mb = false;
|
||||
String displayName = method.getName();
|
||||
String displayValue = value.toString();
|
||||
if (displayName.endsWith("CpuLoad")) {
|
||||
percent = true;
|
||||
}
|
||||
if (displayName.endsWith("MemorySize")) {
|
||||
mb = true;
|
||||
}
|
||||
ArrayList<String> arr = new ArrayList<>();
|
||||
arr.add("getFreePhysicalMemorySize");
|
||||
arr.add("getProcessCpuLoad");
|
||||
arr.add("getSystemCpuLoad");
|
||||
arr.add("getTotalPhysicalMemorySize");
|
||||
if (arr.contains(displayName)) {
|
||||
if (percent) {
|
||||
try {
|
||||
System.out.println(displayName + " = " + (((int)(Float.parseFloat(displayValue) * 10000f))/100f) + "%");
|
||||
}catch(Exception ex) {
|
||||
System.out.println(displayName + " = " + displayValue);
|
||||
}
|
||||
} else if (mb) {
|
||||
try {
|
||||
System.out.println(displayName + " = " + (Long.parseLong(displayValue) / 1024L / 1024L) + " MB");
|
||||
}catch(Exception ex) {
|
||||
System.out.println(displayName + " = " + displayValue);
|
||||
}
|
||||
} else {
|
||||
System.out.println(displayName + " = " + displayValue);
|
||||
}
|
||||
}
|
||||
} // if
|
||||
} // for
|
||||
System.out.println("============");
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
dbgthrd.setDaemon(true);
|
||||
dbgthrd.setName("Debug performance thread");
|
||||
dbgthrd.start();
|
||||
|
||||
display.start(this);
|
||||
|
||||
display.waitUntilExit();
|
||||
} catch (final Exception ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {}
|
||||
}
|
||||
|
||||
public static void changeBrightness(float change) {
|
||||
setBrightness(brightness + change);
|
||||
}
|
||||
|
||||
public static void setBrightness(float newval) {
|
||||
if (newval >= 0 && 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(0f);
|
||||
} else if (brightness + step <= 0f) {
|
||||
setBrightness(1.0f);
|
||||
} else {
|
||||
changeBrightness(step);
|
||||
}
|
||||
}
|
||||
|
||||
public static float getBrightness() {
|
||||
return brightness;
|
||||
}
|
||||
|
||||
public static int currentSession = 0;
|
||||
public static Screen[] sessions = new Screen[5];
|
||||
|
||||
@Deprecated
|
||||
public static void colore(float f1, float f2, float f3, float f4) {
|
||||
renderer.glColor4f(f1,f2,f3,f4);
|
||||
}
|
||||
|
||||
public static Drawable getDrawable() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void drawSkinPart(int x, int y, int uvX, int uvY, int uvX2, int uvY2) {
|
||||
renderer.glFillRect(x, y, uvX2-uvX, uvY2-uvY, uvX, uvY, uvX2-uvX, uvY2-uvY);
|
||||
}
|
||||
}
|
60
src/org/warp/picalculator/gui/GraphicUtils.java
Normal file
60
src/org/warp/picalculator/gui/GraphicUtils.java
Normal file
@ -0,0 +1,60 @@
|
||||
package org.warp.picalculator.gui;
|
||||
|
||||
public class GraphicUtils {
|
||||
public static final float sin(float rad)
|
||||
{
|
||||
return sin[(int) (rad * radToIndex) & SIN_MASK];
|
||||
}
|
||||
|
||||
public static final float cos(float rad)
|
||||
{
|
||||
return cos[(int) (rad * radToIndex) & SIN_MASK];
|
||||
}
|
||||
|
||||
public static final float sinDeg(float deg)
|
||||
{
|
||||
return sin[(int) (deg * degToIndex) & SIN_MASK];
|
||||
}
|
||||
|
||||
public static final float cosDeg(float deg)
|
||||
{
|
||||
return cos[(int) (deg * degToIndex) & SIN_MASK];
|
||||
}
|
||||
|
||||
private static final float RAD,DEG;
|
||||
private static final int SIN_BITS,SIN_MASK,SIN_COUNT;
|
||||
private static final float radFull,radToIndex;
|
||||
private static final float degFull,degToIndex;
|
||||
private static final float[] sin, cos;
|
||||
|
||||
static
|
||||
{
|
||||
RAD = (float) Math.PI / 180.0f;
|
||||
DEG = 180.0f / (float) Math.PI;
|
||||
|
||||
SIN_BITS = 12;
|
||||
SIN_MASK = ~(-1 << SIN_BITS);
|
||||
SIN_COUNT = SIN_MASK + 1;
|
||||
|
||||
radFull = (float) (Math.PI * 2.0);
|
||||
degFull = (float) (360.0);
|
||||
radToIndex = SIN_COUNT / radFull;
|
||||
degToIndex = SIN_COUNT / degFull;
|
||||
|
||||
sin = new float[SIN_COUNT];
|
||||
cos = new float[SIN_COUNT];
|
||||
|
||||
for (int i = 0; i < SIN_COUNT; i++)
|
||||
{
|
||||
sin[i] = (float) Math.sin((i + 0.5f) / SIN_COUNT * radFull);
|
||||
cos[i] = (float) Math.cos((i + 0.5f) / SIN_COUNT * radFull);
|
||||
}
|
||||
|
||||
// Four cardinal directions (credits: Nate)
|
||||
for (int i = 0; i < 360; i += 90)
|
||||
{
|
||||
sin[(int)(i * degToIndex) & SIN_MASK] = (float)Math.sin(i * Math.PI / 180.0);
|
||||
cos[(int)(i * degToIndex) & SIN_MASK] = (float)Math.cos(i * Math.PI / 180.0);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,437 +0,0 @@
|
||||
package org.warp.picalculator.gui;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.device.Keyboard;
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
import org.warp.picalculator.gui.graphicengine.Drawable;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.gui.screens.Screen;
|
||||
|
||||
import com.pi4j.wiringpi.Gpio;
|
||||
|
||||
public final class PIDisplay implements Drawable {
|
||||
public static PIDisplay INSTANCE;
|
||||
private static float brightness;
|
||||
|
||||
public static final Display display = new CPUDisplay();
|
||||
public static final Renderer renderer = display.getRenderer();
|
||||
|
||||
private static int[] skin;
|
||||
private static int[] skinSize;
|
||||
public static RAWFont[] fonts;
|
||||
|
||||
public static String error = null;
|
||||
public String[] errorStackTrace = null;
|
||||
public final static int[] glyphsHeight = new int[] { 9, 6, 12, 9 };
|
||||
|
||||
public static Screen screen;
|
||||
public static String displayDebugString = "";
|
||||
|
||||
public PIDisplay(Screen screen) {
|
||||
setScreen(screen);
|
||||
INSTANCE = this;
|
||||
loop();
|
||||
}
|
||||
/*
|
||||
* 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) {
|
||||
PIDisplay.currentSession = 0;
|
||||
for (int i = PIDisplay.sessions.length - 1; i >= 1; i--) {
|
||||
PIDisplay.sessions[i] = PIDisplay.sessions[i - 1];
|
||||
}
|
||||
PIDisplay.sessions[0] = screen;
|
||||
} else {
|
||||
PIDisplay.currentSession = -1;
|
||||
}
|
||||
}
|
||||
screen.d = this;
|
||||
try {
|
||||
screen.create();
|
||||
PIDisplay.screen = screen;
|
||||
if (screen.initialized == false) {
|
||||
screen.initialize();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void replaceScreen(Screen screen) {
|
||||
if (screen.initialized == false) {
|
||||
if (screen.canBeInHistory) {
|
||||
PIDisplay.sessions[PIDisplay.currentSession] = screen;
|
||||
} else {
|
||||
PIDisplay.currentSession = -1;
|
||||
for (int i = 0; i < PIDisplay.sessions.length - 2; i++) {
|
||||
PIDisplay.sessions[i] = PIDisplay.sessions[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
screen.d = this;
|
||||
try {
|
||||
screen.create();
|
||||
PIDisplay.screen = screen;
|
||||
if (screen.initialized == false) {
|
||||
screen.initialize();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canGoBack() {
|
||||
if (PIDisplay.currentSession == -1) {
|
||||
return PIDisplay.sessions[0] != null;
|
||||
}
|
||||
if (PIDisplay.screen != PIDisplay.sessions[PIDisplay.currentSession]) {
|
||||
|
||||
} else if (PIDisplay.currentSession + 1 < PIDisplay.sessions.length) {
|
||||
if (PIDisplay.sessions[PIDisplay.currentSession + 1] != null) {
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (PIDisplay.sessions[PIDisplay.currentSession] != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void goBack() {
|
||||
if (canGoBack()) {
|
||||
if (PIDisplay.currentSession >= 0 && PIDisplay.screen != PIDisplay.sessions[PIDisplay.currentSession]) {
|
||||
} else {
|
||||
PIDisplay.currentSession += 1;
|
||||
}
|
||||
PIDisplay.screen = PIDisplay.sessions[PIDisplay.currentSession];
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canGoForward() {
|
||||
if (PIDisplay.currentSession <= 0) { // -1 e 0
|
||||
return false;
|
||||
}
|
||||
if (PIDisplay.screen != PIDisplay.sessions[PIDisplay.currentSession]) {
|
||||
|
||||
} else if (PIDisplay.currentSession > 0) {
|
||||
if (PIDisplay.sessions[PIDisplay.currentSession - 1] != null) {
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (PIDisplay.sessions[PIDisplay.currentSession] != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void goForward() {
|
||||
if (canGoForward()) {
|
||||
if (PIDisplay.screen != PIDisplay.sessions[PIDisplay.currentSession]) {
|
||||
|
||||
} else {
|
||||
PIDisplay.currentSession -= 1;
|
||||
}
|
||||
PIDisplay.screen = PIDisplay.sessions[PIDisplay.currentSession];
|
||||
}
|
||||
}
|
||||
|
||||
public Screen getScreen() {
|
||||
return PIDisplay.screen;
|
||||
}
|
||||
|
||||
private void load_skin() throws IOException {
|
||||
BufferedImage img = ImageIO.read(Main.instance.getClass().getResource("/skin.png"));
|
||||
skin = renderer.getMatrixOfImage(img);
|
||||
skinSize = new int[] { img.getWidth(), img.getHeight() };
|
||||
}
|
||||
|
||||
private void load_fonts() {
|
||||
fonts = new RAWFont[7];
|
||||
fonts[0] = new RAWFont();
|
||||
fonts[0].create("big");
|
||||
fonts[1] = new RAWFont();
|
||||
fonts[1].create("small");
|
||||
fonts[2] = new RAWFont();
|
||||
fonts[2].create("ex");
|
||||
fonts[3] = new RAWFont();
|
||||
fonts[3].create("big");
|
||||
fonts[4] = new RAWFont();
|
||||
fonts[4].create("32");
|
||||
fonts[5] = new RAWFont();
|
||||
fonts[5].create("square");
|
||||
renderer.glSetFont(fonts[0]);
|
||||
}
|
||||
|
||||
private void draw_init() {
|
||||
renderer.glClear();
|
||||
}
|
||||
|
||||
public static void drawSkinPart(int x, int y, int sx1, int sy1, int sx2, int sy2) {
|
||||
renderer.glDrawSkin(skinSize[0], skin, x, y, sx1, sy1, sx2, sy2, false);
|
||||
}
|
||||
|
||||
private void draw_status() {
|
||||
renderer.glColor(0xFFc5c2af);
|
||||
renderer.glFillRect(0, 0, Main.screenSize[0], 20);
|
||||
renderer.glColor3i(0, 0, 0);
|
||||
renderer.glDrawLine(0, 20, Main.screenSize[0]-1, 20);
|
||||
renderer.glColor3i(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 == 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 == 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 == 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 * 9));
|
||||
if (brightness <= 10) {
|
||||
drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * brightness, 16 * 1, 16 + 16 * brightness, 16 + 16 * 1);
|
||||
} else {
|
||||
Utils.debug.println("Brightness error");
|
||||
}
|
||||
|
||||
padding += 18 + 6;
|
||||
|
||||
boolean canGoBack = canGoBack();
|
||||
boolean canGoForward = canGoForward();
|
||||
|
||||
if (Main.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;
|
||||
|
||||
screen.renderStatusbar();
|
||||
}
|
||||
|
||||
private void draw_screen() {
|
||||
screen.render();
|
||||
}
|
||||
|
||||
private void draw_bottom() {
|
||||
renderer.glDrawStringLeft(2, 90, displayDebugString);
|
||||
}
|
||||
|
||||
private void draw_world() {
|
||||
renderer.glColor3i(255, 255, 255);
|
||||
|
||||
if (error != null) {
|
||||
renderer.glSetFont(Utils.getFont(false, false));
|
||||
renderer.glColor3i(129, 28, 22);
|
||||
renderer.glDrawStringRight(Main.screenSize[0] - 2, Main.screenSize[1]- PIDisplay.glyphsHeight[1] - 2, "ANDREA CAVALLI'S CALCULATOR");
|
||||
renderer.glColor3i(149, 32, 26);
|
||||
renderer.glDrawStringCenter((Main.screenSize[0] / 2), 22, error);
|
||||
renderer.glColor3i(164, 34, 28);
|
||||
int i = 22;
|
||||
for (String stackPart : errorStackTrace) {
|
||||
renderer.glDrawStringLeft(2, 22 + i, stackPart);
|
||||
i += 11;
|
||||
}
|
||||
renderer.glSetFont(fonts[0]);
|
||||
renderer.glColor3i(129, 28, 22);
|
||||
renderer.glDrawStringCenter((Main.screenSize[0] / 2), 11, "UNEXPECTED EXCEPTION");
|
||||
} else {
|
||||
draw_screen();
|
||||
draw_status();
|
||||
draw_bottom();
|
||||
}
|
||||
}
|
||||
|
||||
private void draw() {
|
||||
draw_init();
|
||||
draw_world();
|
||||
}
|
||||
|
||||
private long precTime = -1;
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
float dt = 0;
|
||||
long newtime = System.nanoTime();
|
||||
if (precTime == -1) {
|
||||
dt = 0;
|
||||
} else {
|
||||
dt = (float) ((newtime - precTime) / 1000000000d);
|
||||
}
|
||||
precTime = newtime;
|
||||
/*
|
||||
* Calcoli
|
||||
*/
|
||||
checkDisplayResized();
|
||||
|
||||
screen.beforeRender(dt);
|
||||
|
||||
if(dt >= 0.03 || screen.mustBeRefreshed()) {
|
||||
draw();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkDisplayResized() {
|
||||
if (display.wasResized()) {
|
||||
Main.screenSize[0] = display.getWidth();
|
||||
Main.screenSize[1]= display.getHeight();
|
||||
}
|
||||
};
|
||||
|
||||
public void loop() {
|
||||
try {
|
||||
load_skin();
|
||||
load_fonts();
|
||||
display.create();
|
||||
|
||||
try {
|
||||
screen.initialize();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
display.start(this);
|
||||
|
||||
Main.instance.afterStart();
|
||||
|
||||
double extratime = 0;
|
||||
while (CPUDisplay.initialized) {
|
||||
long start = System.currentTimeMillis();
|
||||
display.repaint();
|
||||
long end = System.currentTimeMillis();
|
||||
double delta = (end - start) / 1000d;
|
||||
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 && 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(0f);
|
||||
} else if (brightness + step <= 0f) {
|
||||
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 static int currentSession = 0;
|
||||
public static Screen[] sessions = new Screen[5];
|
||||
|
||||
public static void colore(float f1, float f2, float f3, float f4) {
|
||||
PIDisplay.INSTANCE.colore = new float[] { f1, f2, f3, f4 };
|
||||
renderer.glColor4i((int) (f1 * 255), (int) (f2 * 255), (int) (f3 * 255), (int) (f4 * 255));
|
||||
}
|
||||
|
||||
public static Drawable getDrawable() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
@ -1,21 +1,21 @@
|
||||
package org.warp.picalculator.gui.graphicengine;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Display {
|
||||
|
||||
public int[] getSize();
|
||||
|
||||
|
||||
public boolean isInitialized();
|
||||
|
||||
public void setTitle(String title);
|
||||
|
||||
public void setResizable(boolean r);
|
||||
|
||||
|
||||
public void setDisplayMode(final int ww, final int wh);
|
||||
|
||||
|
||||
public void create();
|
||||
|
||||
|
||||
public boolean wasResized();
|
||||
|
||||
public int getWidth();
|
||||
@ -27,6 +27,14 @@ public interface Display {
|
||||
public void start(Drawable d);
|
||||
|
||||
public void repaint();
|
||||
|
||||
|
||||
public Renderer getRenderer();
|
||||
|
||||
public RAWFont loadFont(String file) throws IOException;
|
||||
|
||||
public RAWSkin loadSkin(String file) throws IOException;
|
||||
|
||||
public void waitUntilExit();
|
||||
|
||||
public boolean isSupported();
|
||||
}
|
||||
|
@ -1,182 +1,14 @@
|
||||
package org.warp.picalculator.gui.graphicengine;
|
||||
|
||||
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 interface RAWFont extends RAWSkin {
|
||||
|
||||
public boolean[][] rawchars;
|
||||
public int[] chars32;
|
||||
public int minBound = 10;
|
||||
public int maxBound = 0;
|
||||
public int charW;
|
||||
public int charH;
|
||||
public int charS;
|
||||
public int charIntCount;
|
||||
public boolean installed;
|
||||
public static final int intBits = 31;
|
||||
public int getStringWidth(String text);
|
||||
|
||||
public void create(String name) {
|
||||
try {
|
||||
loadFont("/font_"+name+".rft");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
chars32 = new int[(maxBound-minBound)*charIntCount];
|
||||
for (int charIndex = 0; charIndex < maxBound-minBound; charIndex++) {
|
||||
boolean[] currentChar = rawchars[charIndex];
|
||||
if (currentChar == null) {
|
||||
int currentInt = 0;
|
||||
int currentBit = 0;
|
||||
for (int i = 0; i < charS; i++) {
|
||||
if (currentInt*intBits+currentBit >= (currentInt+1)*intBits) {
|
||||
currentInt += 1;
|
||||
currentBit = 0;
|
||||
}
|
||||
chars32[charIndex*charIntCount+currentInt] = (chars32[charIndex*charIntCount+currentInt] << 1) + 1;
|
||||
currentBit += 1;
|
||||
}
|
||||
} else {
|
||||
int currentInt = 0;
|
||||
int currentBit = 0;
|
||||
for (int i = 0; i < charS; i++) {
|
||||
if (currentBit >= intBits) {
|
||||
currentInt += 1;
|
||||
currentBit = 0;
|
||||
}
|
||||
chars32[charIndex*charIntCount+currentInt] = (chars32[charIndex*charIntCount+currentInt]) | ((currentChar[i] ? 1 : 0) << currentBit);
|
||||
currentBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object obj = new Object();
|
||||
WeakReference<Object> ref = new WeakReference<>(obj);
|
||||
obj = null;
|
||||
while (ref.get() != null) {
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
public int getCharacterWidth();
|
||||
|
||||
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[0x8] == 0xFF && file[0xD] == 0xFF) {
|
||||
charW = file[0x4] << 8 | file[0x5];
|
||||
charH = file[0x6] << 8 | file[0x7];
|
||||
charS = charW*charH;
|
||||
charIntCount = (int) Math.ceil(((double)charS)/((double)intBits));
|
||||
minBound = file[0x9] << 24 | file[0xA] << 16 | file[0xB] << 8 | file[0xC];
|
||||
maxBound = file[0xE] << 24 | file[0xF] << 16 | file[0x10] << 8 | file[0x11];
|
||||
if (maxBound <= minBound) {
|
||||
maxBound = 10000; //TODO remove it: temp fix
|
||||
}
|
||||
rawchars = new boolean[maxBound-minBound][];
|
||||
int index = 0x12;
|
||||
while (index < filelength) {
|
||||
try {
|
||||
int charIndex = file[index] << 8 | file[index+1];
|
||||
boolean[] rawchar = new boolean[charS];
|
||||
int charbytescount = 0;
|
||||
while (charbytescount*8 < charS) {
|
||||
charbytescount+=1;
|
||||
}
|
||||
int currentBit = 0;
|
||||
for (int i = 0; i <= charbytescount; i++) {
|
||||
for (int bit = 0; bit < 8; bit++) {
|
||||
if (currentBit >= charS) {
|
||||
break;
|
||||
}
|
||||
rawchar[currentBit] = (((file[index + 2 + i] >> (8-1-bit)) & 0x1)==1)?true:false;
|
||||
currentBit++;
|
||||
}
|
||||
}
|
||||
rawchars[charIndex - minBound] = rawchar;
|
||||
index += 2 + charbytescount;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
System.out.println(string);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
|
||||
|
||||
int currentInt;
|
||||
int currentIntBitPosition;
|
||||
int bitData;
|
||||
int cpos;
|
||||
int j;
|
||||
final int l = text.length;
|
||||
for (int i = 0; i < l; i++) {
|
||||
cpos = (i * (charW + 1));
|
||||
final int charIndex = text[i];
|
||||
for (int dy = 0; dy < charH; dy++) {
|
||||
for (int dx = 0; dx < charW; dx++) {
|
||||
j = x + cpos + dx;
|
||||
if (j > 0 & j < screenSize[0]) {
|
||||
int bit = dx + dy * charW;
|
||||
currentInt = (int) (Math.floor(bit)/(intBits));
|
||||
currentIntBitPosition = bit-(currentInt*intBits);
|
||||
bitData = (chars32[charIndex*charIntCount+currentInt] >> currentIntBitPosition) & 1;
|
||||
screenPos = x + cpos + dx + (y + dy) * screenSize[0];
|
||||
if (bitData == 1 & screenLength > screenPos) {
|
||||
screen[screenPos] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public int getCharacterHeight();
|
||||
}
|
||||
|
12
src/org/warp/picalculator/gui/graphicengine/RAWSkin.java
Normal file
12
src/org/warp/picalculator/gui/graphicengine/RAWSkin.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.warp.picalculator.gui.graphicengine;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface RAWSkin {
|
||||
|
||||
public void load(String file) throws IOException;
|
||||
|
||||
public void initialize(Display d);
|
||||
|
||||
public void use(Display d);
|
||||
}
|
@ -1,43 +1,41 @@
|
||||
package org.warp.picalculator.gui.graphicengine;
|
||||
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public interface Renderer {
|
||||
public void glColor3i(int r, int gg, int b);
|
||||
|
||||
public void glColor(int c);
|
||||
|
||||
public void glColor4i(int red, int green, int blue, int alpha);
|
||||
|
||||
public void glColor3f(float red, float green, float blue);
|
||||
|
||||
public void glColor4f(float red, float green, float blue, float alpha);
|
||||
|
||||
public void glClearColor4i(int red, int green, int blue, int alpha);
|
||||
|
||||
public void glClearColor4f(float red, float green, float blue, float alpha);
|
||||
|
||||
public int glGetClearColor();
|
||||
|
||||
public void glClearColor(int c);
|
||||
|
||||
public void glColor4i(int red, int green, int blue, int alpha);
|
||||
|
||||
public void glClearColor(int red, int green, int blue, int alpha);
|
||||
|
||||
public void glClear();
|
||||
|
||||
public void glDrawSkin(int skinwidth, int[] skin, int x0, int y0, int s0, int t0, int s1, int t1, boolean transparent);
|
||||
public void glClear(int screenWidth, int screenHeight);
|
||||
|
||||
public void glDrawLine(int x0, int y0, int x1, int y1);
|
||||
|
||||
public void glFillRect(int x0, int y0, int w1, int h1);
|
||||
public void glFillRect(int x, int y, int width, int height, float uvX, float uvY, float uvWidth, float uvHeight);
|
||||
|
||||
@Deprecated
|
||||
public int[] getMatrixOfImage(BufferedImage bufferedImage);
|
||||
public void glFillColor(int x, int y, int width, int height);
|
||||
|
||||
public void glDrawStringLeft(int x, int y, String text);
|
||||
|
||||
public void glDrawStringCenter(int x, int y, String text);
|
||||
|
||||
public void glDrawStringRight(int x, int y, String text);
|
||||
|
||||
public void glSetFont(RAWFont font);
|
||||
|
||||
public int glGetStringWidth(RAWFont rf, String text);
|
||||
|
||||
public int glGetFontWidth(FontMetrics fm, String text);
|
||||
|
||||
public void glClearSkin();
|
||||
|
||||
public RAWFont getCurrentFont();
|
||||
}
|
@ -1,35 +1,43 @@
|
||||
package org.warp.picalculator.gui.graphicengine.cpu;
|
||||
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
import org.warp.picalculator.gui.graphicengine.Drawable;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWSkin;
|
||||
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||
|
||||
public class CPUDisplay implements Display {
|
||||
|
||||
private static SwingWindow INSTANCE;
|
||||
public static int[] size = new int[] { 1, 1 };
|
||||
public static BufferedImage g = new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_RGB);
|
||||
private SwingWindow INSTANCE;
|
||||
public int[] size = new int[] { 1, 1 };
|
||||
public BufferedImage g = new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_RGB);
|
||||
static int[] canvas2d = new int[1];
|
||||
public static int color = 0xFF000000;
|
||||
public static boolean initialized = false;
|
||||
public int color = 0xFF000000;
|
||||
public volatile boolean initialized = false;
|
||||
private final CPURenderer r = new CPURenderer();
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
INSTANCE.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResizable(boolean r) {
|
||||
INSTANCE.setResizable(r);
|
||||
if (!r)
|
||||
if (!r) {
|
||||
INSTANCE.setUndecorated(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayMode(final int ww, final int wh) {
|
||||
INSTANCE.setSize(ww, wh);
|
||||
size = new int[] { ww, wh };
|
||||
@ -38,14 +46,16 @@ public class CPUDisplay implements Display {
|
||||
INSTANCE.wasResized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
INSTANCE = new SwingWindow(PIDisplay.getDrawable());
|
||||
setResizable(Utils.debugOn&!Utils.debugThirdScreen);
|
||||
INSTANCE = new SwingWindow(this, DisplayManager.getDrawable());
|
||||
setResizable(Utils.debugOn & !Utils.debugThirdScreen);
|
||||
setDisplayMode(Main.screenSize[0], Main.screenSize[1]);
|
||||
INSTANCE.setVisible(true);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean wasResized() {
|
||||
if (INSTANCE.wasResized) {
|
||||
size = new int[] { INSTANCE.getWidth(), INSTANCE.getHeight() };
|
||||
@ -57,37 +67,66 @@ public class CPUDisplay implements Display {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return INSTANCE.getWidth()-Main.screenPos[0];
|
||||
return INSTANCE.getWidth() - Main.screenPos[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return INSTANCE.getHeight()-Main.screenPos[1];
|
||||
return INSTANCE.getHeight() - Main.screenPos[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
initialized = false;
|
||||
INSTANCE.setVisible(false);
|
||||
INSTANCE.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Drawable d) {
|
||||
Thread th = new Thread(() -> {
|
||||
try {
|
||||
double extratime = 0;
|
||||
while (initialized) {
|
||||
final long start = System.currentTimeMillis();
|
||||
repaint();
|
||||
final long end = System.currentTimeMillis();
|
||||
final double delta = (end - start) / 1000d;
|
||||
final int deltaInt = (int) Math.floor(delta);
|
||||
final int extraTimeInt = (int) Math.floor(extratime);
|
||||
if (extraTimeInt + deltaInt < 50) {
|
||||
Thread.sleep(50 - (extraTimeInt + deltaInt));
|
||||
extratime = 0;
|
||||
} else {
|
||||
extratime += delta - 50d;
|
||||
}
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
th.setName("Game loop thread");
|
||||
th.setDaemon(true);
|
||||
th.start();
|
||||
}
|
||||
|
||||
@Deprecated()
|
||||
public void refresh() {
|
||||
if (PIDisplay.screen == null || (PIDisplay.error != null && PIDisplay.error.length() > 0) || PIDisplay.screen == null || PIDisplay.screen.mustBeRefreshed()) {
|
||||
CPUDisplay.INSTANCE.c.repaint();
|
||||
if (DisplayManager.screen == null || (DisplayManager.error != null && DisplayManager.error.length() > 0) || DisplayManager.screen == null || DisplayManager.screen.mustBeRefreshed()) {
|
||||
INSTANCE.c.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repaint() {
|
||||
CPUDisplay.INSTANCE.c.repaint();
|
||||
INSTANCE.c.repaint();
|
||||
}
|
||||
|
||||
public abstract class Startable {
|
||||
public Startable() {
|
||||
this.force = false;
|
||||
force = false;
|
||||
}
|
||||
|
||||
public Startable(boolean force) {
|
||||
@ -99,58 +138,70 @@ public class CPUDisplay implements Display {
|
||||
public abstract void run();
|
||||
}
|
||||
|
||||
public class Render implements Renderer {
|
||||
public class CPURenderer implements Renderer {
|
||||
public int clearcolor = 0xFFc5c2af;
|
||||
public RAWFont currentFont;
|
||||
public CPUFont currentFont;
|
||||
public CPUSkin currentSkin;
|
||||
|
||||
@Override
|
||||
public void glColor3i(int r, int gg, int b) {
|
||||
glColor4i(r, gg, b, 255);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor(int c) {
|
||||
color = c & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearColor(int c) {
|
||||
clearcolor = c & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor4i(int red, int green, int blue, int alpha) {
|
||||
color = (alpha << 24) + (red << 16) + (green << 8) + (blue);
|
||||
}
|
||||
|
||||
public void glClearColor(int red, int green, int blue, int alpha) {
|
||||
@Override
|
||||
public void glClearColor4i(int red, int green, int blue, int alpha) {
|
||||
clearcolor = (alpha << 24) + (red << 16) + (green << 8) + (blue);
|
||||
}
|
||||
|
||||
public void glClear() {
|
||||
for (int x = 0; x < size[0]; x++) {
|
||||
for (int y = 0; y < size[1]; y++) {
|
||||
@Override
|
||||
public void glClearColor4f(float red, float green, float blue, float alpha) {
|
||||
clearcolor = ((int)(alpha*255) << 24) + ((int)(red*255) << 16) + ((int)(green*255) << 8) + ((int)(blue*255));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClear(int screenWidth, int screenHeight) {
|
||||
for (int x = 0; x < screenWidth; x++) {
|
||||
for (int y = 0; y < screenHeight; y++) {
|
||||
canvas2d[x + y * size[0]] = clearcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public 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];
|
||||
private void glDrawSkin(int x0, int y0, int s0, int t0, int s1, int t1, boolean transparent) {
|
||||
x0 += Main.screenPos[0];
|
||||
y0 += Main.screenPos[1];
|
||||
int oldColor;
|
||||
int newColor;
|
||||
int onex = s0 <= s1?1:-1;
|
||||
int oney = t0 <= t1?1:-1;
|
||||
final int onex = s0 <= s1 ? 1 : -1;
|
||||
final int oney = t0 <= t1 ? 1 : -1;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
if (onex == -1) {
|
||||
int s00 = s0;
|
||||
final int s00 = s0;
|
||||
s0 = s1;
|
||||
s1 = s00;
|
||||
width = s1-s0;
|
||||
width = s1 - s0;
|
||||
}
|
||||
if (oney == -1) {
|
||||
int t00 = t0;
|
||||
final int t00 = t0;
|
||||
t0 = t1;
|
||||
t1 = t00;
|
||||
height = t1-t0;
|
||||
height = t1 - t0;
|
||||
}
|
||||
if (x0 >= size[0] || y0 >= size[0]) {
|
||||
return;
|
||||
@ -179,28 +230,35 @@ public class CPUDisplay implements Display {
|
||||
}
|
||||
y0 = 0;
|
||||
}
|
||||
int pixelX;
|
||||
int pixelY;
|
||||
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*onex + width) + (y0 + texy*oney + height) * size[0]];
|
||||
float a2 = (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;
|
||||
pixelX = (x0 + texx * onex + width);
|
||||
pixelY = (y0 + texy * oney + height);
|
||||
if (pixelX - (pixelX % size[0]) == 0) {
|
||||
newColor = currentSkin.skinData[(s0 + texx) + (t0 + texy) * currentSkin.skinSize[0]];
|
||||
if (transparent) {
|
||||
oldColor = canvas2d[pixelX + pixelY * size[0]];
|
||||
final float a2 = (newColor >> 24 & 0xFF) / 255f;
|
||||
final float a1 = 1f - a2;
|
||||
final int r = (int) ((oldColor >> 16 & 0xFF) * a1 + (newColor >> 16 & 0xFF) * a2);
|
||||
final int g = (int) ((oldColor >> 8 & 0xFF) * a1 + (newColor >> 8 & 0xFF) * a2);
|
||||
final int b = (int) ((oldColor & 0xFF) * a1 + (newColor & 0xFF) * a2);
|
||||
newColor = 0xFF000000 | r << 16 | g << 8 | b;
|
||||
}
|
||||
canvas2d[pixelX + pixelY * size[0]] = newColor;
|
||||
}
|
||||
canvas2d[(x0 + texx*onex + width) + (y0 + texy*oney + height) * size[0]] = newColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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];
|
||||
x0 += Main.screenPos[0];
|
||||
x1 += Main.screenPos[0];
|
||||
y0 += Main.screenPos[1];
|
||||
y1 += Main.screenPos[1];
|
||||
if (x0 >= size[0] || y0 >= size[0]) {
|
||||
return;
|
||||
}
|
||||
@ -213,7 +271,7 @@ public class CPUDisplay implements Display {
|
||||
canvas2d[x0 + (y0 + y) * size[0]] = color;
|
||||
}
|
||||
} else {
|
||||
int m = (y1 - y0) / (x1 - x0);
|
||||
final 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;
|
||||
@ -222,12 +280,23 @@ public class CPUDisplay implements Display {
|
||||
}
|
||||
}
|
||||
|
||||
public 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]) {
|
||||
@Override
|
||||
public void glFillRect(int x, int y, int width, int height, float uvX, float uvY, float uvWidth,
|
||||
float uvHeight) {
|
||||
if (currentSkin != null) {
|
||||
glDrawSkin(x, y, (int) uvX, (int) uvY, (int) (uvWidth + uvX), (int) (uvHeight + uvY), true);
|
||||
} else {
|
||||
glFillColor(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glFillColor(int x, int y, int width, int height) {
|
||||
x += Main.screenPos[0];
|
||||
y += Main.screenPos[1];
|
||||
int x1 = x + width;
|
||||
int y1 = y + height;
|
||||
if (x >= size[0] || y >= size[0]) {
|
||||
return;
|
||||
}
|
||||
if (x1 >= size[0]) {
|
||||
@ -237,57 +306,62 @@ public class CPUDisplay implements Display {
|
||||
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;
|
||||
for (int px = x; px < x1; px++) {
|
||||
for (int py = y; py < y1; py++) {
|
||||
canvas2d[(px) + (py) * sizeW] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public 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);
|
||||
@Override
|
||||
public void glDrawStringLeft(int x, int y, String textString) {
|
||||
x += Main.screenPos[0];
|
||||
y += Main.screenPos[1];
|
||||
|
||||
final int[] text = currentFont.getCharIndexes(textString);
|
||||
final int[] screen = canvas2d;
|
||||
final int[] screenSize = size;
|
||||
final int screenLength = screen.length;
|
||||
int screenPos = 0;
|
||||
|
||||
int currentInt;
|
||||
int currentIntBitPosition;
|
||||
int bitData;
|
||||
int cpos;
|
||||
int j;
|
||||
final int l = text.length;
|
||||
for (int i = 0; i < l; i++) {
|
||||
cpos = (i * (currentFont.charW + 1));
|
||||
final int charIndex = text[i];
|
||||
for (int dy = 0; dy < currentFont.charH; dy++) {
|
||||
for (int dx = 0; dx < currentFont.charW; dx++) {
|
||||
j = x + cpos + dx;
|
||||
if (j > 0 & j < screenSize[0]) {
|
||||
final int bit = dx + dy * currentFont.charW;
|
||||
currentInt = (int) (Math.floor(bit) / (CPUFont.intBits));
|
||||
currentIntBitPosition = bit - (currentInt * CPUFont.intBits);
|
||||
bitData = (currentFont.chars32[charIndex * currentFont.charIntCount + currentInt] >> currentIntBitPosition) & 1;
|
||||
screenPos = x + cpos + dx + (y + dy) * screenSize[0];
|
||||
if (bitData == 1 & screenLength > screenPos) {
|
||||
screen[screenPos] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringCenter(int x, int y, String text) {
|
||||
glDrawStringLeft(x - (glGetStringWidth(currentFont, text) / 2), y, text);
|
||||
glDrawStringLeft(x - (currentFont.getStringWidth(text) / 2), y, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringRight(int x, int y, String text) {
|
||||
glDrawStringLeft(x - glGetStringWidth(currentFont, text), y, text);
|
||||
}
|
||||
|
||||
public void glSetFont(RAWFont font) {
|
||||
if (currentFont != font) {
|
||||
currentFont = font;
|
||||
}
|
||||
}
|
||||
|
||||
public int glGetStringWidth(RAWFont rf, String text) {
|
||||
int w =(rf.charW+1)*text.length();
|
||||
if (text.length() > 0) {
|
||||
return w-1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
// return text.length()*6;
|
||||
glDrawStringLeft(x - currentFont.getStringWidth(text), y, text);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int glGetFontWidth(FontMetrics fm, String text) {
|
||||
return fm.stringWidth(text);
|
||||
}
|
||||
@ -307,8 +381,23 @@ public class CPUDisplay implements Display {
|
||||
return currentFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor3f(float red, float green, float blue) {
|
||||
glColor3i((int) (red * 255f), (int) (green * 255f), (int) (blue * 255f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor4f(float red, float green, float blue, float alpha) {
|
||||
glColor4i((int) (red * 255f), (int) (green * 255f), (int) (blue * 255f), (int) (alpha * 255f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearSkin() {
|
||||
currentSkin = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int[] getSize() {
|
||||
return size;
|
||||
@ -320,7 +409,33 @@ public class CPUDisplay implements Display {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderer getRenderer() {
|
||||
return new Render();
|
||||
public CPURenderer getRenderer() {
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RAWFont loadFont(String file) throws IOException {
|
||||
return new CPUFont(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RAWSkin loadSkin(String file) throws IOException {
|
||||
return new CPUSkin(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitUntilExit() {
|
||||
try {
|
||||
do {
|
||||
Thread.sleep(500);
|
||||
} while(initialized);
|
||||
} catch (InterruptedException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return GraphicsEnvironment.isHeadless() == false;
|
||||
}
|
||||
}
|
||||
|
182
src/org/warp/picalculator/gui/graphicengine/cpu/CPUFont.java
Normal file
182
src/org/warp/picalculator/gui/graphicengine/cpu/CPUFont.java
Normal file
@ -0,0 +1,182 @@
|
||||
package org.warp.picalculator.gui.graphicengine.cpu;
|
||||
|
||||
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.Utils;
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay.CPURenderer;
|
||||
|
||||
public class CPUFont implements RAWFont {
|
||||
|
||||
public boolean[][] rawchars;
|
||||
public int[] chars32;
|
||||
public int minBound = 10;
|
||||
public int maxBound = 0;
|
||||
public int charW;
|
||||
public int charH;
|
||||
public int charS;
|
||||
public int charIntCount;
|
||||
public static final int intBits = 31;
|
||||
|
||||
CPUFont(String file) throws IOException {
|
||||
load(file);
|
||||
}
|
||||
|
||||
public static CPUFont loadTemporaryFont(String name) throws IOException {
|
||||
return new CPUFont(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String name) throws IOException {
|
||||
loadFont("/font_" + name + ".rft");
|
||||
chars32 = new int[(maxBound - minBound) * charIntCount];
|
||||
for (int charIndex = 0; charIndex < maxBound - minBound; charIndex++) {
|
||||
final boolean[] currentChar = rawchars[charIndex];
|
||||
if (currentChar == null) {
|
||||
int currentInt = 0;
|
||||
int currentBit = 0;
|
||||
for (int i = 0; i < charS; i++) {
|
||||
if (currentInt * intBits + currentBit >= (currentInt + 1) * intBits) {
|
||||
currentInt += 1;
|
||||
currentBit = 0;
|
||||
}
|
||||
chars32[charIndex * charIntCount + currentInt] = (chars32[charIndex * charIntCount + currentInt] << 1) + 1;
|
||||
currentBit += 1;
|
||||
}
|
||||
} else {
|
||||
int currentInt = 0;
|
||||
int currentBit = 0;
|
||||
for (int i = 0; i < charS; i++) {
|
||||
if (currentBit >= intBits) {
|
||||
currentInt += 1;
|
||||
currentBit = 0;
|
||||
}
|
||||
chars32[charIndex * charIntCount + currentInt] = (chars32[charIndex * charIntCount + currentInt]) | ((currentChar[i] ? 1 : 0) << currentBit);
|
||||
currentBit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object obj = new Object();
|
||||
final WeakReference<Object> ref = new WeakReference<>(obj);
|
||||
obj = null;
|
||||
while (ref.get() != null) {
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFont(String string) throws IOException {
|
||||
final URL res = this.getClass().getResource(string);
|
||||
final int[] file = Utils.realBytes(Utils.convertStreamToByteArray(res.openStream(), res.getFile().length()));
|
||||
final int filelength = file.length;
|
||||
if (filelength >= 16) {
|
||||
if (file[0x0] == 114 && file[0x1] == 97 && file[0x2] == 119 && file[0x3] == 0xFF && file[0x8] == 0xFF && file[0xD] == 0xFF) {
|
||||
charW = file[0x4] << 8 | file[0x5];
|
||||
charH = file[0x6] << 8 | file[0x7];
|
||||
charS = charW * charH;
|
||||
charIntCount = (int) Math.ceil(((double) charS) / ((double) intBits));
|
||||
minBound = file[0x9] << 24 | file[0xA] << 16 | file[0xB] << 8 | file[0xC];
|
||||
maxBound = file[0xE] << 24 | file[0xF] << 16 | file[0x10] << 8 | file[0x11];
|
||||
if (maxBound <= minBound) {
|
||||
maxBound = 9900; //TODO remove it: temp fix
|
||||
}
|
||||
rawchars = new boolean[maxBound - minBound][];
|
||||
int index = 0x12;
|
||||
while (index < filelength) {
|
||||
try {
|
||||
final int charIndex = file[index] << 8 | file[index + 1];
|
||||
final boolean[] rawchar = new boolean[charS];
|
||||
int charbytescount = 0;
|
||||
while (charbytescount * 8 < charS) {
|
||||
charbytescount += 1;
|
||||
}
|
||||
int currentBit = 0;
|
||||
for (int i = 0; i <= charbytescount; i++) {
|
||||
for (int bit = 0; bit < 8; bit++) {
|
||||
if (currentBit >= charS) {
|
||||
break;
|
||||
}
|
||||
rawchar[currentBit] = (((file[index + 2 + i] >> (8 - 1 - bit)) & 0x1) == 1) ? true : false;
|
||||
currentBit++;
|
||||
}
|
||||
}
|
||||
rawchars[charIndex - minBound] = rawchar;
|
||||
index += 2 + charbytescount;
|
||||
} catch (final Exception ex) {
|
||||
ex.printStackTrace();
|
||||
System.out.println(string);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new IOException();
|
||||
}
|
||||
} else {
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void saveArray(int[] screen, String coutputpng) {
|
||||
final BufferedImage bi = new BufferedImage(300, 200, BufferedImage.TYPE_INT_RGB);
|
||||
final int[] a = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
|
||||
System.arraycopy(screen, 0, a, 0, screen.length);
|
||||
try {
|
||||
ImageIO.write(bi, "PNG", new File(coutputpng));
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(RAWFont.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getCharIndexes(String txt) {
|
||||
final int l = txt.length();
|
||||
final int[] indexes = new int[l];
|
||||
final char[] chars = txt.toCharArray();
|
||||
for (int i = 0; i < l; i++) {
|
||||
indexes[i] = (chars[i] & 0xFFFF) - minBound;
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Display d) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Display d) {
|
||||
((CPURenderer) d.getRenderer()).currentFont = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStringWidth(String text) {
|
||||
final int w = (charW + 1) * text.length();
|
||||
if (text.length() > 0) {
|
||||
return w - 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterWidth() {
|
||||
return charW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterHeight() {
|
||||
return charH;
|
||||
}
|
||||
|
||||
}
|
53
src/org/warp/picalculator/gui/graphicengine/cpu/CPUSkin.java
Normal file
53
src/org/warp/picalculator/gui/graphicengine/cpu/CPUSkin.java
Normal file
@ -0,0 +1,53 @@
|
||||
package org.warp.picalculator.gui.graphicengine.cpu;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWSkin;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay.CPURenderer;
|
||||
|
||||
public class CPUSkin implements RAWSkin {
|
||||
|
||||
public int[] skinData;
|
||||
public int[] skinSize;
|
||||
|
||||
CPUSkin(String file) throws IOException {
|
||||
load(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String file) throws IOException {
|
||||
final BufferedImage img = ImageIO.read(Main.instance.getClass().getResource("/"+file));
|
||||
skinData = getMatrixOfImage(img);
|
||||
skinSize = new int[] { img.getWidth(), img.getHeight() };
|
||||
}
|
||||
|
||||
public static int[] getMatrixOfImage(BufferedImage bufferedImage) {
|
||||
final int width = bufferedImage.getWidth(null);
|
||||
final int height = bufferedImage.getHeight(null);
|
||||
final 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Display d) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Display d) {
|
||||
((CPURenderer) d.getRenderer()).currentSkin = this;
|
||||
}
|
||||
|
||||
}
|
@ -18,7 +18,7 @@ import javax.swing.JPanel;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.device.Keyboard;
|
||||
import org.warp.picalculator.device.Keyboard.Key;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.Drawable;
|
||||
|
||||
public class SwingWindow extends JFrame {
|
||||
@ -26,40 +26,41 @@ public class SwingWindow extends JFrame {
|
||||
public CustomCanvas c;
|
||||
private static Drawable d;
|
||||
public boolean wasResized = false;
|
||||
private final CPUDisplay display;
|
||||
|
||||
public SwingWindow(Drawable d) {
|
||||
public SwingWindow(CPUDisplay disp, Drawable d) {
|
||||
SwingWindow.d = d;
|
||||
display = disp;
|
||||
c = new CustomCanvas();
|
||||
c.setDoubleBuffered(false);
|
||||
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);
|
||||
|
||||
final BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
if (Utils.debugOn) {
|
||||
if (Utils.debugThirdScreen) {
|
||||
this.setLocation(2880, 900);
|
||||
this.setResizable(false);
|
||||
this.setAlwaysOnTop(true);
|
||||
setResizable(false);
|
||||
setAlwaysOnTop(true);
|
||||
}
|
||||
} else {
|
||||
// Create a new blank cursor.
|
||||
Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");
|
||||
final Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");
|
||||
|
||||
// Set the blank cursor to the JFrame.
|
||||
getContentPane().setCursor(blankCursor);
|
||||
|
||||
this.setResizable(false);
|
||||
|
||||
setResizable(false);
|
||||
}
|
||||
|
||||
this.setTitle("Raspberry PI Calculator by XDrake99 (Andrea Cavalli)");
|
||||
|
||||
|
||||
this.addComponentListener(new ComponentListener() {
|
||||
|
||||
setTitle("Raspberry PI Calculator by XDrake99 (Andrea Cavalli)");
|
||||
|
||||
addComponentListener(new ComponentListener() {
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
PIDisplay.display.destroy();
|
||||
DisplayManager.display.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,10 +74,10 @@ public class SwingWindow extends JFrame {
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {}
|
||||
});
|
||||
this.addKeyListener(new KeyListener() {
|
||||
addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent arg0) {
|
||||
Keyboard.debugKeyEvent = arg0;
|
||||
Keyboard.debugKeyCode = arg0.getKeyCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -125,7 +126,7 @@ public class SwingWindow extends JFrame {
|
||||
}
|
||||
int row = 2;
|
||||
int col = 1;
|
||||
Keyboard.debugKeysDown[row-1][col-1] = false;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = false;
|
||||
break;
|
||||
case KeyEvent.VK_1:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
@ -175,12 +176,12 @@ public class SwingWindow extends JFrame {
|
||||
//LEFT
|
||||
row = 2;
|
||||
col = 3;
|
||||
Keyboard.debugKeysDown[row-1][col-1] = false;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = false;
|
||||
case KeyEvent.VK_RIGHT:
|
||||
//RIGHT
|
||||
row = 2;
|
||||
col = 5;
|
||||
Keyboard.debugKeysDown[row-1][col-1] = false;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,7 +217,7 @@ public class SwingWindow extends JFrame {
|
||||
|
||||
// private static ArrayList<Double> mediaValori = new ArrayList<Double>();
|
||||
|
||||
public static class CustomCanvas extends JPanel {
|
||||
public class CustomCanvas extends JPanel {
|
||||
|
||||
/**
|
||||
*
|
||||
@ -228,11 +229,11 @@ public class SwingWindow extends JFrame {
|
||||
// long time1 = System.nanoTime();
|
||||
d.refresh();
|
||||
|
||||
final int[] a = ((DataBufferInt) CPUDisplay.g.getRaster().getDataBuffer()).getData();
|
||||
final int[] a = ((DataBufferInt) display.g.getRaster().getDataBuffer()).getData();
|
||||
// System.arraycopy(canvas2d, 0, a, 0, canvas2d.length);
|
||||
CPUDisplay.canvas2d = a;
|
||||
g.clearRect(0, 0, CPUDisplay.size[0], CPUDisplay.size[1]);
|
||||
g.drawImage(CPUDisplay.g, 0, 0, null);
|
||||
CPUDisplay.canvas2d = a;
|
||||
g.clearRect(0, 0, display.size[0], display.size[1]);
|
||||
g.drawImage(display.g, 0, 0, null);
|
||||
// long time2 = System.nanoTime();
|
||||
// double timeDelta = ((double)(time2-time1))/1000000000d;
|
||||
// double mediaAttuale = timeDelta;
|
||||
|
@ -1,673 +0,0 @@
|
||||
/**
|
||||
* Copyright 2012-2013 JogAmp Community. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of JogAmp Community.
|
||||
*/
|
||||
|
||||
package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import com.jogamp.opengl.GL;
|
||||
import com.jogamp.opengl.GL2ES1;
|
||||
import com.jogamp.opengl.GL2ES2;
|
||||
import com.jogamp.opengl.GLAutoDrawable;
|
||||
import com.jogamp.opengl.GLEventListener;
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.GLProfile;
|
||||
import com.jogamp.opengl.GLCapabilities;
|
||||
import com.jogamp.newt.opengl.GLWindow;
|
||||
|
||||
import com.jogamp.opengl.util.*;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
import com.jogamp.opengl.util.texture.TextureIO;
|
||||
import com.jogamp.common.nio.Buffers;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* __ __|_ ___________________________________________________________________________ ___|__ __
|
||||
* // /\ _ /\ \\
|
||||
* //____/ \__ __ _____ _____ _____ _____ _____ | | __ _____ _____ __ __/ \____\\
|
||||
* \ \ / / __| | | __| _ | | _ | | | __| | | __| | /\ \ / /
|
||||
* \____\/_/ | | | | | | | | | | | __| | | | | | | | | | |__ " \_\/____/
|
||||
* /\ \ |_____|_____|_____|__|__|_|_|_|__| | | |_____|_____|_____|_____| _ / /\
|
||||
* / \____\ http://jogamp.org |_| /____/ \
|
||||
* \ / "' _________________________________________________________________________ `" \ /
|
||||
* \/____. .____\/
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* JOGL2 OpenGL ES 2 demo to expose and learn what the RAW OpenGL ES 2 API looks like.
|
||||
*
|
||||
* Compile, run and enjoy:
|
||||
wget http://jogamp.org/deployment/jogamp-current/archive/jogamp-all-platforms.7z
|
||||
7z x jogamp-all-platforms.7z
|
||||
cd jogamp-all-platforms
|
||||
mkdir -p demos/es2
|
||||
cd demos/es2
|
||||
wget https://raw.github.com/xranby/jogl-demos/master/src/demos/es2/RawGL2ES2demo.java
|
||||
cd ../..
|
||||
javac -cp jar/jogl-all.jar:jar/gluegen-rt.jar demos/es2/RawGL2ES2demo.java
|
||||
java -cp jar/jogl-all.jar:jar/gluegen-rt.jar:. demos.es2.RawGL2ES2demo
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Xerxes Rånby (xranby)
|
||||
*/
|
||||
|
||||
public class CalculatorWindow implements GLEventListener{
|
||||
|
||||
/* Introducing the OpenGL ES 2 Vertex shader
|
||||
*
|
||||
* The main loop inside the vertex shader gets executed
|
||||
* one time for each vertex.
|
||||
*
|
||||
* vertex -> * uniform data -> mat4 projection = ( 1, 0, 0, 0,
|
||||
* (0,1,0) / \ 0, 1, 0, 0,
|
||||
* / . \ <- origo (0,0,0) 0, 0, 1, 0,
|
||||
* / \ 0, 0,-1, 1 );
|
||||
* vertex -> *-------* <- vertex
|
||||
* (-1,-1,0) (1,-1,0) <- attribute data can be used
|
||||
* (0, 0,1) for color, position, normals etc.
|
||||
*
|
||||
* The vertex shader recive input data in form of
|
||||
* "uniform" data that are common to all vertex
|
||||
* and
|
||||
* "attribute" data that are individual to each vertex.
|
||||
* One vertex can have several "attribute" data sources enabled.
|
||||
*
|
||||
* The vertex shader produce output used by the fragment shader.
|
||||
* gl_Position are expected to get set to the final vertex position.
|
||||
* You can also send additional user defined
|
||||
* "varying" data to the fragment shader.
|
||||
*
|
||||
* Model Translate, Scale and Rotate are done here by matrix-multiplying a
|
||||
* projection matrix against each vertex position.
|
||||
*
|
||||
* The whole vertex shader program are a String containing GLSL ES language
|
||||
* http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
|
||||
* sent to the GPU driver for compilation.
|
||||
*/
|
||||
private String vertexShaderString =
|
||||
// For GLSL 1 and 1.1 code i highly recomend to not include a
|
||||
// GLSL ES language #version line, GLSL ES section 3.4
|
||||
// Many GPU drivers refuse to compile the shader if #version is different from
|
||||
// the drivers internal GLSL version.
|
||||
//
|
||||
// This demo use GLSL version 1.1 (the implicit version)
|
||||
|
||||
"#if __VERSION__ >= 130\n" + // GLSL 130+ uses in and out
|
||||
" #define attribute in\n" + // instead of attribute and varying
|
||||
" #define varying out\n" + // used by OpenGL 3 core and later.
|
||||
"#endif\n" +
|
||||
|
||||
"#ifdef GL_ES \n" +
|
||||
"precision mediump float; \n" + // Precision Qualifiers
|
||||
"precision mediump int; \n" + // GLSL ES section 4.5.2
|
||||
"#endif \n" +
|
||||
|
||||
"uniform mat4 uniform_Projection; \n" + // Incomming data used by
|
||||
"attribute vec4 attribute_Position; \n" + // the vertex shader
|
||||
"attribute vec4 attribute_Color; \n" + // uniform and attributes
|
||||
"attribute vec2 a_TexCoordinate; \n" +
|
||||
|
||||
"varying vec2 v_TexCoordinate; \n" +
|
||||
"varying vec4 varying_Color; \n" + // Outgoing varying data
|
||||
// sent to the fragment shader
|
||||
"void main(void) \n" +
|
||||
"{ \n" +
|
||||
" varying_Color = attribute_Color; \n" +
|
||||
" v_TexCoordinate = a_TexCoordinate; \n" +
|
||||
" gl_Position = uniform_Projection * attribute_Position; \n" +
|
||||
"} ";
|
||||
|
||||
/* Introducing the OpenGL ES 2 Fragment shader
|
||||
*
|
||||
* The main loop of the fragment shader gets executed for each visible
|
||||
* pixel fragment on the render buffer.
|
||||
*
|
||||
* vertex-> *
|
||||
* (0,1,-1) /f\
|
||||
* /ffF\ <- This fragment F gl_FragCoord get interpolated
|
||||
* /fffff\ to (0.25,0.25,-1) based on the
|
||||
* vertex-> *fffffff* <-vertex three vertex gl_Position.
|
||||
* (-1,-1,-1) (1,-1,-1)
|
||||
*
|
||||
*
|
||||
* All incomming "varying" and gl_FragCoord data to the fragment shader
|
||||
* gets interpolated based on the vertex positions.
|
||||
*
|
||||
* The fragment shader produce and store the final color data output into
|
||||
* gl_FragColor.
|
||||
*
|
||||
* Is up to you to set the final colors and calculate lightning here based on
|
||||
* supplied position, color and normal data.
|
||||
*
|
||||
* The whole fragment shader program are a String containing GLSL ES language
|
||||
* http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
|
||||
* sent to the GPU driver for compilation.
|
||||
*/
|
||||
private String fragmentShaderString =
|
||||
"#if __VERSION__ >= 130\n" +
|
||||
" #define varying in\n" +
|
||||
" out vec4 mgl_FragColor;\n" +
|
||||
" #define texture2D texture\n" +
|
||||
" #define gl_FragColor mgl_FragColor\n" +
|
||||
"#endif\n" +
|
||||
|
||||
"#ifdef GL_ES \n" +
|
||||
"precision mediump float; \n" +
|
||||
"precision mediump int; \n" +
|
||||
"#endif \n" +
|
||||
|
||||
"uniform sampler2D u_Texture; \n" +
|
||||
|
||||
"varying vec2 v_TexCoordinate; \n" +
|
||||
"varying vec4 varying_Color; \n" + //incomming varying data to the
|
||||
//frament shader
|
||||
//sent from the vertex shader
|
||||
"void main (void) \n" +
|
||||
"{ \n" +
|
||||
|
||||
" gl_FragColor = (varying_Color * texture2D(u_Texture, v_TexCoordinate));" +
|
||||
"} ";
|
||||
|
||||
|
||||
FloatBuffer fbVertices = Buffers.newDirectFloatBuffer(2000*18); // max 2000 quadrati
|
||||
FloatBuffer fbColors = Buffers.newDirectFloatBuffer(2000*24); // max 2000 quadrati
|
||||
FloatBuffer fbTextureCoordinates = Buffers.newDirectFloatBuffer(2000*12); // max 2000 quadrati
|
||||
final Texture[] texture = new Texture[1];
|
||||
final int[] textureHandle = new int[1];
|
||||
|
||||
private final Display disp;
|
||||
public CalculatorWindow(Display disp) {
|
||||
this.disp = disp;
|
||||
}
|
||||
|
||||
/* Introducing projection matrix helper functions
|
||||
*
|
||||
* OpenGL ES 2 vertex projection transformations gets applied inside the
|
||||
* vertex shader, all you have to do are to calculate and supply a projection matrix.
|
||||
*
|
||||
* Its recomended to use the com/jogamp/opengl/util/PMVMatrix.java
|
||||
* import com.jogamp.opengl.util.PMVMatrix;
|
||||
* To simplify all your projection model view matrix creation needs.
|
||||
*
|
||||
* These helpers here are based on PMVMatrix code and common linear
|
||||
* algebra for matrix multiplication, translate and rotations.
|
||||
*/
|
||||
private void glMultMatrixf(FloatBuffer a, FloatBuffer b, FloatBuffer d) {
|
||||
final int aP = a.position();
|
||||
final int bP = b.position();
|
||||
final int dP = d.position();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
final float ai0=a.get(aP+i+0*4), ai1=a.get(aP+i+1*4), ai2=a.get(aP+i+2*4), ai3=a.get(aP+i+3*4);
|
||||
d.put(dP+i+0*4 , ai0 * b.get(bP+0+0*4) + ai1 * b.get(bP+1+0*4) + ai2 * b.get(bP+2+0*4) + ai3 * b.get(bP+3+0*4) );
|
||||
d.put(dP+i+1*4 , ai0 * b.get(bP+0+1*4) + ai1 * b.get(bP+1+1*4) + ai2 * b.get(bP+2+1*4) + ai3 * b.get(bP+3+1*4) );
|
||||
d.put(dP+i+2*4 , ai0 * b.get(bP+0+2*4) + ai1 * b.get(bP+1+2*4) + ai2 * b.get(bP+2+2*4) + ai3 * b.get(bP+3+2*4) );
|
||||
d.put(dP+i+3*4 , ai0 * b.get(bP+0+3*4) + ai1 * b.get(bP+1+3*4) + ai2 * b.get(bP+2+3*4) + ai3 * b.get(bP+3+3*4) );
|
||||
}
|
||||
}
|
||||
|
||||
private float[] multiply(float[] a,float[] b){
|
||||
float[] tmp = new float[16];
|
||||
glMultMatrixf(FloatBuffer.wrap(a),FloatBuffer.wrap(b),FloatBuffer.wrap(tmp));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private float[] translate(float[] m,float x,float y,float z){
|
||||
float[] t = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
x, y, z, 1.0f };
|
||||
return multiply(m, t);
|
||||
}
|
||||
|
||||
private float[] rotate(float[] m,float a,float x,float y,float z){
|
||||
float s, c;
|
||||
s = (float)Math.sin(Math.toRadians(a));
|
||||
c = (float)Math.cos(Math.toRadians(a));
|
||||
float[] r = {
|
||||
x * x * (1.0f - c) + c, y * x * (1.0f - c) + z * s, x * z * (1.0f - c) - y * s, 0.0f,
|
||||
x * y * (1.0f - c) - z * s, y * y * (1.0f - c) + c, y * z * (1.0f - c) + x * s, 0.0f,
|
||||
x * z * (1.0f - c) + y * s, y * z * (1.0f - c) - x * s, z * z * (1.0f - c) + c, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f };
|
||||
return multiply(m, r);
|
||||
}
|
||||
|
||||
/* Introducing the GL2ES2 demo
|
||||
*
|
||||
* How to render a triangle using ~500 lines of code using the RAW
|
||||
* OpenGL ES 2 API.
|
||||
* The Programmable pipeline in OpenGL ES 2 are both fast and flexible
|
||||
* yet it do take some extra lines of code to setup.
|
||||
*
|
||||
*/
|
||||
private double t0 = System.currentTimeMillis();
|
||||
private double theta;
|
||||
private double s;
|
||||
|
||||
private static int width=1920;
|
||||
private static int height=1080;
|
||||
|
||||
private int shaderProgram;
|
||||
private int vertShader;
|
||||
private int fragShader;
|
||||
private int ModelViewProjectionMatrixHandle;
|
||||
private int mTextureUniformHandle;
|
||||
private int mTextureCoordinateHandle;
|
||||
private final int mTextureCoordinateDataSize = 2;
|
||||
private int mTextureDataHandle;
|
||||
static final int COLOR_IDX = 0;
|
||||
static final int VERTICES_IDX = 1;
|
||||
static final int TEXTURE_IDX = 2;
|
||||
int[] vboHandles;
|
||||
|
||||
public GLWindow window;
|
||||
|
||||
public void create(){
|
||||
/* This demo are based on the GL2ES2 GLProfile that uses common hardware acceleration
|
||||
* functionality of desktop OpenGL 3, 2 and mobile OpenGL ES 2 devices.
|
||||
* JogAmp JOGL will probe all the installed libGL.so, libEGL.so and libGLESv2.so librarys on
|
||||
* the system to find which one provide hardware acceleration for your GPU device.
|
||||
* Its common to find more than one version of these librarys installed on a system.
|
||||
* For example on a ARM Linux system JOGL may find
|
||||
* Hardware accelerated Nvidia tegra GPU drivers in: /usr/lib/nvidia-tegra/libEGL.so
|
||||
* Software rendered Mesa Gallium driver in: /usr/lib/arm-linux-gnueabi/mesa-egl/libEGL.so.1
|
||||
* Software rendered Mesa X11 in: /usr/lib/arm-linux-gnueabi/mesa/libGL.so
|
||||
* Good news!: JOGL does all this probing for you all you have to do are to ask for
|
||||
* the GLProfile you want to use.
|
||||
*/
|
||||
|
||||
GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES2));
|
||||
// We may at this point tweak the caps and request a translucent drawable
|
||||
caps.setBackgroundOpaque(false);
|
||||
GLWindow glWindow = GLWindow.create(caps);
|
||||
window = glWindow;
|
||||
|
||||
/* You may combine the NEWT GLWindow inside existing Swing and AWT
|
||||
* applications by encapsulating the glWindow inside a
|
||||
* com.jogamp.newt.awt.NewtCanvasAWT canvas.
|
||||
*
|
||||
* NewtCanvasAWT newtCanvas = new NewtCanvasAWT(glWindow);
|
||||
* JFrame frame = new JFrame("RAW GL2ES2 Demo inside a JFrame!");
|
||||
* frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
* frame.setSize(width,height);
|
||||
* frame.add(newtCanvas);
|
||||
* // add some swing code if you like.
|
||||
* // javax.swing.JButton b = new javax.swing.JButton();
|
||||
* // b.setText("Hi");
|
||||
* // frame.add(b);
|
||||
* frame.setVisible(true);
|
||||
*/
|
||||
|
||||
// In this demo we prefer to setup and view the GLWindow directly
|
||||
// this allows the demo to run on -Djava.awt.headless=true systems
|
||||
glWindow.setTitle("Raw GL2ES2 Demo");
|
||||
|
||||
// Finally we connect the GLEventListener application code to the NEWT GLWindow.
|
||||
// GLWindow will call the GLEventListener init, reshape, display and dispose
|
||||
// functions when needed.
|
||||
glWindow.addGLEventListener(this /* GLEventListener */);
|
||||
Animator animator = new Animator();
|
||||
animator.add(glWindow);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
public void init(GLAutoDrawable drawable) {
|
||||
GL2ES2 gl = drawable.getGL().getGL2ES2();
|
||||
|
||||
System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
|
||||
System.err.println("INIT GL IS: " + gl.getClass().getName());
|
||||
System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
|
||||
System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
|
||||
System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
|
||||
|
||||
/* The initialization below will use the OpenGL ES 2 API directly
|
||||
* to setup the two shader programs that will be run on the GPU.
|
||||
*
|
||||
* Its recommended to use the jogamp/opengl/util/glsl/ classes
|
||||
* import com.jogamp.opengl.util.glsl.ShaderCode;
|
||||
* import com.jogamp.opengl.util.glsl.ShaderProgram;
|
||||
* import com.jogamp.opengl.util.glsl.ShaderState;
|
||||
* to simplify shader customization, compile and loading.
|
||||
*
|
||||
* You may also want to look at the JOGL RedSquareES2 demo
|
||||
* http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java;hb=HEAD#l78
|
||||
* to see how the shader customization, compile and loading is done
|
||||
* using the recommended JogAmp GLSL utility classes.
|
||||
*/
|
||||
|
||||
// Make the shader strings compatible with OpenGL 3 core if needed
|
||||
// GL2ES2 also includes the intersection of GL3 core
|
||||
// The default implicit GLSL version 1.1 is now depricated in GL3 core
|
||||
// GLSL 1.3 is the minimum version that now has to be explicitly set.
|
||||
// This allows the shaders to compile using the latest
|
||||
// desktop OpenGL 3 and 4 drivers.
|
||||
if(gl.isGL3core()){
|
||||
System.out.println("GL3 core detected: explicit add #version 130 to shaders");
|
||||
vertexShaderString = "#version 130\n"+vertexShaderString;
|
||||
fragmentShaderString = "#version 130\n"+fragmentShaderString;
|
||||
}
|
||||
|
||||
// Create GPU shader handles
|
||||
// OpenGL ES retuns a index id to be stored for future reference.
|
||||
vertShader = gl.glCreateShader(GL2ES2.GL_VERTEX_SHADER);
|
||||
fragShader = gl.glCreateShader(GL2ES2.GL_FRAGMENT_SHADER);
|
||||
|
||||
//Generate textures
|
||||
gl.glGenTextures(1, textureHandle, 0);
|
||||
|
||||
try {
|
||||
Texture t = loadTexture("test.png");
|
||||
textureHandle[0] = t.getTarget();
|
||||
texture[0] = t;
|
||||
gl.glBindTexture(GL2ES2.GL_TEXTURE_2D, textureHandle[0]);
|
||||
} catch (GLException | IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//Compile the vertexShader String into a program.
|
||||
String[] vlines = new String[] { vertexShaderString };
|
||||
int[] vlengths = new int[] { vlines[0].length() };
|
||||
gl.glShaderSource(vertShader, vlines.length, vlines, vlengths, 0);
|
||||
gl.glCompileShader(vertShader);
|
||||
|
||||
//Check compile status.
|
||||
int[] compiled = new int[1];
|
||||
gl.glGetShaderiv(vertShader, GL2ES2.GL_COMPILE_STATUS, compiled,0);
|
||||
if(compiled[0]!=0){System.out.println("Horray! vertex shader compiled");}
|
||||
else {
|
||||
int[] logLength = new int[1];
|
||||
gl.glGetShaderiv(vertShader, GL2ES2.GL_INFO_LOG_LENGTH, logLength, 0);
|
||||
|
||||
byte[] log = new byte[logLength[0]];
|
||||
gl.glGetShaderInfoLog(vertShader, logLength[0], (int[])null, 0, log, 0);
|
||||
|
||||
System.err.println("Error compiling the vertex shader: " + new String(log));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
//Compile the fragmentShader String into a program.
|
||||
String[] flines = new String[] { fragmentShaderString };
|
||||
int[] flengths = new int[] { flines[0].length() };
|
||||
gl.glShaderSource(fragShader, flines.length, flines, flengths, 0);
|
||||
gl.glCompileShader(fragShader);
|
||||
|
||||
//Check compile status.
|
||||
gl.glGetShaderiv(fragShader, GL2ES2.GL_COMPILE_STATUS, compiled,0);
|
||||
if(compiled[0]!=0){System.out.println("Horray! fragment shader compiled");}
|
||||
else {
|
||||
int[] logLength = new int[1];
|
||||
gl.glGetShaderiv(fragShader, GL2ES2.GL_INFO_LOG_LENGTH, logLength, 0);
|
||||
|
||||
byte[] log = new byte[logLength[0]];
|
||||
gl.glGetShaderInfoLog(fragShader, logLength[0], (int[])null, 0, log, 0);
|
||||
|
||||
System.err.println("Error compiling the fragment shader: " + new String(log));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
//Each shaderProgram must have
|
||||
//one vertex shader and one fragment shader.
|
||||
shaderProgram = gl.glCreateProgram();
|
||||
gl.glAttachShader(shaderProgram, vertShader);
|
||||
gl.glAttachShader(shaderProgram, fragShader);
|
||||
|
||||
//Associate attribute ids with the attribute names inside
|
||||
//the vertex shader.
|
||||
gl.glBindAttribLocation(shaderProgram, 0, "attribute_Position");
|
||||
gl.glBindAttribLocation(shaderProgram, 1, "attribute_Color");
|
||||
gl.glBindAttribLocation(shaderProgram, 2, "a_TexCoordinate");
|
||||
|
||||
gl.glLinkProgram(shaderProgram);
|
||||
|
||||
//Get a id number to the uniform_Projection matrix
|
||||
//so that we can update it.
|
||||
ModelViewProjectionMatrixHandle = gl.glGetUniformLocation(shaderProgram, "uniform_Projection");
|
||||
mTextureUniformHandle = gl.glGetUniformLocation(shaderProgram, "u_Texture");
|
||||
mTextureCoordinateHandle = gl.glGetAttribLocation(shaderProgram, "a_TexCoordinate");
|
||||
|
||||
/* GL2ES2 also includes the intersection of GL3 core
|
||||
* GL3 core and later mandates that a "Vector Buffer Object" must
|
||||
* be created and bound before calls such as gl.glDrawArrays is used.
|
||||
* The VBO lines in this demo makes the code forward compatible with
|
||||
* OpenGL 3 and ES 3 core and later where a default
|
||||
* vector buffer object is deprecated.
|
||||
*
|
||||
* Generate two VBO pointers / handles
|
||||
* VBO is data buffers stored inside the graphics card memory.
|
||||
*/
|
||||
vboHandles = new int[3];
|
||||
gl.glGenBuffers(3, vboHandles, 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void reshape(GLAutoDrawable drawable, int x, int y, int z, int h) {
|
||||
System.out.println("Window resized to width=" + z + " height=" + h);
|
||||
width = z;
|
||||
height = h;
|
||||
|
||||
// Get gl
|
||||
GL2ES2 gl = drawable.getGL().getGL2ES2();
|
||||
|
||||
// Optional: Set viewport
|
||||
// Render to a square at the center of the window.
|
||||
gl.glViewport((width-height)/2,0,height,height);
|
||||
}
|
||||
|
||||
public void display(GLAutoDrawable drawable) {
|
||||
// Update variables used in animation
|
||||
double t1 = System.currentTimeMillis();
|
||||
theta += (t1-t0)*0.005f;
|
||||
t0 = t1;
|
||||
s = Math.sin(theta);
|
||||
|
||||
// Get gl
|
||||
GL2ES2 gl = drawable.getGL().getGL2ES2();
|
||||
|
||||
// Clear screen
|
||||
gl.glClearColor(0, 0, 0, 0f); // Purple
|
||||
gl.glClear(GL2ES2.GL_STENCIL_BUFFER_BIT |
|
||||
GL2ES2.GL_COLOR_BUFFER_BIT |
|
||||
GL2ES2.GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
// Use the shaderProgram that got linked during the init part.
|
||||
gl.glUseProgram(shaderProgram);
|
||||
|
||||
/* Change a projection matrix
|
||||
* The matrix multiplications and OpenGL ES2 code below
|
||||
* basically match this OpenGL ES1 code.
|
||||
* note that the model_view_projection matrix gets sent to the vertexShader.
|
||||
*
|
||||
* gl.glLoadIdentity();
|
||||
* gl.glTranslatef(0.0f,0.0f,-0.1f);
|
||||
* gl.glRotatef((float)30f*(float)s,1.0f,0.0f,1.0f);
|
||||
*
|
||||
*/
|
||||
|
||||
// Set the active texture unit to texture unit 0.
|
||||
gl.glActiveTexture(textureHandle[0]);
|
||||
|
||||
// Bind the texture to this unit.
|
||||
gl.glBindTexture(GL2ES2.GL_TEXTURE_2D, mTextureDataHandle);
|
||||
|
||||
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
|
||||
gl.glUniform1i(mTextureUniformHandle, 0);
|
||||
|
||||
float[] model_view_projection;
|
||||
float[] identity_matrix = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
model_view_projection = identity_matrix;
|
||||
// model_view_projection = rotate(model_view_projection,30f*(float)s,1.0f,0.0f,1.0f);
|
||||
// model_view_projection = translate(model_view_projection,-0.5f,-0.5f, 0f);
|
||||
|
||||
// Send the final projection matrix to the vertex shader by
|
||||
// using the uniform location id obtained during the init part.
|
||||
gl.glUniformMatrix4fv(ModelViewProjectionMatrixHandle, 1, false, model_view_projection, 0);
|
||||
|
||||
/*
|
||||
* Render a triangle:
|
||||
* The OpenGL ES2 code below basically match this OpenGL code.
|
||||
*
|
||||
* gl.glBegin(GL_TRIANGLES); // Drawing Using Triangles
|
||||
* gl.glVertex3f( 0.0f, 1.0f, 0.0f); // Top
|
||||
* gl.glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
|
||||
* gl.glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
|
||||
* gl.glEnd(); // Finished Drawing The Triangle
|
||||
*/
|
||||
|
||||
fbVertices.clear();
|
||||
fbColors.clear();
|
||||
fbTextureCoordinates.clear();
|
||||
|
||||
fbVertices.put(new float[]{
|
||||
0.0f, 0.0f, 0.0f, //Top
|
||||
1.0f, 1.0f, 0.0f, //Bottom Left
|
||||
0.0f, 1.0f, 0.0f, //Bottom Right
|
||||
});
|
||||
fbColors.put(new float[]{
|
||||
1.0f, 0.0f, 0.0f, 1.0f, //Top color (red)
|
||||
0.0f, 0.0f, 0.0f, 1.0f, //Bottom Left color (black)
|
||||
1.0f, 1.0f, 0.0f, 1.0f, //Bottom Right color (yellow)
|
||||
});
|
||||
fbTextureCoordinates.put(new float[]{
|
||||
0.0f, 0.0f,
|
||||
0.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
});
|
||||
fbVertices.put(new float[]{
|
||||
0.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f});
|
||||
fbColors.put(new float[]{
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f});
|
||||
fbTextureCoordinates.put(new float[]{
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
});
|
||||
fbColors.position(0);
|
||||
fbVertices.position(0);
|
||||
fbTextureCoordinates.position(0);
|
||||
int numTriangles = fbVertices.limit()/9;
|
||||
|
||||
// Select the VBO, GPU memory data, to use for vertices
|
||||
gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, vboHandles[VERTICES_IDX]);
|
||||
|
||||
// transfer data to VBO, this perform the copy of data from CPU -> GPU memory
|
||||
int numBytes = numTriangles * 9 * 4;
|
||||
gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, fbVertices, GL.GL_STATIC_DRAW);
|
||||
|
||||
// Associate Vertex attribute 0 with the last bound VBO
|
||||
gl.glVertexAttribPointer(0 /* the vertex attribute */, 3,
|
||||
GL2ES2.GL_FLOAT, false /* normalized? */, 0 /* stride */,
|
||||
0 /* The bound VBO data offset */);
|
||||
|
||||
// VBO
|
||||
// gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, 0); // You can unbind the VBO after it have been associated using glVertexAttribPointer
|
||||
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
|
||||
// Select the VBO, GPU memory data, to use for colors
|
||||
gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, vboHandles[COLOR_IDX]);
|
||||
|
||||
numBytes = numTriangles * 12 * 4;
|
||||
gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, fbColors, GL.GL_STATIC_DRAW);
|
||||
|
||||
// Associate Vertex attribute 1 with the last bound VBO
|
||||
gl.glVertexAttribPointer(1 /* the color attribute */, 4 /* four possitions used for each vertex */,
|
||||
GL2ES2.GL_FLOAT, false /* normalized? */, 0 /* stride */,
|
||||
0 /* The bound VBO data offset */);
|
||||
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
|
||||
// Select the VBO, GPU memory data, to use for texture
|
||||
gl.glBindBuffer(GL2ES2.GL_ARRAY_BUFFER, vboHandles[TEXTURE_IDX]);
|
||||
|
||||
numBytes = numTriangles * 6 * 4;
|
||||
gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, fbTextureCoordinates, GL.GL_STATIC_DRAW);
|
||||
|
||||
// Associate Vertex attribute 1 with the last bound VBO
|
||||
gl.glVertexAttribPointer(mTextureCoordinateHandle /* the texture attribute */, 2 /* two possitions used for each coordinate */,
|
||||
GL2ES2.GL_FLOAT, false /* normalized? */, 0 /* stride */,
|
||||
0 /* The bound VBO data offset */);
|
||||
|
||||
gl.glEnableVertexAttribArray(mTextureCoordinateHandle);
|
||||
|
||||
|
||||
gl.glDrawArrays(GL2ES2.GL_TRIANGLES, 0, numTriangles*3); //Draw the vertices as triangle
|
||||
|
||||
gl.glDisableVertexAttribArray(0); // Allow release of vertex position memory
|
||||
gl.glDisableVertexAttribArray(1); // Allow release of vertex color memory
|
||||
gl.glDisableVertexAttribArray(mTextureCoordinateHandle); // Allow release of vertex texture memory
|
||||
|
||||
// disp.di
|
||||
}
|
||||
|
||||
public void drawQuad() {
|
||||
|
||||
}
|
||||
|
||||
public void dispose(GLAutoDrawable drawable){
|
||||
System.out.println("cleanup, remember to release shaders");
|
||||
GL2ES2 gl = drawable.getGL().getGL2ES2();
|
||||
gl.glUseProgram(0);
|
||||
gl.glDeleteBuffers(3, vboHandles, 0); // Release VBO, color and vertices, buffer GPU memory.
|
||||
vboHandles = null;
|
||||
gl.glDetachShader(shaderProgram, vertShader);
|
||||
gl.glDeleteShader(vertShader);
|
||||
gl.glDetachShader(shaderProgram, fragShader);
|
||||
gl.glDeleteShader(fragShader);
|
||||
gl.glDeleteProgram(shaderProgram);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public static Texture loadTexture(String file) throws GLException, IOException
|
||||
{
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
ImageIO.write(ImageIO.read(new File(file)), "png", os);
|
||||
InputStream fis = new ByteArrayInputStream(os.toByteArray());
|
||||
return TextureIO.newTexture(fis, true, TextureIO.PNG);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,706 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2016 Julien Gouesse This program is free software; you can
|
||||
* redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version. This program is distributed
|
||||
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received
|
||||
* a copy of the GNU General Public License along with this program; if not,
|
||||
* write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.DoubleBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Helper to deallocate memory on the native heap allocated during the creation
|
||||
* of a direct byte buffer. It supports numerous virtual machines including
|
||||
* OpenJDK, Oracle/Sun Java, Android Dalvik Virtual Machine, Apache Harmony and
|
||||
* GNU Classpath. This class uses the syntax of Java 1.7 but it can work
|
||||
* correctly with Java 1.4 with a very few minor type changes when using the
|
||||
* maps and the collections. It relies on lots of implementation details but
|
||||
* it's robust enough to go on working (except when the implementors
|
||||
* intentionally use a very general class to store the buffers) despite minor
|
||||
* naming changes like those that occurred between Java 1.6 and Java 1.7. It
|
||||
* supports Java 1.9 despite the move of the cleaner from the package sun.misc
|
||||
* to jdk.internal.ref (in the module java.base). N.B: Releasing the native
|
||||
* memory of a sliced direct NIO buffer, the one of a direct NIO buffer created
|
||||
* with JNI or the one of any direct NIO buffer created by the virtual machine
|
||||
* or by a framework not under your control doesn't prevent the calls to methods
|
||||
* attempting to access such buffers. Those calls can throw an exception or
|
||||
* crash the virtual machine depending on the implementations.
|
||||
*
|
||||
* @author Julien Gouesse
|
||||
*/
|
||||
public class DeallocationHelper {
|
||||
|
||||
/**
|
||||
* tool responsible for releasing the native memory of a deallocatable byte
|
||||
* buffer
|
||||
*/
|
||||
public static abstract class Deallocator {
|
||||
|
||||
public Deallocator() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* releases the native memory of a deallocatable byte buffer
|
||||
*
|
||||
* @param directByteBuffer
|
||||
* deallocatable byte buffer
|
||||
*
|
||||
* @return <code>true</code> if the deallocation is successful,
|
||||
* otherwise <code>false</code>
|
||||
*/
|
||||
public abstract boolean run(final ByteBuffer directByteBuffer);
|
||||
}
|
||||
|
||||
public static class OracleSunOpenJdkDeallocator extends Deallocator {
|
||||
|
||||
private Method directByteBufferCleanerMethod;
|
||||
|
||||
private Method cleanerCleanMethod;
|
||||
|
||||
public OracleSunOpenJdkDeallocator() {
|
||||
super();
|
||||
try {
|
||||
final Class<?> directByteBufferClass = Class.forName("java.nio.DirectByteBuffer");
|
||||
directByteBufferCleanerMethod = directByteBufferClass.getDeclaredMethod("cleaner");
|
||||
/**
|
||||
* The return type is sun.misc.Cleaner in Java <= 1.8,
|
||||
* jdk.internal.ref.Cleaner in Java >= 1.9. Only the latter
|
||||
* implements the Runnable interface.
|
||||
*/
|
||||
final Class<?> cleanerClass = directByteBufferCleanerMethod.getReturnType();
|
||||
if (Runnable.class.isAssignableFrom(cleanerClass)) {
|
||||
cleanerCleanMethod = Runnable.class.getDeclaredMethod("run");
|
||||
} else {
|
||||
cleanerCleanMethod = cleanerClass.getDeclaredMethod("clean");
|
||||
}
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
logger.log(Level.WARNING, "The initialization of the deallocator for Oracle Java, Sun Java and OpenJDK has failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(final ByteBuffer directByteBuffer) {
|
||||
boolean success = false;
|
||||
if (directByteBufferCleanerMethod != null && cleanerCleanMethod != null) {
|
||||
final boolean directByteBufferCleanerMethodWasAccessible = directByteBufferCleanerMethod.isAccessible();
|
||||
final boolean cleanerCleanMethodWasAccessible = cleanerCleanMethod.isAccessible();
|
||||
try {
|
||||
// according to the Java documentation, by default, a reflected object is not accessible
|
||||
directByteBufferCleanerMethod.setAccessible(true);
|
||||
final Object cleaner = directByteBufferCleanerMethod.invoke(directByteBuffer);
|
||||
if (cleaner != null) {
|
||||
cleanerCleanMethod.setAccessible(true);
|
||||
cleanerCleanMethod.invoke(cleaner);
|
||||
success = true;
|
||||
}
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
logger.log(Level.WARNING, "The deallocation of a direct NIO buffer has failed", e);
|
||||
} finally {
|
||||
directByteBufferCleanerMethod.setAccessible(directByteBufferCleanerMethodWasAccessible);
|
||||
cleanerCleanMethod.setAccessible(cleanerCleanMethodWasAccessible);
|
||||
}
|
||||
}
|
||||
return (success);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AndroidDeallocator extends Deallocator {
|
||||
|
||||
private Method directByteBufferFreeMethod;
|
||||
|
||||
public AndroidDeallocator() {
|
||||
super();
|
||||
try {
|
||||
final Class<?> directByteBufferClass = Class.forName("java.nio.DirectByteBuffer");
|
||||
directByteBufferFreeMethod = directByteBufferClass.getDeclaredMethod("free");
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
logger.log(Level.WARNING, "The initialization of the deallocator for Android has failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(final ByteBuffer directByteBuffer) {
|
||||
boolean success = false;
|
||||
if (directByteBufferFreeMethod != null) {
|
||||
final boolean directByteBufferFreeMethodWasAccessible = directByteBufferFreeMethod.isAccessible();
|
||||
try {
|
||||
directByteBufferFreeMethod.setAccessible(true);
|
||||
directByteBufferFreeMethod.invoke(directByteBuffer);
|
||||
success = true;
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
logger.log(Level.WARNING, "The deallocation of a direct NIO buffer has failed", e);
|
||||
} finally {
|
||||
directByteBufferFreeMethod.setAccessible(directByteBufferFreeMethodWasAccessible);
|
||||
}
|
||||
}
|
||||
return (success);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GnuClasspathDeallocator extends Deallocator {
|
||||
|
||||
private Method vmDirectByteBufferFreeMethod;
|
||||
|
||||
private Field bufferAddressField;
|
||||
|
||||
public GnuClasspathDeallocator() {
|
||||
super();
|
||||
try {
|
||||
final Class<?> vmDirectByteBufferClass = Class.forName("java.nio.VMDirectByteBuffer");
|
||||
final Class<?> gnuClasspathPointerClass = Class.forName("gnu.classpath.Pointer");
|
||||
vmDirectByteBufferFreeMethod = vmDirectByteBufferClass.getDeclaredMethod("free", gnuClasspathPointerClass);
|
||||
bufferAddressField = Buffer.class.getDeclaredField("address");
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException e) {
|
||||
logger.log(Level.WARNING, "The initialization of the deallocator for GNU Classpath has failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(final ByteBuffer directByteBuffer) {
|
||||
boolean success = false;
|
||||
if (vmDirectByteBufferFreeMethod != null && bufferAddressField != null) {
|
||||
final boolean bufferAddressFieldWasAccessible = bufferAddressField.isAccessible();
|
||||
final boolean vmDirectByteBufferFreeMethodWasAccessible = vmDirectByteBufferFreeMethod.isAccessible();
|
||||
try {
|
||||
bufferAddressField.setAccessible(true);
|
||||
final Object address = bufferAddressField.get(directByteBuffer);
|
||||
if (address != null) {
|
||||
vmDirectByteBufferFreeMethod.setAccessible(true);
|
||||
vmDirectByteBufferFreeMethod.invoke(null, address);
|
||||
success = true;
|
||||
}
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
logger.log(Level.WARNING, "The deallocation of a direct NIO buffer has failed", e);
|
||||
} finally {
|
||||
bufferAddressField.setAccessible(bufferAddressFieldWasAccessible);
|
||||
vmDirectByteBufferFreeMethod.setAccessible(vmDirectByteBufferFreeMethodWasAccessible);
|
||||
}
|
||||
}
|
||||
return (success);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApacheHarmonyDeallocator extends Deallocator {
|
||||
|
||||
private Method directByteBufferFreeMethod;
|
||||
|
||||
public ApacheHarmonyDeallocator() {
|
||||
super();
|
||||
try {
|
||||
final Class<?> directByteBufferClass = Class.forName("java.nio.DirectByteBuffer");
|
||||
directByteBufferFreeMethod = directByteBufferClass.getDeclaredMethod("free");
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
logger.log(Level.WARNING, "The initialization of the deallocator for Apache Harmony has failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(final ByteBuffer directByteBuffer) {
|
||||
boolean success = false;
|
||||
if (directByteBufferFreeMethod != null) {
|
||||
final boolean directByteBufferFreeMethodWasAccessible = directByteBufferFreeMethod.isAccessible();
|
||||
try {
|
||||
directByteBufferFreeMethod.setAccessible(true);
|
||||
directByteBufferFreeMethod.invoke(directByteBuffer);
|
||||
success = true;
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
logger.log(Level.WARNING, "The deallocation of a direct NIO buffer has failed", e);
|
||||
} finally {
|
||||
directByteBufferFreeMethod.setAccessible(directByteBufferFreeMethodWasAccessible);
|
||||
}
|
||||
}
|
||||
return (success);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DeallocationHelper.class.getName());
|
||||
|
||||
private Map<Class<?>, Field> attachmentOrByteBufferFieldMap;
|
||||
|
||||
private Set<Class<?>> deallocatableBufferClassSet;
|
||||
|
||||
private Deallocator deallocator;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public DeallocationHelper() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor
|
||||
*
|
||||
* @param ignoreClassesAndFieldsHints
|
||||
* <code>true</code> if the known implementation details should
|
||||
* be ignored when looking for the classes and the fields used
|
||||
* for the native memory of the direct buffers (they are then
|
||||
* fully recomputed at runtime which is slower but safer),
|
||||
* otherwise <code>false</code>
|
||||
*/
|
||||
public DeallocationHelper(final boolean ignoreClassesAndFieldsHints) {
|
||||
super();
|
||||
final List<Buffer> buffersToDelete = new ArrayList<>();
|
||||
/**
|
||||
* builds the map used to determine the names of the fields containing
|
||||
* the direct byte buffers. The direct read only buffers and the sliced
|
||||
* buffers and the direct buffers for other primitive types than bytes
|
||||
* store their data into some direct byte buffers. Those direct byte
|
||||
* buffers often are the only one accessing directly to the native
|
||||
* memory. That's why it's necessary to find them when a developer
|
||||
* passes a direct NIO buffer. The code below relies on numerous
|
||||
* implementation details found in some classes not available in the
|
||||
* public APIs, it's used to find the fields faster in most of the
|
||||
* cases. The class names haven't changed since Java 1.4 unlike a few
|
||||
* field names.
|
||||
*/
|
||||
final Map<String, String> attachmentOrByteBufferFieldNameMap = new HashMap<>();
|
||||
final String javaVendor = System.getProperty("java.vendor");
|
||||
final String javaVersion = System.getProperty("java.version");
|
||||
if (!ignoreClassesAndFieldsHints) {
|
||||
if (javaVendor.equals("Sun Microsystems Inc.") || javaVendor.equals("Oracle Corporation")) {
|
||||
final String java14to16DirectBufferAttachmentFieldName = "viewedBuffer";
|
||||
final String java17to19DirectBufferAttachmentFieldName = "att";
|
||||
final String byteBufferAsNonByteBufferByteBufferFieldName = "bb";
|
||||
final String[] directBufferClassnames = new String[] { "java.nio.DirectByteBuffer", "java.nio.DirectByteBufferR", "java.nio.DirectCharBufferRS", "java.nio.DirectCharBufferRU", "java.nio.DirectCharBufferS", "java.nio.DirectCharBufferU", "java.nio.DirectDoubleBufferRS", "java.nio.DirectDoubleBufferRU", "java.nio.DirectDoubleBufferS", "java.nio.DirectDoubleBufferU", "java.nio.DirectFloatBufferRS", "java.nio.DirectFloatBufferRU", "java.nio.DirectFloatBufferS", "java.nio.DirectFloatBufferU", "java.nio.DirectIntBufferRS", "java.nio.DirectIntBufferRU", "java.nio.DirectIntBufferS", "java.nio.DirectIntBufferU", "java.nio.DirectLongBufferRS", "java.nio.DirectLongBufferRU", "java.nio.DirectLongBufferS", "java.nio.DirectLongBufferU", "java.nio.DirectShortBufferRS", "java.nio.DirectShortBufferRU", "java.nio.DirectShortBufferS", "java.nio.DirectShortBufferU" };
|
||||
final String[] byteBufferAsNonByteBufferClassnames = new String[] { "java.nio.ByteBufferAsCharBufferB", "java.nio.ByteBufferAsCharBufferL", "java.nio.ByteBufferAsCharBufferRB", "java.nio.ByteBufferAsCharBufferRL", "java.nio.ByteBufferAsDoubleBufferB", "java.nio.ByteBufferAsDoubleBufferL", "java.nio.ByteBufferAsDoubleBufferRB", "java.nio.ByteBufferAsDoubleBufferRL", "java.nio.ByteBufferAsFloatBufferB", "java.nio.ByteBufferAsFloatBufferL", "java.nio.ByteBufferAsFloatBufferRB", "java.nio.ByteBufferAsFloatBufferRL", "java.nio.ByteBufferAsIntBufferB", "java.nio.ByteBufferAsIntBufferL", "java.nio.ByteBufferAsIntBufferRB", "java.nio.ByteBufferAsIntBufferRL", "java.nio.ByteBufferAsLongBufferB", "java.nio.ByteBufferAsLongBufferL", "java.nio.ByteBufferAsLongBufferRB", "java.nio.ByteBufferAsLongBufferRL", "java.nio.ByteBufferAsShortBufferB", "java.nio.ByteBufferAsShortBufferL", "java.nio.ByteBufferAsShortBufferRB", "java.nio.ByteBufferAsShortBufferRL" };
|
||||
final String[] javaVersionElements = System.getProperty("java.version").split("\\.");
|
||||
final int indexOfEarlyAccessSuffix = javaVersionElements[0].lastIndexOf("-ea");
|
||||
if (indexOfEarlyAccessSuffix != -1) {
|
||||
// drops the "-ea" suffix from the major version number for
|
||||
// an early access build
|
||||
javaVersionElements[0] = javaVersionElements[0].substring(0, indexOfEarlyAccessSuffix);
|
||||
}
|
||||
final int major, minor;
|
||||
if (javaVersionElements.length >= 2) {
|
||||
major = Integer.parseInt(javaVersionElements[0]);
|
||||
minor = Integer.parseInt(javaVersionElements[1]);
|
||||
} else {
|
||||
major = 1;
|
||||
minor = Integer.parseInt(javaVersionElements[0]);
|
||||
}
|
||||
final String directBufferAttachmentFieldName;
|
||||
if (minor == 1 && major <= 6) {
|
||||
directBufferAttachmentFieldName = java14to16DirectBufferAttachmentFieldName;
|
||||
} else {
|
||||
directBufferAttachmentFieldName = java17to19DirectBufferAttachmentFieldName;
|
||||
}
|
||||
for (final String directBufferClassname : directBufferClassnames) {
|
||||
attachmentOrByteBufferFieldNameMap.put(directBufferClassname, directBufferAttachmentFieldName);
|
||||
}
|
||||
for (final String byteBufferAsNonByteBufferClassname : byteBufferAsNonByteBufferClassnames) {
|
||||
attachmentOrByteBufferFieldNameMap.put(byteBufferAsNonByteBufferClassname, byteBufferAsNonByteBufferByteBufferFieldName);
|
||||
}
|
||||
} else if (javaVendor.equals("The Android Project")) {
|
||||
final String byteBufferAsNonByteBufferByteBufferFieldName = "byteBuffer";
|
||||
final String[] byteBufferAsNonByteBufferClassnames = new String[] { "java.nio.ByteBufferAsCharBuffer", "java.nio.ByteBufferAsDoubleBuffer", "java.nio.ByteBufferAsFloatBuffer", "java.nio.ByteBufferAsIntBuffer", "java.nio.ByteBufferAsLongBuffer", "java.nio.ByteBufferAsShortBuffer" };
|
||||
for (final String byteBufferAsNonByteBufferClassname : byteBufferAsNonByteBufferClassnames) {
|
||||
attachmentOrByteBufferFieldNameMap.put(byteBufferAsNonByteBufferClassname, byteBufferAsNonByteBufferByteBufferFieldName);
|
||||
}
|
||||
} else if (/* javaVendor.equals("Apple Inc.")|| */javaVendor.equals("Free Software Foundation, Inc.")) {
|
||||
final String byteBufferAsNonByteBufferByteBufferFieldName = "bb";
|
||||
final String[] byteBufferAsNonByteBufferClassnames = new String[] { "java.nio.CharViewBufferImpl", "java.nio.DoubleViewBufferImpl", "java.nio.FloatViewBufferImpl", "java.nio.IntViewBufferImpl", "java.nio.LongViewBufferImpl", "java.nio.ShortViewBufferImpl" };
|
||||
for (final String byteBufferAsNonByteBufferClassname : byteBufferAsNonByteBufferClassnames) {
|
||||
attachmentOrByteBufferFieldNameMap.put(byteBufferAsNonByteBufferClassname, byteBufferAsNonByteBufferByteBufferFieldName);
|
||||
}
|
||||
} else if (javaVendor.contains("Apache")) {
|
||||
final String byteBufferAsNonByteBufferByteBufferFieldName = "byteBuffer";
|
||||
final String[] byteBufferAsNonByteBufferClassnames = new String[] { "java.nio.CharToByteBufferAdapter", "java.nio.DoubleToByteBufferAdapter", "java.nio.FloatToByteBufferAdapter", "java.nio.IntToByteBufferAdapter", "java.nio.LongToByteBufferAdapter", "java.nio.ShortToByteBufferAdapter" };
|
||||
for (final String byteBufferAsNonByteBufferClassname : byteBufferAsNonByteBufferClassnames) {
|
||||
attachmentOrByteBufferFieldNameMap.put(byteBufferAsNonByteBufferClassname, byteBufferAsNonByteBufferByteBufferFieldName);
|
||||
}
|
||||
} else if (javaVendor.equals("Jeroen Frijters")) {// TODO IKVM
|
||||
} else if (javaVendor.contains("IBM")) {// TODO J9
|
||||
}
|
||||
}
|
||||
// checks if these classes are in the class library
|
||||
if (!attachmentOrByteBufferFieldNameMap.isEmpty()) {
|
||||
final List<String> classnamesToRemove = new ArrayList<>();
|
||||
for (final String classname : attachmentOrByteBufferFieldNameMap.keySet()) {
|
||||
try {
|
||||
Class.forName(classname);
|
||||
} catch (final ClassNotFoundException cnfe) {
|
||||
classnamesToRemove.add(classname);
|
||||
}
|
||||
}
|
||||
for (final String classnameToRemove : classnamesToRemove) {
|
||||
attachmentOrByteBufferFieldNameMap.remove(classnameToRemove);
|
||||
}
|
||||
}
|
||||
// builds the map used to determine the fields containing the direct
|
||||
// byte buffers
|
||||
attachmentOrByteBufferFieldMap = new HashMap<>();
|
||||
if (!attachmentOrByteBufferFieldNameMap.isEmpty()) {
|
||||
for (final Entry<String, String> attachmentOrByteBufferFieldNameEntry : attachmentOrByteBufferFieldNameMap.entrySet()) {
|
||||
final String classname = attachmentOrByteBufferFieldNameEntry.getKey();
|
||||
final String fieldname = attachmentOrByteBufferFieldNameEntry.getValue();
|
||||
try {
|
||||
final Class<?> bufferClass = Class.forName(classname);
|
||||
Field bufferField = null;
|
||||
Class<?> bufferIntermediaryClass = bufferClass;
|
||||
final List<Class<?>> intermediaryClassWithoutBufferList = new ArrayList<>();
|
||||
while (bufferIntermediaryClass != null) {
|
||||
try {
|
||||
bufferField = bufferIntermediaryClass.getDeclaredField(fieldname);
|
||||
} catch (final NoSuchFieldException nsfe) {
|
||||
if (!bufferIntermediaryClass.equals(Object.class) && !bufferIntermediaryClass.equals(Buffer.class)) {
|
||||
intermediaryClassWithoutBufferList.add(bufferIntermediaryClass);
|
||||
}
|
||||
}
|
||||
bufferIntermediaryClass = bufferIntermediaryClass.getSuperclass();
|
||||
}
|
||||
if (bufferField == null) {
|
||||
final String superClassesMsg;
|
||||
if (intermediaryClassWithoutBufferList.isEmpty()) {
|
||||
superClassesMsg = "";
|
||||
} else if (intermediaryClassWithoutBufferList.size() == 1) {
|
||||
superClassesMsg = " and in its super class " + intermediaryClassWithoutBufferList.get(0).getName();
|
||||
} else {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append(" and in its super classes");
|
||||
int classIndex = 0;
|
||||
for (final Class<?> intermediaryClassWithoutBuffer : intermediaryClassWithoutBufferList) {
|
||||
builder.append(' ');
|
||||
builder.append(intermediaryClassWithoutBuffer.getName());
|
||||
if (classIndex < intermediaryClassWithoutBufferList.size() - 1) {
|
||||
builder.append(',');
|
||||
}
|
||||
classIndex++;
|
||||
}
|
||||
superClassesMsg = builder.toString();
|
||||
}
|
||||
logger.warning("The field " + fieldname + " hasn't been found in the class " + classname + superClassesMsg);
|
||||
} else {// the field has been found, stores it into the map
|
||||
attachmentOrByteBufferFieldMap.put(bufferClass, bufferField);
|
||||
}
|
||||
} catch (final ClassNotFoundException cnfe) {// TODO The Java version
|
||||
// isn't very useful
|
||||
// under
|
||||
// Android as it is
|
||||
// always zero, rather
|
||||
// use
|
||||
// android.os.Build.VERSION.RELEASE
|
||||
// to show something
|
||||
// meaningful supported
|
||||
// since the API level 1
|
||||
final String msg = "The class " + classname + " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor + " Java version: " + javaVersion;
|
||||
logger.log(Level.WARNING, msg, cnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if a known implementation has drastically changed or if the current
|
||||
// implementation is unknown
|
||||
if (attachmentOrByteBufferFieldNameMap.isEmpty()) {// detects everything
|
||||
// with the
|
||||
// reflection API
|
||||
// creates all
|
||||
// possible kinds of
|
||||
// direct NIO buffer
|
||||
// that can contain
|
||||
// buffers (sliced
|
||||
// buffers and views)
|
||||
final ByteBuffer slicedBigEndianReadOnlyDirectByteBuffer = ((ByteBuffer) ByteBuffer.allocateDirect(2).order(ByteOrder.BIG_ENDIAN).put((byte) 0).put((byte) 0).position(1).limit(2)).slice().asReadOnlyBuffer();
|
||||
final ByteBuffer slicedBigEndianReadWriteDirectByteBuffer = ((ByteBuffer) ByteBuffer.allocateDirect(2).order(ByteOrder.BIG_ENDIAN).put((byte) 0).put((byte) 0).position(1).limit(2)).slice();
|
||||
final CharBuffer bigEndianReadOnlyDirectCharBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asCharBuffer();
|
||||
final CharBuffer bigEndianReadWriteDirectCharBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asCharBuffer();
|
||||
final DoubleBuffer bigEndianReadOnlyDirectDoubleBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asDoubleBuffer();
|
||||
final DoubleBuffer bigEndianReadWriteDirectDoubleBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asDoubleBuffer();
|
||||
final FloatBuffer bigEndianReadOnlyDirectFloatBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asFloatBuffer();
|
||||
final FloatBuffer bigEndianReadWriteDirectFloatBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asFloatBuffer();
|
||||
final IntBuffer bigEndianReadOnlyDirectIntBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asIntBuffer();
|
||||
final IntBuffer bigEndianReadWriteDirectIntBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asIntBuffer();
|
||||
final LongBuffer bigEndianReadOnlyDirectLongBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asLongBuffer();
|
||||
final LongBuffer bigEndianReadWriteDirectLongBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asLongBuffer();
|
||||
final ShortBuffer bigEndianReadOnlyDirectShortBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asShortBuffer();
|
||||
final ShortBuffer bigEndianReadWriteDirectShortBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN).asShortBuffer();
|
||||
final ByteBuffer slicedLittleEndianReadOnlyDirectByteBuffer = ((ByteBuffer) ByteBuffer.allocateDirect(2).order(ByteOrder.LITTLE_ENDIAN).put((byte) 0).put((byte) 0).position(1).limit(2)).slice().asReadOnlyBuffer();
|
||||
final ByteBuffer slicedLittleEndianReadWriteDirectByteBuffer = ((ByteBuffer) ByteBuffer.allocateDirect(2).order(ByteOrder.LITTLE_ENDIAN).put((byte) 0).put((byte) 0).position(1).limit(2)).slice();
|
||||
final CharBuffer littleEndianReadOnlyDirectCharBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asCharBuffer();
|
||||
final CharBuffer littleEndianReadWriteDirectCharBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asCharBuffer();
|
||||
final DoubleBuffer littleEndianReadOnlyDirectDoubleBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asDoubleBuffer();
|
||||
final DoubleBuffer littleEndianReadWriteDirectDoubleBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer();
|
||||
final FloatBuffer littleEndianReadOnlyDirectFloatBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asFloatBuffer();
|
||||
final FloatBuffer littleEndianReadWriteDirectFloatBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
|
||||
final IntBuffer littleEndianReadOnlyDirectIntBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asIntBuffer();
|
||||
final IntBuffer littleEndianReadWriteDirectIntBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
|
||||
final LongBuffer littleEndianReadOnlyDirectLongBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asLongBuffer();
|
||||
final LongBuffer littleEndianReadWriteDirectLongBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
|
||||
final ShortBuffer littleEndianReadOnlyDirectShortBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asShortBuffer();
|
||||
final ShortBuffer littleEndianReadWriteDirectShortBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
|
||||
final List<Buffer> buffers = new ArrayList<>();
|
||||
buffers.add(slicedBigEndianReadOnlyDirectByteBuffer);
|
||||
buffers.add(slicedBigEndianReadWriteDirectByteBuffer);
|
||||
buffers.add(bigEndianReadOnlyDirectCharBuffer);
|
||||
buffers.add(bigEndianReadWriteDirectCharBuffer);
|
||||
buffers.add(bigEndianReadOnlyDirectDoubleBuffer);
|
||||
buffers.add(bigEndianReadWriteDirectDoubleBuffer);
|
||||
buffers.add(bigEndianReadOnlyDirectFloatBuffer);
|
||||
buffers.add(bigEndianReadWriteDirectFloatBuffer);
|
||||
buffers.add(bigEndianReadOnlyDirectIntBuffer);
|
||||
buffers.add(bigEndianReadWriteDirectIntBuffer);
|
||||
buffers.add(bigEndianReadOnlyDirectLongBuffer);
|
||||
buffers.add(bigEndianReadWriteDirectLongBuffer);
|
||||
buffers.add(bigEndianReadOnlyDirectShortBuffer);
|
||||
buffers.add(bigEndianReadWriteDirectShortBuffer);
|
||||
buffers.add(slicedLittleEndianReadOnlyDirectByteBuffer);
|
||||
buffers.add(slicedLittleEndianReadWriteDirectByteBuffer);
|
||||
buffers.add(littleEndianReadOnlyDirectCharBuffer);
|
||||
buffers.add(littleEndianReadWriteDirectCharBuffer);
|
||||
buffers.add(littleEndianReadOnlyDirectDoubleBuffer);
|
||||
buffers.add(littleEndianReadWriteDirectDoubleBuffer);
|
||||
buffers.add(littleEndianReadOnlyDirectFloatBuffer);
|
||||
buffers.add(littleEndianReadWriteDirectFloatBuffer);
|
||||
buffers.add(littleEndianReadOnlyDirectIntBuffer);
|
||||
buffers.add(littleEndianReadWriteDirectIntBuffer);
|
||||
buffers.add(littleEndianReadOnlyDirectLongBuffer);
|
||||
buffers.add(littleEndianReadWriteDirectLongBuffer);
|
||||
buffers.add(littleEndianReadOnlyDirectShortBuffer);
|
||||
buffers.add(littleEndianReadWriteDirectShortBuffer);
|
||||
// gets the fields to access the contained buffers
|
||||
for (final Buffer buffer : buffers) {
|
||||
final Class<?> bufferClass = buffer.getClass();
|
||||
if (!attachmentOrByteBufferFieldMap.containsKey(bufferClass)) {
|
||||
Field bufferField = null;
|
||||
Class<?> bufferIntermediaryClass = bufferClass;
|
||||
while (bufferIntermediaryClass != null && bufferField == null) {
|
||||
for (final Field field : bufferIntermediaryClass.getDeclaredFields()) {
|
||||
final boolean fieldWasAccessible = field.isAccessible();
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
final Object fieldValue = field.get(buffer);
|
||||
if (fieldValue != null && fieldValue instanceof Buffer) {
|
||||
bufferField = field;
|
||||
break;
|
||||
}
|
||||
} catch (final IllegalAccessException iae) {
|
||||
logger.log(Level.WARNING, "Cannot access the field " + field.getName() + " of the class " + bufferIntermediaryClass.getName(), iae);
|
||||
} finally {
|
||||
field.setAccessible(fieldWasAccessible);
|
||||
}
|
||||
}
|
||||
bufferIntermediaryClass = bufferIntermediaryClass.getSuperclass();
|
||||
}
|
||||
if (bufferField != null) {
|
||||
attachmentOrByteBufferFieldMap.put(bufferClass, bufferField);
|
||||
}
|
||||
}
|
||||
}
|
||||
// cleans the mess
|
||||
buffersToDelete.addAll(buffers);
|
||||
}
|
||||
// builds the set of classes whose instances can be deallocated
|
||||
deallocatableBufferClassSet = new HashSet<>();
|
||||
if (javaVendor.equals("Sun Microsystems Inc.") || javaVendor.equals("Oracle Corporation") || javaVendor.equals("The Android Project")) {
|
||||
Class<?> directByteBufferClass = null;
|
||||
final String directByteBufferClassName = "java.nio.DirectByteBuffer";
|
||||
try {
|
||||
directByteBufferClass = Class.forName(directByteBufferClassName);
|
||||
} catch (final ClassNotFoundException cnfe) {
|
||||
final String msg = "The class " + directByteBufferClassName + " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor + " Java version: " + javaVersion;
|
||||
logger.log(Level.WARNING, msg, cnfe);
|
||||
}
|
||||
if (directByteBufferClass != null) {
|
||||
deallocatableBufferClassSet.add(directByteBufferClass);
|
||||
}
|
||||
} else if (/* javaVendor.equals("Apple Inc.")|| */javaVendor.equals("Free Software Foundation, Inc.")) {
|
||||
Class<?> readOnlyDirectByteBufferClass = null;
|
||||
final String readOnlyDirectByteBufferClassName = "java.nio.DirectByteBufferImpl.ReadOnly";
|
||||
try {
|
||||
readOnlyDirectByteBufferClass = Class.forName(readOnlyDirectByteBufferClassName);
|
||||
} catch (final ClassNotFoundException cnfe) {
|
||||
final String msg = "The class " + readOnlyDirectByteBufferClassName + " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor + " Java version: " + javaVersion;
|
||||
logger.log(Level.WARNING, msg, cnfe);
|
||||
}
|
||||
if (readOnlyDirectByteBufferClass != null) {
|
||||
deallocatableBufferClassSet.add(readOnlyDirectByteBufferClass);
|
||||
}
|
||||
Class<?> readWriteDirectByteBufferClass = null;
|
||||
final String readWriteDirectByteBufferClassName = "java.nio.DirectByteBufferImpl.ReadWrite";
|
||||
try {
|
||||
readWriteDirectByteBufferClass = Class.forName(readWriteDirectByteBufferClassName);
|
||||
} catch (final ClassNotFoundException cnfe) {
|
||||
final String msg = "The class " + readWriteDirectByteBufferClassName + " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor + " Java version: " + javaVersion;
|
||||
logger.log(Level.WARNING, msg, cnfe);
|
||||
}
|
||||
if (readWriteDirectByteBufferClass != null) {
|
||||
deallocatableBufferClassSet.add(readWriteDirectByteBufferClass);
|
||||
}
|
||||
} else if (javaVendor.contains("Apache")) {
|
||||
Class<?> readOnlyDirectByteBufferClass = null;
|
||||
final String readOnlyDirectByteBufferClassName = "java.nio.ReadOnlyDirectByteBuffer";
|
||||
try {
|
||||
readOnlyDirectByteBufferClass = Class.forName(readOnlyDirectByteBufferClassName);
|
||||
} catch (final ClassNotFoundException cnfe) {
|
||||
final String msg = "The class " + readOnlyDirectByteBufferClassName + " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor + " Java version: " + javaVersion;
|
||||
logger.log(Level.WARNING, msg, cnfe);
|
||||
}
|
||||
if (readOnlyDirectByteBufferClass != null) {
|
||||
deallocatableBufferClassSet.add(readOnlyDirectByteBufferClass);
|
||||
}
|
||||
Class<?> readWriteDirectByteBufferClass = null;
|
||||
final String readWriteDirectByteBufferClassName = "java.nio.ReadWriteDirectByteBuffer";
|
||||
try {
|
||||
readWriteDirectByteBufferClass = Class.forName(readWriteDirectByteBufferClassName);
|
||||
} catch (final ClassNotFoundException cnfe) {
|
||||
final String msg = "The class " + readWriteDirectByteBufferClassName + " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor + " Java version: " + javaVersion;
|
||||
logger.log(Level.WARNING, msg, cnfe);
|
||||
}
|
||||
if (readWriteDirectByteBufferClass != null) {
|
||||
deallocatableBufferClassSet.add(readWriteDirectByteBufferClass);
|
||||
}
|
||||
} else if (javaVendor.equals("Jeroen Frijters")) {// TODO IKVM
|
||||
} else if (javaVendor.contains("IBM")) {// TODO J9
|
||||
}
|
||||
// if there is no known implementation class of the direct byte buffers
|
||||
if (deallocatableBufferClassSet.isEmpty()) {// creates a read write
|
||||
// direct byte buffer
|
||||
final ByteBuffer dummyReadWriteDirectByteBuffer = ByteBuffer.allocateDirect(1);
|
||||
// gets its class
|
||||
final Class<?> readWriteDirectByteBufferClass = dummyReadWriteDirectByteBuffer.getClass();
|
||||
// stores this class
|
||||
deallocatableBufferClassSet.add(readWriteDirectByteBufferClass);
|
||||
// cleans the mess
|
||||
buffersToDelete.add(dummyReadWriteDirectByteBuffer);
|
||||
// creates a read only direct byte buffer
|
||||
final ByteBuffer dummyReadOnlyDirectByteBuffer = ByteBuffer.allocateDirect(1).asReadOnlyBuffer();
|
||||
// gets its class
|
||||
final Class<?> readOnlyDirectByteBufferClass = dummyReadOnlyDirectByteBuffer.getClass();
|
||||
// stores this class
|
||||
deallocatableBufferClassSet.add(readOnlyDirectByteBufferClass);
|
||||
// cleans the mess
|
||||
buffersToDelete.add(dummyReadOnlyDirectByteBuffer);
|
||||
}
|
||||
// builds the deallocator responsible for releasing the native memory of
|
||||
// a deallocatable byte buffer
|
||||
if (javaVendor.equals("Sun Microsystems Inc.") || javaVendor.equals("Oracle Corporation")) {
|
||||
deallocator = new OracleSunOpenJdkDeallocator();
|
||||
} else if (javaVendor.equals("The Android Project")) {
|
||||
deallocator = new AndroidDeallocator();
|
||||
} else if (/* javaVendor.equals("Apple Inc.")|| */javaVendor.equals("Free Software Foundation, Inc.")) {
|
||||
deallocator = new GnuClasspathDeallocator();
|
||||
} else if (javaVendor.contains("Apache")) {
|
||||
deallocator = new ApacheHarmonyDeallocator();
|
||||
} else if (javaVendor.equals("Jeroen Frijters")) {// TODO IKVM
|
||||
deallocator = null;
|
||||
} else if (javaVendor.contains("IBM")) {// TODO J9
|
||||
deallocator = null;
|
||||
} else {
|
||||
deallocator = null;
|
||||
}
|
||||
// final cleanup
|
||||
for (final Buffer bufferToDelete : buffersToDelete) {
|
||||
deallocate(bufferToDelete);
|
||||
}
|
||||
}
|
||||
|
||||
public ByteBuffer findDeallocatableBuffer(Buffer buffer) {
|
||||
final ByteBuffer deallocatableDirectByteBuffer;
|
||||
// looks only for the direct buffers
|
||||
if (buffer != null && buffer.isDirect()) {// looks for any contained
|
||||
// buffer in the passed buffer
|
||||
final Class<?> bufferClass = buffer.getClass();
|
||||
final Field attachmentOrByteBufferField = attachmentOrByteBufferFieldMap == null ? null : attachmentOrByteBufferFieldMap.get(bufferClass);
|
||||
final Buffer attachmentBufferOrByteBuffer;
|
||||
if (attachmentOrByteBufferField == null) {
|
||||
attachmentBufferOrByteBuffer = null;
|
||||
} else {
|
||||
Object attachedObjectOrByteBuffer;
|
||||
final boolean attachedObjectOrByteBufferFieldWasAccessible = attachmentOrByteBufferField.isAccessible();
|
||||
try {
|
||||
attachmentOrByteBufferField.setAccessible(true);
|
||||
attachedObjectOrByteBuffer = attachmentOrByteBufferField.get(buffer);
|
||||
} catch (IllegalArgumentException | IllegalAccessException iae) {
|
||||
attachedObjectOrByteBuffer = null;
|
||||
} finally {
|
||||
attachmentOrByteBufferField.setAccessible(attachedObjectOrByteBufferFieldWasAccessible);
|
||||
}
|
||||
if (attachedObjectOrByteBuffer instanceof Buffer) {
|
||||
attachmentBufferOrByteBuffer = (Buffer) attachedObjectOrByteBuffer;
|
||||
} else {
|
||||
attachmentBufferOrByteBuffer = null;
|
||||
}
|
||||
}
|
||||
// if there is no buffer inside the buffer given in input
|
||||
if (attachmentBufferOrByteBuffer == null) {// if it's a direct byte
|
||||
// buffer and if it's an
|
||||
// instance of
|
||||
// a deallocatable buffer
|
||||
// class
|
||||
if (buffer instanceof ByteBuffer && deallocatableBufferClassSet.contains(bufferClass)) {
|
||||
deallocatableDirectByteBuffer = (ByteBuffer) buffer;
|
||||
} else {// it's not a byte buffer or it's not a
|
||||
// deallocatable buffer
|
||||
deallocatableDirectByteBuffer = null;
|
||||
final String bufferClassName = bufferClass.getName();
|
||||
logger.warning("No deallocatable buffer has been found for an instance of the class " + bufferClassName + " whereas it is a direct NIO buffer");
|
||||
}
|
||||
} else {// the passed buffer contains another buffer, looks for a
|
||||
// deallocatable buffer inside it
|
||||
deallocatableDirectByteBuffer = findDeallocatableBuffer(attachmentBufferOrByteBuffer);
|
||||
}
|
||||
} else {// there is no need to clean the heap based buffers
|
||||
deallocatableDirectByteBuffer = null;
|
||||
}
|
||||
return deallocatableDirectByteBuffer;
|
||||
}
|
||||
|
||||
public void deallocate(final Buffer buffer) {
|
||||
if (deallocator != null) {
|
||||
final ByteBuffer deallocatableBuffer = findDeallocatableBuffer(buffer);
|
||||
if (deallocatableBuffer != null) {
|
||||
deallocator.run(deallocatableBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Deallocator getDeallocator() {
|
||||
return (deallocator);
|
||||
}
|
||||
|
||||
public void setDeallocator(Deallocator deallocator) {
|
||||
this.deallocator = deallocator;
|
||||
}
|
||||
|
||||
public Map<Class<?>, Field> getAttachmentOrByteBufferFieldMap() {
|
||||
return (attachmentOrByteBufferFieldMap);
|
||||
}
|
||||
|
||||
public void setAttachmentOrByteBufferFieldMap(Map<Class<?>, Field> attachmentOrByteBufferFieldMap) {
|
||||
this.attachmentOrByteBufferFieldMap = attachmentOrByteBufferFieldMap;
|
||||
}
|
||||
|
||||
public Set<Class<?>> getDeallocatableBufferClassSet() {
|
||||
return (deallocatableBufferClassSet);
|
||||
}
|
||||
|
||||
public void setDeallocatableBufferClassSet(Set<Class<?>> deallocatableBufferClassSet) {
|
||||
this.deallocatableBufferClassSet = deallocatableBufferClassSet;
|
||||
}
|
||||
}
|
@ -1,23 +1,28 @@
|
||||
package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.graphicengine.Drawable;
|
||||
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWSkin;
|
||||
|
||||
import com.jogamp.opengl.GLProfile;
|
||||
import com.jogamp.opengl.egl.EGL;
|
||||
|
||||
public class GPUDisplay implements org.warp.picalculator.gui.graphicengine.Display {
|
||||
|
||||
private boolean initialized = false;
|
||||
private CalculatorWindow wnd;
|
||||
private volatile boolean initialized = false;
|
||||
private volatile boolean created = false;
|
||||
private NEWTWindow wnd;
|
||||
private Drawable d;
|
||||
private GPURenderer r;
|
||||
|
||||
int[] size = new int[]{Main.screenSize[0], Main.screenSize[1]};
|
||||
|
||||
@Override
|
||||
public int[] getSize() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -27,8 +32,7 @@ public class GPUDisplay implements org.warp.picalculator.gui.graphicengine.Displ
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
wnd.window.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -38,59 +42,59 @@ public class GPUDisplay implements org.warp.picalculator.gui.graphicengine.Displ
|
||||
}
|
||||
wnd.window.setResizable(r);
|
||||
wnd.window.setUndecorated(!r);
|
||||
wnd.window.setPointerVisible(r);
|
||||
wnd.window.setPointerVisible(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayMode(int ww, int wh) {
|
||||
this.size[0] = ww;
|
||||
this.size[1] = wh;
|
||||
wnd.window.setSize(ww, wh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
created = true;
|
||||
r = new GPURenderer();
|
||||
wnd = new CalculatorWindow(this);
|
||||
wnd = new NEWTWindow(this);
|
||||
wnd.create();
|
||||
setDisplayMode(Main.screenSize[0], Main.screenSize[1]);
|
||||
setResizable(Utils.debugOn&!Utils.debugThirdScreen);
|
||||
setResizable(Utils.debugOn & !Utils.debugThirdScreen);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasResized() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
return Main.screenSize[0] != size[0] | Main.screenSize[1] != size[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
return size[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
return size[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// EGL.destroy(); (Automatic)
|
||||
initialized = false;
|
||||
created = false;
|
||||
wnd.window.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Drawable d) {
|
||||
this.d = d;
|
||||
wnd.window.setVisible(true);
|
||||
this.d = d;
|
||||
wnd.window.setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repaint() {
|
||||
if (d != null) {
|
||||
r.gl.glClearColor(red, green, blue, alpha);
|
||||
if (d != null & r != null && r.gl != null) {
|
||||
d.refresh();
|
||||
r.glFlush();
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,4 +103,30 @@ public class GPUDisplay implements org.warp.picalculator.gui.graphicengine.Displ
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RAWFont loadFont(String file) throws IOException {
|
||||
return new GPUFont(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RAWSkin loadSkin(String file) throws IOException {
|
||||
return new GPUSkin(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitUntilExit() {
|
||||
try {
|
||||
do {
|
||||
Thread.sleep(500);
|
||||
} while(initialized | created);
|
||||
} catch (InterruptedException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return GLProfile.isAnyAvailable() == false;
|
||||
}
|
||||
|
||||
}
|
||||
|
140
src/org/warp/picalculator/gui/graphicengine/gpu/GPUFont.java
Normal file
140
src/org/warp/picalculator/gui/graphicengine/gpu/GPUFont.java
Normal file
@ -0,0 +1,140 @@
|
||||
package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUFont;
|
||||
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
|
||||
public class GPUFont implements RAWFont {
|
||||
|
||||
public Texture texture;
|
||||
public int textureW;
|
||||
public int textureH;
|
||||
public int charW;
|
||||
public int charH;
|
||||
public int minCharIndex;
|
||||
public int maxCharIndex;
|
||||
|
||||
public int memoryWidth;
|
||||
public int memoryHeight;
|
||||
public int memoryWidthOfEachColumn;
|
||||
|
||||
private boolean initialized = false;
|
||||
private CPUFont tmpFont;
|
||||
|
||||
GPUFont(String file) throws IOException {
|
||||
load(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String file) throws IOException {
|
||||
CPUFont font = CPUFont.loadTemporaryFont(file);
|
||||
charW = font.charW;
|
||||
charH = font.charH;
|
||||
minCharIndex = font.minBound;
|
||||
maxCharIndex = font.maxBound;
|
||||
tmpFont = font;
|
||||
font = null;
|
||||
}
|
||||
|
||||
public int[] getCharIndexes(String txt) {
|
||||
final int l = txt.length();
|
||||
final int[] indexes = new int[l];
|
||||
final char[] chars = txt.toCharArray();
|
||||
for (int i = 0; i < l; i++) {
|
||||
indexes[i] = (chars[i] & 0xFFFF) - minCharIndex;
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
private void genTexture(boolean[][] chars) {
|
||||
final double totalChars = maxCharIndex - minCharIndex;
|
||||
final int w = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charW)));
|
||||
final int h = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charH)));
|
||||
final int maxIndexW = (int) Math.floor(((double) w) / ((double) charW)) - 1;
|
||||
BufferedImage bfi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
|
||||
int indexX = 0;
|
||||
int indexY = 0;
|
||||
for (int i = 0; i < totalChars; i++) {
|
||||
boolean[] currentChar = chars[i];
|
||||
if (currentChar != null && currentChar.length > 0) {
|
||||
for (int charY = 0; charY < charH; charY++) {
|
||||
for (int charX = 0; charX < charW; charX++) {
|
||||
if (currentChar[charY*charW+charX]) {
|
||||
bfi.setRGB(indexX * charW + charX, indexY * charH + charY, 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
indexX++;
|
||||
if (indexX >= maxIndexW) {
|
||||
indexX = 0;
|
||||
indexY += 1;
|
||||
}
|
||||
currentChar = null;
|
||||
}
|
||||
try {
|
||||
memoryWidth = w;
|
||||
memoryHeight = h;
|
||||
memoryWidthOfEachColumn = maxIndexW;
|
||||
texture = GPURenderer.importTexture(bfi);
|
||||
textureW = bfi.getWidth();
|
||||
textureH = bfi.getHeight();
|
||||
bfi.flush();
|
||||
bfi = null;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int powerOf2(int a) {
|
||||
return (int) (a == 0 ? 0 : Math.pow(2, 32 - Integer.numberOfLeadingZeros(a - 1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Display d) {
|
||||
genTexture(tmpFont.rawchars);
|
||||
tmpFont.chars32 = null;
|
||||
tmpFont.rawchars = null;
|
||||
tmpFont = null;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Display d) {
|
||||
if (!initialized) {
|
||||
initialize(d);
|
||||
}
|
||||
final GPURenderer r = (GPURenderer) d.getRenderer();
|
||||
r.currentFont = this;
|
||||
r.useTexture(texture, textureW, textureH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStringWidth(String text) {
|
||||
final int w = (charW + 1) * text.length();
|
||||
if (text.length() > 0) {
|
||||
return w - 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterWidth() {
|
||||
return charW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterHeight() {
|
||||
return charH;
|
||||
}
|
||||
}
|
@ -2,123 +2,261 @@ package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||
|
||||
import com.jogamp.opengl.GL2ES2;
|
||||
import com.jogamp.common.nio.Buffers;
|
||||
import com.jogamp.opengl.GL;
|
||||
import com.jogamp.opengl.GL2ES1;
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
import com.jogamp.opengl.util.texture.TextureData;
|
||||
import com.jogamp.opengl.util.texture.TextureIO;
|
||||
|
||||
public class GPURenderer implements Renderer {
|
||||
|
||||
public GL2ES2 gl;
|
||||
public GL2ES1 gl;
|
||||
|
||||
private final DeallocationHelper deallocationHelper = new DeallocationHelper();
|
||||
FloatBuffer fbVertices;
|
||||
FloatBuffer txVertices;
|
||||
FloatBuffer colVertices;
|
||||
int fbElements;
|
||||
|
||||
float[] currentColor = new float[16];
|
||||
float[] currentClearColorARGBf = new float[]{1f, 197f/255f, 194f/255f, 175f/255f};
|
||||
boolean currentTexEnabled;
|
||||
Texture currentTex;
|
||||
float currentTexWidth;
|
||||
float currentTexHeight;
|
||||
|
||||
GPUFont currentFont;
|
||||
|
||||
@Override
|
||||
public void glColor3i(int r, int gg, int b) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
final float red = ((float)r) / 255f;
|
||||
final float gre = ((float)gg) / 255f;
|
||||
final float blu = ((float)b) / 255f;
|
||||
currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor(int c) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
public void glColor3f(float red, float gre, float blu) {
|
||||
currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor4f(float red, float gre, float blu, float alp) {
|
||||
currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor(int rgb) {
|
||||
final int alpha = (rgb >> 24) & 0xFF;
|
||||
final int red = (rgb >> 16) & 0xFF;
|
||||
final int green = (rgb >> 8) & 0xFF;
|
||||
final int blue = rgb & 0xFF;
|
||||
glColor4i(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetClearColor() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
return (int)(currentClearColorARGBf[0] * 255) << 24 | (int)(currentClearColorARGBf[1] * 255) << 16 | (int)(currentClearColorARGBf[2] * 255) << 8 | (int)(currentClearColorARGBf[3] * 255);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearColor(int c) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
public void glClearColor(int rgb) {
|
||||
final float alpha = (float)((rgb >> 24) & 0xFF) / 255f;
|
||||
final float red = (float)((rgb >> 16) & 0xFF) / 255f;
|
||||
final float green = (float)((rgb >> 8) & 0xFF) / 255f;
|
||||
final float blue = (float)(rgb & 0xFF) / 255f;
|
||||
glClearColor4f(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor4i(int red, int green, int blue, int alpha) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
public void glColor4i(int r, int g, int b, int a) {
|
||||
final float red = (r) / 255f;
|
||||
final float gre = (g) / 255f;
|
||||
final float blu = (b) / 255f;
|
||||
final float alp = (a) / 255f;
|
||||
currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearColor(int red, int green, int blue, int alpha) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
public void glClearColor4i(int red, int green, int blue, int alpha) {
|
||||
final float ros = (red) / 255f;
|
||||
final float gre = (green) / 255f;
|
||||
final float blu = (blue) / 255f;
|
||||
final float alp = (alpha) / 255f;
|
||||
currentClearColorARGBf = new float[]{alp, ros, gre, blu};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClear() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
public void glClearColor4f(float red, float green, float blue, float alpha) {
|
||||
currentClearColorARGBf = new float[]{alpha, red, green, blue};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawSkin(int skinwidth, int[] skin, int x0, int y0, int s0, int t0, int s1, int t1,
|
||||
boolean transparent) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
public void glClear(int screenWidth, int screenHeight) {
|
||||
glColor(glGetClearColor());
|
||||
glFillColor(0, 0, screenWidth, screenHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawLine(int x0, int y0, int x1, int y1) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
glFillColor(x0, y0, x1-x0+1, y1-y0+1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glFillRect(int x0, int y0, int w1, int h1) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
public void glFillRect(int x, int y, int width, int height, float uvX, float uvY, float uvWidth, float uvHeight) {
|
||||
enableTexture();
|
||||
uvWidth/=currentTexWidth;
|
||||
uvX/=currentTexWidth;
|
||||
uvHeight/=currentTexHeight;
|
||||
uvY = 1 - uvY/currentTexHeight - uvHeight;
|
||||
final float[] vertices = { x, y, 0.0f, x, y + height, 0.0f, x + width, y, 0.0f, x + width, y + height, 0.0f, };
|
||||
final float[] tex_vertices = { uvX, uvY + uvHeight, uvX, uvY, uvX + uvWidth, uvY + uvHeight, uvX + uvWidth, uvY, };
|
||||
fbElements++;
|
||||
fbVertices.put(vertices);
|
||||
txVertices.put(tex_vertices);
|
||||
colVertices.put(currentColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getMatrixOfImage(BufferedImage bufferedImage) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
public void glFillColor(int x0, int y0, int w1, int h1) {
|
||||
disableTexture();
|
||||
final float[] vertices = { x0, y0, 0.0f, x0, y0 + h1, 0.0f, x0 + w1, y0, 0.0f, x0 + w1, y0 + h1, 0.0f, };
|
||||
final float[] tex_vertices = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, };
|
||||
fbElements++;
|
||||
fbVertices.put(vertices);
|
||||
txVertices.put(tex_vertices);
|
||||
colVertices.put(currentColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringLeft(int x, int y, String text) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
final int txtLen = text.length();
|
||||
int[] txtArray = currentFont.getCharIndexes(text);
|
||||
int tableIndexX;
|
||||
int tableIndexY;
|
||||
for (int currentCharIndex = 0; currentCharIndex < txtLen; currentCharIndex++) {
|
||||
tableIndexX = txtArray[currentCharIndex] % currentFont.memoryWidthOfEachColumn;
|
||||
tableIndexY = (txtArray[currentCharIndex] - tableIndexX) / currentFont.memoryWidthOfEachColumn;
|
||||
glFillRect(x + currentCharIndex * (currentFont.charW + 1), y, currentFont.charW, currentFont.charH, tableIndexX*currentFont.charW, tableIndexY*currentFont.charH, currentFont.charW, currentFont.charH);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringCenter(int x, int y, String text) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
glDrawStringLeft(x - (currentFont.getStringWidth(text) / 2), y, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringRight(int x, int y, String text) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glSetFont(RAWFont font) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetStringWidth(RAWFont rf, String text) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetFontWidth(FontMetrics fm, String text) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
glDrawStringLeft(x - currentFont.getStringWidth(text), y, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RAWFont getCurrentFont() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return currentFont;
|
||||
}
|
||||
|
||||
static Texture importTexture(GL gl, String string) throws IOException {
|
||||
final FileInputStream f = new FileInputStream("test.png");
|
||||
final TextureData tx_dat = TextureIO.newTextureData(gl.getGLProfile(), f, false, TextureIO.PNG);
|
||||
final Texture tex = new Texture(gl, tx_dat);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
|
||||
return tex;
|
||||
}
|
||||
|
||||
static BufferedImage openTexture(String file) throws GLException, IOException {
|
||||
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
return ImageIO.read(GPURenderer.class.getClassLoader().getResource(file));
|
||||
}
|
||||
|
||||
static Texture importTexture(BufferedImage img) throws GLException, IOException {
|
||||
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
ImageIO.write(img, "png", os);
|
||||
final InputStream fis = new ByteArrayInputStream(os.toByteArray());
|
||||
return TextureIO.newTexture(fis, false, TextureIO.PNG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearSkin() {
|
||||
if (currentTex != null) {
|
||||
currentTex = null;
|
||||
endDrawCycle();
|
||||
startDrawCycle();
|
||||
}
|
||||
}
|
||||
|
||||
public void startDrawCycle() {
|
||||
fbVertices = Buffers.newDirectFloatBuffer(3 * 4);
|
||||
txVertices = Buffers.newDirectFloatBuffer(2 * 4);
|
||||
colVertices = Buffers.newDirectFloatBuffer(4 * 4);
|
||||
fbElements = 0;
|
||||
}
|
||||
|
||||
public void endDrawCycle() {
|
||||
fbVertices.rewind();
|
||||
txVertices.rewind();
|
||||
colVertices.rewind();
|
||||
|
||||
gl.glColorPointer(4, GL.GL_FLOAT, 0, colVertices);
|
||||
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, txVertices);
|
||||
gl.glVertexPointer(3, GL.GL_FLOAT, 0, fbVertices);
|
||||
|
||||
if (currentTexEnabled) {
|
||||
gl.glEnable(GL2ES1.GL_TEXTURE_2D);
|
||||
currentTex.bind(gl);
|
||||
} else {
|
||||
gl.glDisable(GL2ES1.GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
deleteBuffer(fbVertices);
|
||||
deleteBuffer(txVertices);
|
||||
deleteBuffer(colVertices);
|
||||
fbVertices = null;
|
||||
txVertices = null;
|
||||
colVertices = null;
|
||||
}
|
||||
|
||||
public void deleteBuffer(final Buffer realNioBuffer) {
|
||||
if (deallocationHelper != null) {
|
||||
deallocationHelper.deallocate(realNioBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void disableTexture() {
|
||||
endDrawCycle();
|
||||
startDrawCycle();
|
||||
currentTexEnabled = false;
|
||||
}
|
||||
|
||||
void enableTexture() {
|
||||
endDrawCycle();
|
||||
startDrawCycle();
|
||||
currentTexEnabled = true;
|
||||
}
|
||||
|
||||
void useTexture(Texture t, float w, float h) {
|
||||
enableTexture();
|
||||
currentTex = t;
|
||||
currentTexWidth = w;
|
||||
currentTexHeight = h;
|
||||
}
|
||||
}
|
||||
|
58
src/org/warp/picalculator/gui/graphicengine/gpu/GPUSkin.java
Normal file
58
src/org/warp/picalculator/gui/graphicengine/gpu/GPUSkin.java
Normal file
@ -0,0 +1,58 @@
|
||||
package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWSkin;
|
||||
|
||||
import com.jogamp.opengl.GL2ES1;
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
|
||||
public class GPUSkin implements RAWSkin {
|
||||
|
||||
public Texture t;
|
||||
public int w;
|
||||
public int h;
|
||||
|
||||
private String texturePath;
|
||||
private boolean initialized = false;
|
||||
|
||||
GPUSkin(String file) throws IOException {
|
||||
load(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String file) throws IOException {
|
||||
if ((this.getClass().getClassLoader().getResource(file)) == null) {
|
||||
throw new IOException("File '" + file + "' not found!");
|
||||
}
|
||||
texturePath = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Display d) {
|
||||
try {
|
||||
BufferedImage i = GPURenderer.openTexture(texturePath);
|
||||
GL2ES1 gl = ((GPURenderer)d.getRenderer()).gl;
|
||||
t = GPURenderer.importTexture(i);
|
||||
w = i.getWidth();
|
||||
h = i.getHeight();
|
||||
t.setTexParameteri(gl, GL2ES1.GL_TEXTURE_MAG_FILTER, GL2ES1.GL_NEAREST);
|
||||
initialized = true;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Display d) {
|
||||
if (!initialized) {
|
||||
initialize(d);
|
||||
}
|
||||
final GPURenderer r = (GPURenderer) d.getRenderer();
|
||||
r.useTexture(t,w,h);
|
||||
}
|
||||
|
||||
}
|
381
src/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java
Normal file
381
src/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java
Normal file
@ -0,0 +1,381 @@
|
||||
/**
|
||||
* Copyright 2012-2013 JogAmp Community. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of JogAmp Community.
|
||||
*/
|
||||
|
||||
package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import com.jogamp.opengl.GL;
|
||||
import com.jogamp.opengl.GL2ES1;
|
||||
import com.jogamp.opengl.GLAutoDrawable;
|
||||
import com.jogamp.opengl.GLEventListener;
|
||||
import com.jogamp.opengl.GLProfile;
|
||||
import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
|
||||
import com.jogamp.opengl.fixedfunc.GLPointerFunc;
|
||||
import com.jogamp.opengl.GLCapabilities;
|
||||
import com.jogamp.newt.event.KeyEvent;
|
||||
import com.jogamp.newt.event.KeyListener;
|
||||
import com.jogamp.newt.event.WindowEvent;
|
||||
import com.jogamp.newt.event.WindowListener;
|
||||
import com.jogamp.newt.event.WindowUpdateEvent;
|
||||
import com.jogamp.newt.opengl.GLWindow;
|
||||
|
||||
import com.jogamp.opengl.util.*;
|
||||
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
|
||||
import org.warp.picalculator.device.Keyboard;
|
||||
import org.warp.picalculator.device.Keyboard.Key;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.Display;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* __ __|_ ___________________________________________________________________________ ___|__ __
|
||||
* // /\ _ /\ \\
|
||||
* //____/ \__ __ _____ _____ _____ _____ _____ | | __ _____ _____ __ __/ \____\\
|
||||
* \ \ / / __| | | __| _ | | _ | | | __| | | __| | /\ \ / /
|
||||
* \____\/_/ | | | | | | | | | | | __| | | | | | | | | | |__ " \_\/____/
|
||||
* /\ \ |_____|_____|_____|__|__|_|_|_|__| | | |_____|_____|_____|_____| _ / /\
|
||||
* / \____\ http://jogamp.org |_| /____/ \
|
||||
* \ / "' _________________________________________________________________________ `" \ /
|
||||
* \/____. .____\/
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* JOGL2 OpenGL ES 2 demo to expose and learn what the RAW OpenGL ES 2 API looks
|
||||
* like.
|
||||
*
|
||||
* Compile, run and enjoy:
|
||||
* wget
|
||||
* http://jogamp.org/deployment/jogamp-current/archive/jogamp-all-platforms.7z
|
||||
* 7z x jogamp-all-platforms.7z
|
||||
* cd jogamp-all-platforms
|
||||
* mkdir -p demos/es2
|
||||
* cd demos/es2
|
||||
* wget
|
||||
* https://raw.github.com/xranby/jogl-demos/master/src/demos/es2/RawGL2ES1demo.java
|
||||
* cd ../..
|
||||
* javac -cp jar/jogl-all.jar:jar/gluegen-rt.jar demos/es2/RawGL2ES1demo.java
|
||||
* java -cp jar/jogl-all.jar:jar/gluegen-rt.jar:. demos.es2.RawGL2ES1demo
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Xerxes Rånby (xranby)
|
||||
*/
|
||||
|
||||
public class NEWTWindow implements GLEventListener {
|
||||
|
||||
private final GPUDisplay disp;
|
||||
private final GPURenderer renderer;
|
||||
|
||||
public NEWTWindow(GPUDisplay disp) {
|
||||
this.disp = disp;
|
||||
renderer = disp.getRenderer();
|
||||
}
|
||||
|
||||
public GLWindow window;
|
||||
|
||||
public void create() {
|
||||
/* This demo are based on the GL2ES1 GLProfile that uses common hardware acceleration
|
||||
* functionality of desktop OpenGL 3, 2 and mobile OpenGL ES 2 devices.
|
||||
* JogAmp JOGL will probe all the installed libGL.so, libEGL.so and libGLESv2.so librarys on
|
||||
* the system to find which one provide hardware acceleration for your GPU device.
|
||||
* Its common to find more than one version of these librarys installed on a system.
|
||||
* For example on a ARM Linux system JOGL may find
|
||||
* Hardware accelerated Nvidia tegra GPU drivers in: /usr/lib/nvidia-tegra/libEGL.so
|
||||
* Software rendered Mesa Gallium driver in: /usr/lib/arm-linux-gnueabi/mesa-egl/libEGL.so.1
|
||||
* Software rendered Mesa X11 in: /usr/lib/arm-linux-gnueabi/mesa/libGL.so
|
||||
* Good news!: JOGL does all this probing for you all you have to do are to ask for
|
||||
* the GLProfile you want to use.
|
||||
*/
|
||||
|
||||
System.out.println("Loading OpenGL...");
|
||||
System.out.println(GLProfile.glAvailabilityToString());
|
||||
if (GLProfile.isAnyAvailable()) {
|
||||
System.err.println("Le OpenGL non sono presenti su questo computer!");
|
||||
}
|
||||
final GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES1));
|
||||
System.out.println("Loaded OpenGL");
|
||||
// We may at this point tweak the caps and request a translucent drawable
|
||||
caps.setBackgroundOpaque(true); //transparency window
|
||||
final GLWindow glWindow = GLWindow.create(caps);
|
||||
window = glWindow;
|
||||
|
||||
glWindow.setTitle("Algebraic Calculator for Raspberry PI by Andrea Cavalli (XDrake99)");
|
||||
|
||||
glWindow.addWindowListener(new WindowListener() {
|
||||
|
||||
@Override
|
||||
public void windowDestroyNotify(WindowEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDestroyed(WindowEvent e) {
|
||||
DisplayManager.display.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowGainedFocus(WindowEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowLostFocus(WindowEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowMoved(WindowEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowRepaint(WindowUpdateEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowResized(WindowEvent e) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
glWindow.addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent arg0) {
|
||||
Keyboard.debugKeyCode = arg0.getKeyCode();
|
||||
}
|
||||
|
||||
@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_P:
|
||||
if (Keyboard.alpha) {
|
||||
Keyboard.keyReleased(Key.PI);
|
||||
} 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);
|
||||
}
|
||||
int row = 2;
|
||||
int col = 1;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = false;
|
||||
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 0x15:
|
||||
case KeyEvent.VK_SHIFT:
|
||||
Keyboard.keyReleased(Key.SHIFT);
|
||||
break;
|
||||
case KeyEvent.VK_A:
|
||||
Keyboard.keyReleased(Key.ALPHA);
|
||||
break;
|
||||
case KeyEvent.VK_M:
|
||||
Keyboard.keyPressed(Key.SURD_MODE);
|
||||
break;
|
||||
case KeyEvent.VK_LEFT:
|
||||
//LEFT
|
||||
row = 2;
|
||||
col = 3;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = false;
|
||||
case KeyEvent.VK_RIGHT:
|
||||
//RIGHT
|
||||
row = 2;
|
||||
col = 5;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
glWindow.addGLEventListener(this /* GLEventListener */);
|
||||
final Animator animator = new Animator();
|
||||
animator.add(glWindow);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(GLAutoDrawable drawable) {
|
||||
final GL2ES1 gl = drawable.getGL().getGL2ES1();
|
||||
|
||||
//Vsync
|
||||
gl.setSwapInterval(2);
|
||||
|
||||
//Textures
|
||||
gl.glEnable(GL.GL_TEXTURE_2D);
|
||||
|
||||
//Transparency
|
||||
gl.glEnable(GL2ES1.GL_BLEND);
|
||||
gl.glBlendFunc(GL2ES1.GL_SRC_ALPHA, GL2ES1.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
try {
|
||||
renderer.currentTex = ((GPUSkin) disp.loadSkin("test.png")).t;
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
|
||||
System.err.println("INIT GL IS: " + gl.getClass().getName());
|
||||
System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
|
||||
System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
|
||||
System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
|
||||
disp.size[0] = width;
|
||||
disp.size[1] = height;
|
||||
final GL2ES1 gl = glad.getGL().getGL2ES1();
|
||||
float max_wh, min_wh;
|
||||
if (width == 0) {
|
||||
width = 1;
|
||||
}
|
||||
if (height == 0) {
|
||||
height = 1;
|
||||
}
|
||||
if (width > height) {
|
||||
max_wh = width;
|
||||
min_wh = height;
|
||||
} else {
|
||||
max_wh = height;
|
||||
min_wh = width;
|
||||
}
|
||||
|
||||
gl.glViewport(0, 0, width, height);
|
||||
|
||||
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
|
||||
gl.glOrtho(0.0, width, height, 0.0, -1, 1);
|
||||
|
||||
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(GLAutoDrawable glad) {
|
||||
final GL2ES1 gl = glad.getGL().getGL2ES1();
|
||||
|
||||
renderer.gl = gl;
|
||||
|
||||
gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);
|
||||
gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
renderer.startDrawCycle();
|
||||
|
||||
disp.repaint();
|
||||
|
||||
renderer.endDrawCycle();
|
||||
|
||||
renderer.gl = null;
|
||||
|
||||
gl.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);
|
||||
gl.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
|
||||
gl.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(GLAutoDrawable drawable) {
|
||||
System.out.println("cleanup");
|
||||
final GL2ES1 gl = drawable.getGL().getGL2ES1();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +1,53 @@
|
||||
package org.warp.picalculator.gui.screens;
|
||||
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.device.Keyboard.Key;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.math.functions.Function;
|
||||
import org.warp.picalculator.math.functions.Variable.VariableValue;
|
||||
|
||||
public class ChooseVariableValueScreen extends Screen {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private MathInputScreen es;
|
||||
private final MathInputScreen es;
|
||||
public Function resultNumberValue;
|
||||
|
||||
public ChooseVariableValueScreen(MathInputScreen es, VariableValue variableValue) {
|
||||
super();
|
||||
canBeInHistory = false;
|
||||
|
||||
|
||||
this.es = es;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
}
|
||||
public void created() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void init() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
PIDisplay.renderer.glColor4i(0, 0, 0, 64);
|
||||
PIDisplay.renderer.glDrawStringCenter(Main.screenSize[0]/2+1, Main.screenSize[1]/4, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
PIDisplay.renderer.glDrawStringCenter(Main.screenSize[0]/2, Main.screenSize[1]/4+1, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
PIDisplay.renderer.glDrawStringCenter(Main.screenSize[0]/2+1, Main.screenSize[1]/4+1, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
PIDisplay.renderer.glColor3i(255, 0, 0);
|
||||
PIDisplay.renderer.glDrawStringCenter(Main.screenSize[0]/2, Main.screenSize[1]/4, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
Utils.getFont(false, true).use(DisplayManager.display);
|
||||
DisplayManager.renderer.glColor4i(0, 0, 0, 64);
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2 + 1, Main.screenSize[1] / 2 - 20, "WORK IN PROGRESS.");
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2, Main.screenSize[1] / 2 - 20 + 1, "WORK IN PROGRESS.");
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2 + 1, Main.screenSize[1] / 2 - 20 + 1, "WORK IN PROGRESS.");
|
||||
DisplayManager.renderer.glColor3i(255, 0, 0);
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2, Main.screenSize[1] / 2 - 20, "WORK IN PROGRESS.");
|
||||
|
||||
Utils.getFont(false, false).use(DisplayManager.display);
|
||||
DisplayManager.renderer.glColor4i(0, 0, 0, 64);
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2 + 1, Main.screenSize[1] / 2, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2, Main.screenSize[1] / 2 + 1, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2 + 1, Main.screenSize[1] / 2 + 1, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
DisplayManager.renderer.glColor3i(255, 0, 0);
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2, Main.screenSize[1] / 2, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,7 +10,7 @@ public class EmptyScreen extends Screen {
|
||||
super();
|
||||
canBeInHistory = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
endLoading = 0;
|
||||
@ -27,7 +27,7 @@ public class EmptyScreen extends Screen {
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -37,7 +37,7 @@ public class EmptyScreen extends Screen {
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(Key k) {
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
package org.warp.picalculator.gui.screens;
|
||||
|
||||
import static org.warp.picalculator.device.graphicengine.cpu.CPUDisplay.Render.*;
|
||||
import static org.warp.picalculator.gui.PIDisplay.colore;
|
||||
import static org.warp.picalculator.gui.PIDisplay.fonts;
|
||||
import static org.warp.picalculator.gui.DisplayManager.fonts;
|
||||
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.device.Keyboard.Key;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||
|
||||
public class KeyboardDebugScreen extends Screen {
|
||||
|
||||
@ -14,169 +13,168 @@ public class KeyboardDebugScreen extends Screen {
|
||||
public String keyevent;
|
||||
public static int keyX;
|
||||
public static int keyY;
|
||||
public static String[] log = new String[]{"POWER ON","LOADING","LOADED","DONE","---"};
|
||||
public static String[] log = new String[] { "POWER ON", "LOADING", "LOADED", "DONE", "---" };
|
||||
public long beforetime;
|
||||
|
||||
|
||||
public KeyboardDebugScreen() {
|
||||
super();
|
||||
canBeInHistory = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws InterruptedException {
|
||||
}
|
||||
public void created() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void init() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
PIDisplay.renderer.glSetFont(fonts[2]);
|
||||
colore(0.75f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringRight(Main.screenSize[0] - 10, 30, "-" + keyevent.toUpperCase() + "-");
|
||||
Renderer renderer = DisplayManager.renderer;
|
||||
fonts[2].use(DisplayManager.display);
|
||||
renderer.glColor4f(0.75f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glDrawStringRight(Main.screenSize[0] - 10, 30, "-" + keyevent.toUpperCase() + "-");
|
||||
if (keyevent != "NONE") {
|
||||
PIDisplay.renderer.glSetFont(fonts[2]);
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringLeft(10, 30, "Key position");
|
||||
PIDisplay.renderer.glDrawStringLeft(10, 45, "X: " + keyX + ", Y:" + keyY);
|
||||
PIDisplay.renderer.glDrawStringLeft(10, 65, "Key value");
|
||||
PIDisplay.renderer.glDrawStringLeft(10, 80, key);
|
||||
fonts[2].use(DisplayManager.display);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glDrawStringLeft(10, 30, "Key position");
|
||||
renderer.glDrawStringLeft(10, 45, "X: " + keyX + ", Y:" + keyY);
|
||||
renderer.glDrawStringLeft(10, 65, "Key value");
|
||||
renderer.glDrawStringLeft(10, 80, key);
|
||||
}
|
||||
PIDisplay.renderer.glSetFont(fonts[3]);
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
fonts[3].use(DisplayManager.display);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (log[i] != null) {
|
||||
PIDisplay.renderer.glDrawStringLeft(10, 230 + 15*(i+1), log[i].toUpperCase());
|
||||
renderer.glDrawStringLeft(10, 230 + 15 * (i + 1), log[i].toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
//FROM SERIAL
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glFillRect(-80+100+200, 90, 5, 5);
|
||||
PIDisplay.renderer.glFillRect(-80+100, 100, 200, 70);
|
||||
PIDisplay.renderer.glSetFont(fonts[2]);
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter(-80+100+200/2, 100+70/2-(PIDisplay.renderer.getCurrentFont().charH/2), "FROM SERIAL");
|
||||
PIDisplay.renderer.glSetFont(fonts[3]);
|
||||
colore(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glFillColor(-80 + 100 + 200, 90, 5, 5);
|
||||
renderer.glFillColor(-80 + 100, 100, 200, 70);
|
||||
fonts[2].use(DisplayManager.display);
|
||||
renderer.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
renderer.glDrawStringCenter(-80 + 100 + 200 / 2, 100 + 70 / 2 - (renderer.getCurrentFont().getCharacterHeight() / 2), "FROM SERIAL");
|
||||
fonts[3].use(DisplayManager.display);
|
||||
renderer.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (pinsA[i] == 1) {
|
||||
colore(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else if (pinsA[i] == 2) {
|
||||
colore(0.5f, 0.5f, 1.0f, 1.0f);
|
||||
renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
|
||||
} else if (pinsA[i] == -1) {
|
||||
colore(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
} else if (pinsA[i] == 0) {
|
||||
colore(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
PIDisplay.renderer.glFillRect(-80+103+25*(7-i), 80, 20, 20);
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter(-80+113+25*(7-i), 90-(PIDisplay.renderer.getCurrentFont().charH/2), ""+(i+1));
|
||||
renderer.glFillColor(-80 + 103 + 25 * (7 - i), 80, 20, 20);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glDrawStringCenter(-80 + 113 + 25 * (7 - i), 90 - (renderer.getCurrentFont().getCharacterHeight() / 2), "" + (i + 1));
|
||||
}
|
||||
for (int i = 15; i >= 8; i--) {
|
||||
if (pinsA[i] == 1) {
|
||||
colore(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else if (pinsA[i] == 2) {
|
||||
colore(0.5f, 0.5f, 1.0f, 1.0f);
|
||||
renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
|
||||
} else if (pinsA[i] == -1) {
|
||||
colore(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
} else if (pinsA[i] == 0) {
|
||||
colore(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
PIDisplay.renderer.glFillRect(-80+103+25*(i-8), 170, 20, 20);
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter(-80+113+25*(i-8), 180-(PIDisplay.renderer.getCurrentFont().charH/2), ""+(i+1));
|
||||
renderer.glFillColor(-80 + 103 + 25 * (i - 8), 170, 20, 20);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glDrawStringCenter(-80 + 113 + 25 * (i - 8), 180 - (renderer.getCurrentFont().getCharacterHeight() / 2), "" + (i + 1));
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (dataA[i]) {
|
||||
colore(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else {
|
||||
colore(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
PIDisplay.renderer.glFillRect(-80+160+10*(i), 150, 8, 8);
|
||||
renderer.glFillColor(-80 + 160 + 10 * (i), 150, 8, 8);
|
||||
}
|
||||
|
||||
//TO SERIAL
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glFillRect(150+90, 200, 5, 5);
|
||||
PIDisplay.renderer.glFillRect(150+100, 100, 200, 70);
|
||||
PIDisplay.renderer.glSetFont(fonts[2]);
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter(150+100+200/2, 100+70/2-(PIDisplay.renderer.getCurrentFont().charH/2), "TO SERIAL");
|
||||
PIDisplay.renderer.glSetFont(fonts[3]);
|
||||
colore(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glFillColor(150 + 90, 200, 5, 5);
|
||||
renderer.glFillColor(150 + 100, 100, 200, 70);
|
||||
fonts[2].use(DisplayManager.display);
|
||||
renderer.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
renderer.glDrawStringCenter(150 + 100 + 200 / 2, 100 + 70 / 2 - (renderer.getCurrentFont().getCharacterHeight() / 2), "TO SERIAL");
|
||||
fonts[3].use(DisplayManager.display);
|
||||
renderer.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
for (int i = 15; i >= 8; i--) {
|
||||
if (pinsB[i] == 1) {
|
||||
colore(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else if (pinsB[i] == 2) {
|
||||
colore(0.5f, 0.5f, 1.0f, 1.0f);
|
||||
renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
|
||||
} else if (pinsB[i] == -1) {
|
||||
colore(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
} else if (pinsB[i] == 0) {
|
||||
colore(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
PIDisplay.renderer.glFillRect(150+103+25*(15-i), 80, 20, 20);
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter(150+113+25*(15-i), 90-(PIDisplay.renderer.getCurrentFont().charH/2), ""+(i+1));
|
||||
renderer.glFillColor(150 + 103 + 25 * (15 - i), 80, 20, 20);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glDrawStringCenter(150 + 113 + 25 * (15 - i), 90 - (renderer.getCurrentFont().getCharacterHeight() / 2), "" + (i + 1));
|
||||
}
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
if (pinsB[i] == 1) {
|
||||
colore(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else if (pinsB[i] == 2) {
|
||||
colore(0.5f, 0.5f, 1.0f, 1.0f);
|
||||
renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
|
||||
} else if (pinsB[i] == -1) {
|
||||
colore(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
} else if (pinsB[i] == 0) {
|
||||
colore(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
PIDisplay.renderer.glFillRect(150+103+25*(i), 170, 20, 20);
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter(150+113+25*(i), 180-(PIDisplay.renderer.getCurrentFont().charH/2), ""+(i+1));
|
||||
renderer.glFillColor(150 + 103 + 25 * (i), 170, 20, 20);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glDrawStringCenter(150 + 113 + 25 * (i), 180 - (renderer.getCurrentFont().getCharacterHeight() / 2), "" + (i + 1));
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (dataB[i]) {
|
||||
colore(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else {
|
||||
colore(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
PIDisplay.renderer.glFillRect(150+160+10*(i), 150, 8, 8);
|
||||
renderer.glFillColor(150 + 160 + 10 * (i), 150, 8, 8);
|
||||
}
|
||||
|
||||
|
||||
//GPIO
|
||||
for (int i = 0; i < 40; i++) {
|
||||
if (gpio[i] == true) {
|
||||
colore(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else {
|
||||
colore(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
if (i % 2 == 0) {
|
||||
PIDisplay.renderer.glFillRect(53+15*((i)/2), 50, 5, 5);
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter(55+15*((i)/2), 60, ""+(i+1));
|
||||
renderer.glFillColor(53 + 15 * ((i) / 2), 50, 5, 5);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glDrawStringCenter(55 + 15 * ((i) / 2), 60, "" + (i + 1));
|
||||
} else {
|
||||
PIDisplay.renderer.glFillRect(53+15*((i-1)/2), 40, 5, 5);
|
||||
colore(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter(55+15*((i-1)/2), 35-PIDisplay.renderer.getCurrentFont().charH, ""+(i+1));
|
||||
renderer.glFillColor(53 + 15 * ((i - 1) / 2), 40, 5, 5);
|
||||
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glDrawStringCenter(55 + 15 * ((i - 1) / 2), 35 - renderer.getCurrentFont().getCharacterHeight(), "" + (i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//KEYS
|
||||
for (int c = 0; c < 8; c++) {
|
||||
for (int r = 0; r < 8; r++) {
|
||||
if (ks[c][r]) {
|
||||
colore(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
} else {
|
||||
colore(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
PIDisplay.renderer.glFillRect(250+6*c, 250+6*r, 5, 5);
|
||||
renderer.glFillColor(250 + 6 * c, 250 + 6 * r, 5, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
if (System.currentTimeMillis()-beforetime >= 1000) {
|
||||
if (System.currentTimeMillis() - beforetime >= 1000) {
|
||||
keyevent = "NONE";
|
||||
keyX = 0;
|
||||
keyY = 0;
|
||||
@ -208,19 +206,18 @@ public class KeyboardDebugScreen extends Screen {
|
||||
key = k.toString();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static int[] pinsA = new int[]{2, 2, 2, 2, 2, 2, 2, 1, -1, -1, 0, 0, 0, 0, 2, -1};
|
||||
public static int[] pinsB = new int[]{0, 0, 2, 2, 2, 2, -1, 1, 0, -1, 2, 2, 2, 2, 0, -1};
|
||||
public static int[] pinsA = new int[] { 2, 2, 2, 2, 2, 2, 2, 1, -1, -1, 0, 0, 0, 0, 2, -1 };
|
||||
public static int[] pinsB = new int[] { 0, 0, 2, 2, 2, 2, -1, 1, 0, -1, 2, 2, 2, 2, 0, -1 };
|
||||
public static boolean[] dataA = new boolean[8];
|
||||
public static boolean[] dataB = new boolean[8];
|
||||
public static boolean[][] ks = new boolean[8][8];
|
||||
public static boolean[] gpio = new boolean[40];
|
||||
|
||||
|
||||
public static void log(String str) {
|
||||
String[] newlog = log;
|
||||
final String[] newlog = log;
|
||||
for (int i = 1; i < 5; i++) {
|
||||
newlog[i-1] = newlog[i];
|
||||
newlog[i - 1] = newlog[i];
|
||||
}
|
||||
newlog[4] = "[" + System.currentTimeMillis() + "]" + str;
|
||||
log = newlog;
|
||||
|
@ -1,79 +1,74 @@
|
||||
package org.warp.picalculator.gui.screens;
|
||||
|
||||
import static org.warp.picalculator.gui.PIDisplay.colore;
|
||||
import static org.warp.picalculator.gui.PIDisplay.fonts;
|
||||
import static org.warp.picalculator.gui.DisplayManager.colore;
|
||||
import static org.warp.picalculator.gui.DisplayManager.fonts;
|
||||
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.device.Keyboard.Key;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.GraphicUtils;
|
||||
|
||||
public class LoadingScreen extends Screen {
|
||||
|
||||
public float endLoading;
|
||||
boolean mustRefresh = true;
|
||||
public float loadingTextTranslation = 0.0f;
|
||||
public boolean loadingTextTranslationTopToBottom = true;
|
||||
private boolean loading;
|
||||
private static final String titleString = "PICalculator by Andrea Cavalli";
|
||||
private static final String titleString = "Andrea Cavalli's Algebraic Calculator";
|
||||
|
||||
public LoadingScreen() {
|
||||
super();
|
||||
canBeInHistory = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
endLoading = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws InterruptedException {
|
||||
}
|
||||
|
||||
public void init() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
if (loadingTextTranslation >= 10.0f) {
|
||||
loadingTextTranslation = 10.0f;
|
||||
loadingTextTranslationTopToBottom = false;
|
||||
} else if (loadingTextTranslation <= -10.0f) {
|
||||
loadingTextTranslation = -10.0f;
|
||||
loadingTextTranslationTopToBottom = true;
|
||||
}
|
||||
loadingTextTranslation = GraphicUtils.sinDeg(endLoading * 90f) * 10f;
|
||||
|
||||
if (loadingTextTranslationTopToBottom) {
|
||||
loadingTextTranslation += dt * 15;
|
||||
} else {
|
||||
loadingTextTranslation -= dt * 15;
|
||||
}
|
||||
|
||||
endLoading += dt;
|
||||
if (endLoading >= 2) {
|
||||
if (endLoading >= 5f) {
|
||||
loading = false;
|
||||
PIDisplay.INSTANCE.setScreen(new MathInputScreen());
|
||||
DisplayManager.INSTANCE.setScreen(new MathInputScreen());
|
||||
}
|
||||
mustRefresh = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
PIDisplay.renderer.glSetFont(fonts[2]);
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter((Main.screenSize[0] / 2) - 1,(int) ((Main.screenSize[1]/ 2) - 25 + loadingTextTranslation), titleString);
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter((Main.screenSize[0] / 2) + 1,(int) ((Main.screenSize[1]/ 2) - 25 + loadingTextTranslation), titleString);
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1]/ 2) - 25 - 1 + loadingTextTranslation), titleString);
|
||||
colore(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1]/ 2) - 25 + 1 + loadingTextTranslation), titleString);
|
||||
colore(1.0f, 0.5f, 0.0f, 1.0f);
|
||||
PIDisplay.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1]/ 2) - 25 + loadingTextTranslation), titleString);
|
||||
colore(0.0f, 0.0f, 0.0f, 0.75f);
|
||||
PIDisplay.renderer.glSetFont(fonts[0]);
|
||||
PIDisplay.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (Main.screenSize[1]/ 2) + 11, "LOADING");
|
||||
PIDisplay.renderer.glSetFont(fonts[1]);
|
||||
colore(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
PIDisplay.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (Main.screenSize[1]/ 2) + 22, "PLEASE WAIT...");
|
||||
|
||||
fonts[2].use(DisplayManager.display);
|
||||
DisplayManager.renderer.glClearColor(0xFF000000);
|
||||
DisplayManager.renderer.glClear(DisplayManager.display.getWidth(), DisplayManager.display.getWidth());
|
||||
DisplayManager.renderer.glColor3i(230, 33, 23);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2) - 1, (int) ((Main.screenSize[1] / 2) - 25 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2) - 2, (int) ((Main.screenSize[1] / 2) - 25 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2) + 1, (int) ((Main.screenSize[1] / 2) - 25 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2) + 2, (int) ((Main.screenSize[1] / 2) - 25 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1] / 2) - 25 - 1 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1] / 2) - 25 - 2 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1] / 2) - 25 + 1 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1] / 2) - 25 + 2 + loadingTextTranslation), titleString);
|
||||
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2) + 1, (int) ((Main.screenSize[1] / 2) - 25 + 1 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2) - 1, (int) ((Main.screenSize[1] / 2) - 25 + 1 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2) - 1, (int) ((Main.screenSize[1] / 2) - 25 - 1 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2) + 1, (int) ((Main.screenSize[1] / 2) - 25 - 1 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glColor3i(255, 255, 255);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (int) ((Main.screenSize[1] / 2) - 25 + loadingTextTranslation), titleString);
|
||||
DisplayManager.renderer.glColor4f(0.0f, 0.0f, 0.0f, 0.75f);
|
||||
fonts[0].use(DisplayManager.display);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (Main.screenSize[1] / 2) + 11, "LOADING");
|
||||
fonts[1].use(DisplayManager.display);
|
||||
DisplayManager.renderer.glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
DisplayManager.renderer.glDrawStringCenter((Main.screenSize[0] / 2), (Main.screenSize[1] / 2) + 22, "PLEASE WAIT...");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -8,17 +8,16 @@ import javax.imageio.ImageIO;
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.device.Keyboard;
|
||||
import org.warp.picalculator.device.Keyboard.Key;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWSkin;
|
||||
|
||||
public class MarioScreen extends Screen {
|
||||
|
||||
private int[] skin;
|
||||
private int[] skinSize;
|
||||
private int[] ground;
|
||||
private int[] groundSize;
|
||||
private RAWSkin skin;
|
||||
private RAWSkin groundskin;
|
||||
private boolean errored;
|
||||
public float[] marioPos = new float[]{30,0};
|
||||
public float[] marioForces = new float[]{0,0};
|
||||
public float[] marioPos = new float[] { 30, 0 };
|
||||
public float[] marioForces = new float[] { 0, 0 };
|
||||
public float walkAnimation = 0;
|
||||
public float jumptime = 0;
|
||||
public boolean walking = false;
|
||||
@ -26,8 +25,8 @@ public class MarioScreen extends Screen {
|
||||
public boolean jumping = false;
|
||||
public boolean flipped = false;
|
||||
public boolean onGround = true;
|
||||
public int[] marioSkinPos = new int[]{0,0};
|
||||
|
||||
public int[] marioSkinPos = new int[] { 0, 0 };
|
||||
|
||||
public MarioScreen() {
|
||||
super();
|
||||
canBeInHistory = false;
|
||||
@ -35,25 +34,14 @@ public class MarioScreen extends Screen {
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
BufferedImage img;
|
||||
try {
|
||||
img = ImageIO.read(Main.instance.getClass().getResource("/marioskin.png"));
|
||||
skin = PIDisplay.renderer.getMatrixOfImage(img);
|
||||
skinSize = new int[] { img.getWidth(), img.getHeight() };
|
||||
skin = DisplayManager.display.loadSkin("marioskin.png");
|
||||
groundskin = DisplayManager.display.loadSkin("marioground.png");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
errored = true;
|
||||
}
|
||||
try {
|
||||
img = ImageIO.read(Main.instance.getClass().getResource("/marioground.png"));
|
||||
ground = PIDisplay.renderer.getMatrixOfImage(img);
|
||||
groundSize = new int[] { img.getWidth(), img.getHeight() };
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
errored = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
if (!errored) {
|
||||
@ -65,36 +53,36 @@ public class MarioScreen extends Screen {
|
||||
public void beforeRender(float dt) {
|
||||
if (!errored) {
|
||||
walkAnimation += dt;
|
||||
boolean rightPressed = Keyboard.isKeyDown(2, 5);
|
||||
boolean leftPressed = Keyboard.isKeyDown(2, 3);
|
||||
boolean jumpPressed = Keyboard.isKeyDown(2, 1);
|
||||
final boolean rightPressed = Keyboard.isKeyDown(2, 5);
|
||||
final boolean leftPressed = Keyboard.isKeyDown(2, 3);
|
||||
final boolean jumpPressed = Keyboard.isKeyDown(2, 1);
|
||||
if ((leftPressed || rightPressed) == (leftPressed & rightPressed)) {
|
||||
walking = false;
|
||||
walkAnimation = 0;
|
||||
} else {
|
||||
if (rightPressed) { //RIGHT
|
||||
if (marioForces[0] < 500f) {
|
||||
marioForces[0] += dt*500f;
|
||||
marioForces[0] += dt * 500f;
|
||||
}
|
||||
walking = true;
|
||||
flipped = false;
|
||||
}
|
||||
if (leftPressed) { //LEFT
|
||||
if (marioForces[0] > -500f) {
|
||||
marioForces[0] -= dt*500f;
|
||||
marioForces[0] -= dt * 500f;
|
||||
}
|
||||
walking = true;
|
||||
flipped = true;
|
||||
}
|
||||
}
|
||||
if (jumpPressed) { //JUMP
|
||||
jumptime+=dt;
|
||||
jumptime += dt;
|
||||
if (!jumping && onGround) {
|
||||
marioForces[1] = dt*(4*1569.6f);
|
||||
marioForces[1] = dt * (4 * 1569.6f);
|
||||
jumping = true;
|
||||
onGround = false;
|
||||
} else if (jumptime <= 0.5f) {
|
||||
marioForces[1] = dt*(4*1569.6f);
|
||||
marioForces[1] = dt * (4 * 1569.6f);
|
||||
}
|
||||
} else {
|
||||
jumping = false;
|
||||
@ -104,7 +92,7 @@ public class MarioScreen extends Screen {
|
||||
marioSkinPos[0] = 0;
|
||||
marioSkinPos[1] = 0;
|
||||
} else if (onGround & walking & !running & !jumping && walkAnimation >= 0.08) {
|
||||
while(walkAnimation > 0.08) {
|
||||
while (walkAnimation > 0.08) {
|
||||
walkAnimation -= 0.08;
|
||||
if (marioSkinPos[0] == 1 & marioSkinPos[1] == 0) {
|
||||
marioSkinPos[0] += 2;
|
||||
@ -121,42 +109,44 @@ public class MarioScreen extends Screen {
|
||||
marioSkinPos[0] = 5;
|
||||
marioSkinPos[1] = 1;
|
||||
}
|
||||
marioForces[1] -= dt*1569.6;
|
||||
marioPos[0] += dt*marioForces[0];
|
||||
marioForces[1] -= dt * 1569.6;
|
||||
marioPos[0] += dt * marioForces[0];
|
||||
if (!onGround) {
|
||||
marioPos[1] -= dt*marioForces[1];
|
||||
marioPos[1] -= dt * marioForces[1];
|
||||
}
|
||||
marioForces[0] *= 0.75;
|
||||
|
||||
PIDisplay.renderer.glClearColor(0xff9290ff);
|
||||
DisplayManager.renderer.glClearColor(0xff9290ff);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
if (errored) {
|
||||
PIDisplay.renderer.glDrawStringLeft(0, 20, "ERROR");
|
||||
DisplayManager.renderer.glDrawStringLeft(0, 20, "ERROR");
|
||||
} else {
|
||||
PIDisplay.renderer.glSetFont(PIDisplay.fonts[0]);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 0, 25+25, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16, 25+25, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*2, 25+25, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*3, 25+25, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*4, 25+25, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*5, 25+25, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*6, 25+25, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*7, 25+25, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*8, 25+25, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 0, 25+25+16, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16, 25+25+16, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*2, 25+25+16, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*3, 25+25+16, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*4, 25+25+16, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*5, 25+25+16, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*6, 25+25+16, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*7, 25+25+16, 0, 0, 16, 16, false);
|
||||
PIDisplay.renderer.glDrawSkin(groundSize[0], ground, 16*8, 25+25+16, 0, 0, 16, 16, false);
|
||||
|
||||
DisplayManager.fonts[0].use(DisplayManager.display);
|
||||
groundskin.use(DisplayManager.display);
|
||||
DisplayManager.renderer.glFillRect(16 * 0, 25 + 25, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 1, 25 + 25, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 2, 25 + 25, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 3, 25 + 25, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 4, 25 + 25, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 5, 25 + 25, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 6, 25 + 25, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 7, 25 + 25, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 8, 25 + 25, 16, 16, 0, 0, 16, 16);
|
||||
|
||||
DisplayManager.renderer.glFillRect(16 * 0, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 1, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 2, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 3, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 4, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 5, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 6, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 7, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
DisplayManager.renderer.glFillRect(16 * 8, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
|
||||
// EASTER EGG
|
||||
// glSetFont(PIDisplay.fonts[4]);
|
||||
// glColor(0xFF000000);
|
||||
@ -173,9 +163,11 @@ public class MarioScreen extends Screen {
|
||||
// glDrawStringRight(0, Main.screenSize[1]-glGetCurrentFontHeight(), "F");
|
||||
// glColor(0xffede7);
|
||||
// glDrawStringRight(0, Main.screenSize[1]-glGetCurrentFontHeight(), "G");
|
||||
|
||||
|
||||
//DRAW MARIO
|
||||
PIDisplay.renderer.glDrawSkin(skinSize[0], skin, getPosX()-18, 25+getPosY(), 35*(marioSkinPos[0]+(flipped?2:1)), 27*marioSkinPos[1], 35*(marioSkinPos[0]+(flipped?1:2)), 27*(marioSkinPos[1]+1), true);
|
||||
skin.use(DisplayManager.display);
|
||||
DisplayManager.renderer.glFillRect(getPosX() - 18, 25 + getPosY(), 35, 27, 35 * (marioSkinPos[0] + 1), 27 * marioSkinPos[1], 35, 27);
|
||||
// PIDisplay.renderer.glDrawSkin(getPosX() - 18, 25 + getPosY(), 35 * (marioSkinPos[0] + (flipped ? 2 : 1)), 27 * marioSkinPos[1], 35 * (marioSkinPos[0] + (flipped ? 1 : 2)), 27 * (marioSkinPos[1] + 1), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,13 +185,13 @@ public class MarioScreen extends Screen {
|
||||
public boolean keyPressed(Key k) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private int getPosX() {
|
||||
return (int)marioPos[0];
|
||||
return (int) marioPos[0];
|
||||
}
|
||||
|
||||
|
||||
private int getPosY() {
|
||||
return (int)marioPos[1];
|
||||
return (int) marioPos[1];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,8 +15,9 @@ import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.device.Keyboard;
|
||||
import org.warp.picalculator.device.Keyboard.Key;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||
import org.warp.picalculator.math.AngleMode;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
import org.warp.picalculator.math.MathematicalSymbols;
|
||||
@ -42,17 +43,17 @@ public class MathInputScreen extends Screen {
|
||||
public int errorLevel = 0; // 0 = nessuno, 1 = risultato, 2 = tutto
|
||||
boolean mustRefresh = true;
|
||||
boolean afterDoNextStep = false;
|
||||
|
||||
|
||||
public MathInputScreen() {
|
||||
super();
|
||||
canBeInHistory = true;
|
||||
|
||||
|
||||
calc = new Calculator();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -114,14 +115,14 @@ public class MathInputScreen extends Screen {
|
||||
}
|
||||
|
||||
public void interpreta(boolean temporary) throws Error {
|
||||
String eqn = nuovaEquazione;
|
||||
final String eqn = nuovaEquazione;
|
||||
if (!temporary) {
|
||||
equazioneCorrente = eqn;
|
||||
}
|
||||
|
||||
|
||||
calc.parseInputString(eqn);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
showCaretDelta += dt;
|
||||
@ -134,39 +135,39 @@ public class MathInputScreen extends Screen {
|
||||
caretPos = nuovaEquazione.length();
|
||||
}
|
||||
|
||||
if (PIDisplay.error == null) {
|
||||
PIDisplay.renderer.glClearColor(0xFFc5c2af);
|
||||
if (DisplayManager.error == null) {
|
||||
DisplayManager.renderer.glClearColor(0xFFc5c2af);
|
||||
} else {
|
||||
PIDisplay.renderer.glClearColor(0xFFDC3C32);
|
||||
DisplayManager.renderer.glClearColor(0xFFDC3C32);
|
||||
}
|
||||
}
|
||||
|
||||
private static final RAWFont fontBig = Utils.getFont(false);
|
||||
|
||||
|
||||
@Override
|
||||
public void renderStatusbar() {
|
||||
PIDisplay.renderer.glColor3i(0, 0, 0);
|
||||
int pos = 2;
|
||||
int spacersNumb = 1;
|
||||
Renderer renderer = DisplayManager.renderer;
|
||||
renderer.glColor3f(1, 1, 1);
|
||||
final int pos = 2;
|
||||
final int spacersNumb = 1;
|
||||
int skinN = 0;
|
||||
if (calc.exactMode) {
|
||||
skinN = 22;
|
||||
PIDisplay.drawSkinPart(2 + 18 * pos + 2 * spacersNumb, 2, 16 * skinN, 16 * 0, 16 + 16 * skinN, 16 + 16 * 0);
|
||||
} else {
|
||||
skinN = 21;
|
||||
PIDisplay.drawSkinPart(2 + 18 * pos + 2 * spacersNumb, 2, 16 * skinN, 16 * 0, 16 + 16 * skinN, 16 + 16 * 0);
|
||||
}
|
||||
renderer.glFillRect(2 + 18 * pos + 2 * spacersNumb, 2, 16, 16, 16 * skinN, 16 * 0, 16, 16);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
PIDisplay.renderer.glSetFont(fontBig);
|
||||
fontBig.use(DisplayManager.display);
|
||||
final int textColor = 0xFF000000;
|
||||
final int padding = 4;
|
||||
PIDisplay.renderer.glColor(textColor);
|
||||
final int caretRealPos = MathematicalSymbols.getGraphicRepresentation(nuovaEquazione.substring(0, caretPos)).length()*(fontBig.charW+1);
|
||||
DisplayManager.renderer.glColor(textColor);
|
||||
final int caretRealPos = MathematicalSymbols.getGraphicRepresentation(nuovaEquazione.substring(0, caretPos)).length() * (fontBig.getCharacterWidth() + 1);
|
||||
final String inputTextWithoutCaret = MathematicalSymbols.getGraphicRepresentation(nuovaEquazione);
|
||||
final boolean tooLongI = padding+PIDisplay.renderer.glGetStringWidth(fontBig, nuovaEquazione)+padding >= Main.screenSize[0];
|
||||
final boolean tooLongI = padding + fontBig.getStringWidth(nuovaEquazione) + padding >= Main.screenSize[0];
|
||||
int scrollI = 0;
|
||||
if (tooLongI) {
|
||||
scrollI = -scrollX;
|
||||
@ -176,23 +177,23 @@ public class MathInputScreen extends Screen {
|
||||
scrollI = 0;
|
||||
}
|
||||
}
|
||||
PIDisplay.renderer.glDrawStringLeft(padding+scrollI, padding+20, inputTextWithoutCaret);
|
||||
DisplayManager.renderer.glDrawStringLeft(padding + scrollI, padding + 20, inputTextWithoutCaret);
|
||||
if (showCaret) {
|
||||
PIDisplay.renderer.glDrawStringLeft(padding+scrollI+caretRealPos, padding+20, "|");
|
||||
DisplayManager.renderer.glDrawStringLeft(padding + scrollI + caretRealPos, padding + 20, "|");
|
||||
}
|
||||
if (tooLongI) {
|
||||
PIDisplay.renderer.glColor(PIDisplay.renderer.glGetClearColor());
|
||||
PIDisplay.renderer.glFillRect(Main.screenSize[0]-16-2, padding+20, fontBig.charH, Main.screenSize[0]);
|
||||
PIDisplay.renderer.glColor(textColor);
|
||||
PIDisplay.drawSkinPart(Main.screenSize[0]-16, padding+20+fontBig.charH/2-16/2, 304, 0, 304+16, 16);
|
||||
DisplayManager.renderer.glColor(DisplayManager.renderer.glGetClearColor());
|
||||
DisplayManager.renderer.glFillColor(Main.screenSize[0] - 16 - 2, padding + 20, fontBig.getCharacterHeight(), Main.screenSize[0]);
|
||||
DisplayManager.renderer.glColor(textColor);
|
||||
DisplayManager.drawSkinPart(Main.screenSize[0] - 16, padding + 20 + fontBig.getCharacterHeight() / 2 - 16 / 2, 304, 0, 304 + 16, 16);
|
||||
}
|
||||
if (calc.f != null) {
|
||||
int topSpacing = 0;
|
||||
Iterator<Function> iter = calc.f.iterator();
|
||||
final Iterator<Function> iter = calc.f.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Function fnc = iter.next();
|
||||
final Function fnc = iter.next();
|
||||
try {
|
||||
final boolean tooLong = padding+fnc.getWidth()+padding >= Main.screenSize[0];
|
||||
final boolean tooLong = padding + fnc.getWidth() + padding >= Main.screenSize[0];
|
||||
int scrollA = 0;
|
||||
if (tooLong) {
|
||||
scrollA = -scrollX;
|
||||
@ -202,15 +203,15 @@ public class MathInputScreen extends Screen {
|
||||
scrollA = 0;
|
||||
}
|
||||
}
|
||||
final int y = padding+20+padding+fontBig.charH+1+topSpacing;
|
||||
fnc.draw(padding+scrollA, y);
|
||||
final int y = padding + 20 + padding + fontBig.getCharacterHeight() + 1 + topSpacing;
|
||||
fnc.draw(padding + scrollA, y);
|
||||
if (tooLong) {
|
||||
PIDisplay.renderer.glColor(PIDisplay.renderer.glGetClearColor());
|
||||
PIDisplay.renderer.glFillRect(Main.screenSize[0]-16-2, y, fnc.getHeight(), Main.screenSize[0]);
|
||||
PIDisplay.renderer.glColor(textColor);
|
||||
PIDisplay.drawSkinPart(Main.screenSize[0]-16, y+fnc.getHeight()/2-16/2, 304, 0, 304+16, 16);
|
||||
DisplayManager.renderer.glColor(DisplayManager.renderer.glGetClearColor());
|
||||
DisplayManager.renderer.glFillColor(Main.screenSize[0] - 16 - 2, y, fnc.getHeight(), Main.screenSize[0]);
|
||||
DisplayManager.renderer.glColor(textColor);
|
||||
DisplayManager.drawSkinPart(Main.screenSize[0] - 16, y + fnc.getHeight() / 2 - 16 / 2, 304, 0, 304 + 16, 16);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
} catch (final NullPointerException e) {
|
||||
iter.remove();
|
||||
}
|
||||
topSpacing += fnc.getHeight() + 2;
|
||||
@ -218,16 +219,16 @@ public class MathInputScreen extends Screen {
|
||||
}
|
||||
if (calc.f2 != null) {
|
||||
int bottomSpacing = 0;
|
||||
for (Function f : calc.f2) {
|
||||
bottomSpacing += f.getHeight()+2;
|
||||
f.draw(PIDisplay.display.getWidth() - 2 - f.getWidth(), PIDisplay.display.getHeight() - bottomSpacing);
|
||||
for (final Function f : calc.f2) {
|
||||
bottomSpacing += f.getHeight() + 2;
|
||||
f.draw(DisplayManager.display.getWidth() - 2 - f.getWidth(), DisplayManager.display.getHeight() - bottomSpacing);
|
||||
}
|
||||
if (calc.resultsCount > 1 && calc.resultsCount != calc.f2.size()) {
|
||||
String resultsCountText = calc.resultsCount+" total results".toUpperCase();
|
||||
PIDisplay.renderer.glColor(0xFF9AAEA0);
|
||||
PIDisplay.renderer.glSetFont(Utils.getFont(true));
|
||||
bottomSpacing += fontBig.charH+2;
|
||||
PIDisplay.renderer.glDrawStringRight(PIDisplay.display.getWidth() - 2, PIDisplay.display.getHeight() - bottomSpacing, resultsCountText);
|
||||
final String resultsCountText = calc.resultsCount + " total results".toUpperCase();
|
||||
DisplayManager.renderer.glColor(0xFF9AAEA0);
|
||||
Utils.getFont(true).use(DisplayManager.display);
|
||||
bottomSpacing += fontBig.getCharacterHeight() + 2;
|
||||
DisplayManager.renderer.glDrawStringRight(DisplayManager.display.getWidth() - 2, DisplayManager.display.getHeight() - bottomSpacing, resultsCountText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -251,26 +252,24 @@ public class MathInputScreen extends Screen {
|
||||
try {
|
||||
try {
|
||||
interpreta(true);
|
||||
showVariablesDialog(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
equazioneCorrente = nuovaEquazione;
|
||||
calc.f2 = calc.f;
|
||||
afterDoNextStep = true;
|
||||
simplify(MathInputScreen.this);
|
||||
}
|
||||
showVariablesDialog(() -> {
|
||||
equazioneCorrente = nuovaEquazione;
|
||||
calc.f2 = calc.f;
|
||||
afterDoNextStep = true;
|
||||
simplify(MathInputScreen.this);
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
if (Utils.debugOn)
|
||||
} catch (final Exception ex) {
|
||||
if (Utils.debugOn) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
} catch (Error e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
} catch (final Error e) {
|
||||
final StringWriter sw = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
|
||||
PIDisplay.error = e.id.toString();
|
||||
DisplayManager.error = e.id.toString();
|
||||
System.err.println(e.id);
|
||||
}
|
||||
} else {
|
||||
@ -279,10 +278,10 @@ public class MathInputScreen extends Screen {
|
||||
}
|
||||
return true;
|
||||
case SOLVE:
|
||||
if (PIDisplay.error != null) {
|
||||
if (DisplayManager.error != null) {
|
||||
Utils.debug.println("Resetting after error...");
|
||||
PIDisplay.error = null;
|
||||
this.equazioneCorrente = null;
|
||||
DisplayManager.error = null;
|
||||
equazioneCorrente = null;
|
||||
calc.f = null;
|
||||
calc.f2 = null;
|
||||
calc.resultsCount = 0;
|
||||
@ -296,26 +295,24 @@ public class MathInputScreen extends Screen {
|
||||
if (nuovaEquazione != equazioneCorrente && nuovaEquazione.length() > 0) {
|
||||
changeEquationScreen();
|
||||
interpreta(true);
|
||||
showVariablesDialog(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
equazioneCorrente = nuovaEquazione;
|
||||
solve();
|
||||
}});
|
||||
showVariablesDialog(() -> {
|
||||
equazioneCorrente = nuovaEquazione;
|
||||
solve();
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
if (Utils.debugOn) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
} catch (Error e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
} catch (final Error e) {
|
||||
final StringWriter sw = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
|
||||
PIDisplay.error = e.id.toString();
|
||||
DisplayManager.error = e.id.toString();
|
||||
System.err.println(e.id);
|
||||
}
|
||||
return true;
|
||||
@ -384,7 +381,7 @@ public class MathInputScreen extends Screen {
|
||||
typeChar("√");
|
||||
return true;
|
||||
case POWER_OF_2:
|
||||
typeChar(MathematicalSymbols.POWER+"2");
|
||||
typeChar(MathematicalSymbols.POWER + "2");
|
||||
return true;
|
||||
case POWER_OF_x:
|
||||
typeChar(MathematicalSymbols.POWER);
|
||||
@ -419,12 +416,14 @@ public class MathInputScreen extends Screen {
|
||||
case DELETE:
|
||||
if (nuovaEquazione.length() > 0) {
|
||||
if (caretPos > 0) {
|
||||
caretPos-=1;
|
||||
nuovaEquazione=nuovaEquazione.substring(0, caretPos)+nuovaEquazione.substring(caretPos+1, nuovaEquazione.length());
|
||||
caretPos -= 1;
|
||||
nuovaEquazione = nuovaEquazione.substring(0, caretPos) + nuovaEquazione.substring(caretPos + 1, nuovaEquazione.length());
|
||||
} else {
|
||||
nuovaEquazione = nuovaEquazione.substring(1);
|
||||
}
|
||||
try {interpreta(true);} catch (Error e) {}
|
||||
try {
|
||||
interpreta(true);
|
||||
} catch (final Error e) {}
|
||||
}
|
||||
afterDoNextStep = false;
|
||||
return true;
|
||||
@ -434,7 +433,7 @@ public class MathInputScreen extends Screen {
|
||||
} else {
|
||||
caretPos = nuovaEquazione.length();
|
||||
}
|
||||
scrollX = PIDisplay.renderer.glGetStringWidth(fontBig, nuovaEquazione.substring(0, caretPos)+"|||");
|
||||
scrollX = fontBig.getStringWidth(nuovaEquazione.substring(0, caretPos) + "|||");
|
||||
showCaret = true;
|
||||
showCaretDelta = 0L;
|
||||
return true;
|
||||
@ -444,27 +443,27 @@ public class MathInputScreen extends Screen {
|
||||
} else {
|
||||
caretPos = 0;
|
||||
}
|
||||
scrollX = PIDisplay.renderer.glGetStringWidth(fontBig, nuovaEquazione.substring(0, caretPos)+"|||");
|
||||
scrollX = fontBig.getStringWidth(nuovaEquazione.substring(0, caretPos) + "|||");
|
||||
showCaret = true;
|
||||
showCaretDelta = 0L;
|
||||
return true;
|
||||
case RESET:
|
||||
if (PIDisplay.error != null) {
|
||||
if (DisplayManager.error != null) {
|
||||
Utils.debug.println("Resetting after error...");
|
||||
PIDisplay.error = null;
|
||||
DisplayManager.error = null;
|
||||
return true;
|
||||
} else {
|
||||
caretPos = 0;
|
||||
nuovaEquazione="";
|
||||
nuovaEquazione = "";
|
||||
afterDoNextStep = false;
|
||||
if (calc.f != null) {
|
||||
calc.f.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case SURD_MODE:
|
||||
case SURD_MODE:
|
||||
calc.exactMode = !calc.exactMode;
|
||||
if (calc.exactMode == false) {
|
||||
if (calc.exactMode == false) {
|
||||
calc.f2 = solveExpression(calc.f2);
|
||||
} else {
|
||||
equazioneCorrente = "";
|
||||
@ -472,27 +471,25 @@ public class MathInputScreen extends Screen {
|
||||
}
|
||||
return true;
|
||||
case debug1:
|
||||
PIDisplay.INSTANCE.setScreen(new EmptyScreen());
|
||||
DisplayManager.INSTANCE.setScreen(new EmptyScreen());
|
||||
return true;
|
||||
case HISTORY_BACK:
|
||||
if (PIDisplay.INSTANCE.canGoBack()) {
|
||||
if (equazioneCorrente != null && equazioneCorrente.length() > 0 & PIDisplay.sessions[PIDisplay.currentSession+1] instanceof MathInputScreen) {
|
||||
if (DisplayManager.INSTANCE.canGoBack()) {
|
||||
if (equazioneCorrente != null && equazioneCorrente.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession + 1] instanceof MathInputScreen) {
|
||||
nuovaEquazione = equazioneCorrente;
|
||||
try {
|
||||
interpreta(true);
|
||||
} catch (Error e) {
|
||||
}
|
||||
} catch (final Error e) {}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case HISTORY_FORWARD:
|
||||
if (PIDisplay.INSTANCE.canGoForward()) {
|
||||
if (equazioneCorrente != null && equazioneCorrente.length() > 0 & PIDisplay.sessions[PIDisplay.currentSession-1] instanceof MathInputScreen) {
|
||||
if (DisplayManager.INSTANCE.canGoForward()) {
|
||||
if (equazioneCorrente != null && equazioneCorrente.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession - 1] instanceof MathInputScreen) {
|
||||
nuovaEquazione = equazioneCorrente;
|
||||
try {
|
||||
interpreta(true);
|
||||
} catch (Error e) {
|
||||
}
|
||||
} catch (final Error e) {}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -527,23 +524,23 @@ public class MathInputScreen extends Screen {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ArrayList<Function> solveExpression(ArrayList<Function> f22) {
|
||||
try {
|
||||
try {
|
||||
return calc.solveExpression(f22);
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
if (Utils.debugOn) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
} catch (Error e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
} catch (final Error e) {
|
||||
final StringWriter sw = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
|
||||
PIDisplay.error = e.id.toString();
|
||||
DisplayManager.error = e.id.toString();
|
||||
System.err.println(e.id);
|
||||
}
|
||||
return null;
|
||||
@ -554,15 +551,15 @@ public class MathInputScreen extends Screen {
|
||||
try {
|
||||
showVariablesDialog();
|
||||
ArrayList<Function> results = new ArrayList<>();
|
||||
ArrayList<Function> partialResults = new ArrayList<>();
|
||||
for (Function f : calc.f2) {
|
||||
final ArrayList<Function> partialResults = new ArrayList<>();
|
||||
for (final Function f : calc.f2) {
|
||||
if (f instanceof Equation) {
|
||||
PIDisplay.INSTANCE.setScreen(new SolveEquationScreen(this));
|
||||
DisplayManager.INSTANCE.setScreen(new SolveEquationScreen(this));
|
||||
} else {
|
||||
results.add(f);
|
||||
for (Function itm : results) {
|
||||
for (final Function itm : results) {
|
||||
if (itm.isSolved() == false) {
|
||||
List<Function> dt = itm.solveOneStep();
|
||||
final List<Function> dt = itm.solveOneStep();
|
||||
partialResults.addAll(dt);
|
||||
} else {
|
||||
partialResults.add(itm);
|
||||
@ -572,34 +569,34 @@ public class MathInputScreen extends Screen {
|
||||
partialResults.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (results.size() == 0) {
|
||||
calc.resultsCount = 0;
|
||||
} else {
|
||||
calc.resultsCount = results.size();
|
||||
Collections.reverse(results);
|
||||
// add elements to al, including duplicates
|
||||
Set<Function> hs = new LinkedHashSet<>();
|
||||
final Set<Function> hs = new LinkedHashSet<>();
|
||||
hs.addAll(results);
|
||||
results.clear();
|
||||
results.addAll(hs);
|
||||
calc.f2 = results;
|
||||
for (Function rf : calc.f2) {
|
||||
for (final Function rf : calc.f2) {
|
||||
rf.generateGraphics();
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
if (Utils.debugOn) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
} catch (Error e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
} catch (final Error e) {
|
||||
final StringWriter sw = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
|
||||
PIDisplay.error = e.id.toString();
|
||||
DisplayManager.error = e.id.toString();
|
||||
System.err.println(e.id);
|
||||
}
|
||||
}
|
||||
@ -607,71 +604,72 @@ public class MathInputScreen extends Screen {
|
||||
protected void solve() {
|
||||
try {
|
||||
try {
|
||||
for (Function f : calc.f) {
|
||||
for (final Function f : calc.f) {
|
||||
if (f instanceof Equation) {
|
||||
PIDisplay.INSTANCE.setScreen(new SolveEquationScreen(this));
|
||||
DisplayManager.INSTANCE.setScreen(new SolveEquationScreen(this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Function> results = solveExpression(calc.f);
|
||||
|
||||
final ArrayList<Function> results = solveExpression(calc.f);
|
||||
if (results.size() == 0) {
|
||||
calc.resultsCount = 0;
|
||||
} else {
|
||||
calc.resultsCount = results.size();
|
||||
Collections.reverse(results);
|
||||
// add elements to al, including duplicates
|
||||
Set<Function> hs = new LinkedHashSet<>();
|
||||
final Set<Function> hs = new LinkedHashSet<>();
|
||||
hs.addAll(results);
|
||||
results.clear();
|
||||
results.addAll(hs);
|
||||
calc.f2 = results;
|
||||
for (Function rf : calc.f2) {
|
||||
for (final Function rf : calc.f2) {
|
||||
rf.generateGraphics();
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
if (Utils.debugOn) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
} catch (Error e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
} catch (final Error e) {
|
||||
final StringWriter sw = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
|
||||
PIDisplay.error = e.id.toString();
|
||||
DisplayManager.error = e.id.toString();
|
||||
System.err.println(e.id);
|
||||
}
|
||||
}
|
||||
|
||||
private void changeEquationScreen() {
|
||||
if (equazioneCorrente != null && equazioneCorrente.length() > 0) {
|
||||
MathInputScreen cloned = clone();
|
||||
final MathInputScreen cloned = clone();
|
||||
cloned.caretPos = cloned.equazioneCorrente.length();
|
||||
cloned.nuovaEquazione = cloned.equazioneCorrente;
|
||||
cloned.scrollX = PIDisplay.renderer.glGetStringWidth(fontBig, cloned.equazioneCorrente);
|
||||
try {cloned.interpreta(true);} catch (Error e) {}
|
||||
PIDisplay.INSTANCE.replaceScreen(cloned);
|
||||
this.initialized = false;
|
||||
PIDisplay.INSTANCE.setScreen(this);
|
||||
|
||||
cloned.scrollX = fontBig.getStringWidth(cloned.equazioneCorrente);
|
||||
try {
|
||||
cloned.interpreta(true);
|
||||
} catch (final Error e) {}
|
||||
DisplayManager.INSTANCE.replaceScreen(cloned);
|
||||
initialized = false;
|
||||
DisplayManager.INSTANCE.setScreen(this);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void typeChar(String chr) {
|
||||
int len = chr.length();
|
||||
nuovaEquazione=nuovaEquazione.substring(0, caretPos)+chr+nuovaEquazione.substring(caretPos, nuovaEquazione.length());
|
||||
caretPos+=len;
|
||||
scrollX = PIDisplay.renderer.glGetStringWidth(fontBig, nuovaEquazione.substring(0, caretPos)+"|||");
|
||||
final int len = chr.length();
|
||||
nuovaEquazione = nuovaEquazione.substring(0, caretPos) + chr + nuovaEquazione.substring(caretPos, nuovaEquazione.length());
|
||||
caretPos += len;
|
||||
scrollX = fontBig.getStringWidth(nuovaEquazione.substring(0, caretPos) + "|||");
|
||||
showCaret = true;
|
||||
showCaretDelta = 0L;
|
||||
afterDoNextStep = false;
|
||||
try {
|
||||
interpreta(true);
|
||||
} catch (Error e) {
|
||||
}
|
||||
} catch (final Error e) {}
|
||||
// f.clear(); //TODO: I removed this line to prevent input blanking when pressing EQUALS button and cloning this screen, but I must see why I created this part of code.
|
||||
}
|
||||
|
||||
@ -679,30 +677,30 @@ public class MathInputScreen extends Screen {
|
||||
public boolean keyReleased(Key k) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void showVariablesDialog() {
|
||||
showVariablesDialog(null);
|
||||
}
|
||||
|
||||
|
||||
public void showVariablesDialog(final Runnable runnable) {
|
||||
Thread ct = new Thread(()->{
|
||||
ArrayList<Function> variablesInFunctions = getVariables(calc.f.toArray(new Function[calc.f.size()]));
|
||||
for (VariableValue f : calc.variablesValues) {
|
||||
final Thread ct = new Thread(() -> {
|
||||
final ArrayList<Function> variablesInFunctions = getVariables(calc.f.toArray(new Function[calc.f.size()]));
|
||||
for (final VariableValue f : calc.variablesValues) {
|
||||
if (variablesInFunctions.contains(f.v)) {
|
||||
variablesInFunctions.remove(f.v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean cancelled = false;
|
||||
for (Function f : variablesInFunctions) {
|
||||
ChooseVariableValueScreen cvs = new ChooseVariableValueScreen(this, new VariableValue((Variable) f, new Number(calc, 0)));
|
||||
PIDisplay.INSTANCE.setScreen(cvs);
|
||||
for (final Function f : variablesInFunctions) {
|
||||
final ChooseVariableValueScreen cvs = new ChooseVariableValueScreen(this, new VariableValue((Variable) f, new Number(calc, 0)));
|
||||
DisplayManager.INSTANCE.setScreen(cvs);
|
||||
try {
|
||||
while (PIDisplay.screen == cvs) {
|
||||
while (DisplayManager.screen == cvs) {
|
||||
Utils.debug.println(Thread.currentThread().getName());
|
||||
Thread.sleep(200);
|
||||
}
|
||||
} catch (InterruptedException e) {}
|
||||
} catch (final InterruptedException e) {}
|
||||
if (cvs.resultNumberValue == null) {
|
||||
cancelled = true;
|
||||
break;
|
||||
@ -716,7 +714,7 @@ public class MathInputScreen extends Screen {
|
||||
calc.variablesValues.add(new VariableValue((Variable) f, (Number) cvs.resultNumberValue));
|
||||
}
|
||||
}
|
||||
if (!cancelled) {
|
||||
if (!cancelled) {
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
@ -728,16 +726,16 @@ public class MathInputScreen extends Screen {
|
||||
ct.setDaemon(true);
|
||||
ct.start();
|
||||
}
|
||||
|
||||
|
||||
private ArrayList<Function> getVariables(Function[] fncs) {
|
||||
ArrayList<Function> res = new ArrayList<>();
|
||||
for (Function f : fncs) {
|
||||
final ArrayList<Function> res = new ArrayList<>();
|
||||
for (final Function f : fncs) {
|
||||
if (f instanceof FunctionTwoValues) {
|
||||
res.addAll(getVariables(new Function[]{((FunctionTwoValues)f).getVariable1(), ((FunctionTwoValues)f).getVariable2()}));
|
||||
res.addAll(getVariables(new Function[] { ((FunctionTwoValues) f).getVariable1(), ((FunctionTwoValues) f).getVariable2() }));
|
||||
} else if (f instanceof FunctionMultipleValues) {
|
||||
res.addAll(getVariables(((FunctionMultipleValues)f).getVariables()));
|
||||
res.addAll(getVariables(((FunctionMultipleValues) f).getVariables()));
|
||||
} else if (f instanceof AnteriorFunction) {
|
||||
res.addAll(getVariables(new Function[]{((AnteriorFunction)f).getVariable()}));
|
||||
res.addAll(getVariables(new Function[] { ((AnteriorFunction) f).getVariable() }));
|
||||
} else if (f instanceof Variable) {
|
||||
if (!res.contains(f)) {
|
||||
res.add(f);
|
||||
@ -746,11 +744,11 @@ public class MathInputScreen extends Screen {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MathInputScreen clone() {
|
||||
MathInputScreen es = this;
|
||||
MathInputScreen es2 = new MathInputScreen();
|
||||
final MathInputScreen es = this;
|
||||
final MathInputScreen es2 = new MathInputScreen();
|
||||
es2.scrollX = es.scrollX;
|
||||
es2.nuovaEquazione = es.nuovaEquazione;
|
||||
es2.equazioneCorrente = es.equazioneCorrente;
|
||||
|
@ -1,10 +1,10 @@
|
||||
package org.warp.picalculator.gui.screens;
|
||||
|
||||
import org.warp.picalculator.device.Keyboard.Key;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
|
||||
public abstract class Screen {
|
||||
public PIDisplay d;
|
||||
public DisplayManager d;
|
||||
public boolean created = false;
|
||||
public boolean initialized = false;
|
||||
public boolean canBeInHistory = false;
|
||||
@ -30,9 +30,9 @@ public abstract class Screen {
|
||||
public abstract void init() throws InterruptedException;
|
||||
|
||||
public abstract void render();
|
||||
|
||||
|
||||
public void renderStatusbar() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public abstract void beforeRender(float dt);
|
||||
@ -40,6 +40,6 @@ public abstract class Screen {
|
||||
public abstract boolean mustBeRefreshed();
|
||||
|
||||
public abstract boolean keyPressed(Key k);
|
||||
|
||||
|
||||
public abstract boolean keyReleased(Key k);
|
||||
}
|
||||
|
@ -3,41 +3,40 @@ package org.warp.picalculator.gui.screens;
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Main;
|
||||
import org.warp.picalculator.device.Keyboard.Key;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
|
||||
public class SolveEquationScreen extends Screen {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private MathInputScreen es;
|
||||
private final MathInputScreen es;
|
||||
|
||||
public SolveEquationScreen(MathInputScreen es) {
|
||||
super();
|
||||
canBeInHistory = false;
|
||||
|
||||
|
||||
this.es = es;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
}
|
||||
public void created() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void init() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
PIDisplay.renderer.glColor4i(0, 0, 0, 64);
|
||||
PIDisplay.renderer.glDrawStringCenter(Main.screenSize[0]/2+1, Main.screenSize[1]/4, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
PIDisplay.renderer.glDrawStringCenter(Main.screenSize[0]/2, Main.screenSize[1]/4+1, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
PIDisplay.renderer.glDrawStringCenter(Main.screenSize[0]/2+1, Main.screenSize[1]/4+1, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
PIDisplay.renderer.glColor3i(255, 0, 0);
|
||||
PIDisplay.renderer.glDrawStringCenter(Main.screenSize[0]/2, Main.screenSize[1]/4, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
DisplayManager.renderer.glColor4i(0, 0, 0, 64);
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2 + 1, Main.screenSize[1] / 4, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2, Main.screenSize[1] / 4 + 1, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2 + 1, Main.screenSize[1] / 4 + 1, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
DisplayManager.renderer.glColor3i(255, 0, 0);
|
||||
DisplayManager.renderer.glDrawStringCenter(Main.screenSize[0] / 2, Main.screenSize[1] / 4, "WORK IN PROGRESS. THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(float dt) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -49,13 +48,13 @@ public class SolveEquationScreen extends Screen {
|
||||
public boolean keyPressed(Key k) {
|
||||
switch (k) {
|
||||
case LETTER_X:
|
||||
PIDisplay.INSTANCE.goBack();
|
||||
DisplayManager.INSTANCE.goBack();
|
||||
try {
|
||||
es.calc.solveExpression('X');
|
||||
} catch (Error e) {
|
||||
Screen scr = PIDisplay.INSTANCE.getScreen();
|
||||
} catch (final Error e) {
|
||||
final Screen scr = DisplayManager.INSTANCE.getScreen();
|
||||
if (scr instanceof MathInputScreen) {
|
||||
MathInputScreen escr = (MathInputScreen) scr;
|
||||
final MathInputScreen escr = (MathInputScreen) scr;
|
||||
escr.errorLevel = 1;
|
||||
//escr.err2 = e; //TODO: What is this variable, and why it doesn't exists?
|
||||
} else {
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.warp.picalculator.math;
|
||||
|
||||
public enum AngleMode {
|
||||
DEG,
|
||||
RAD,
|
||||
GRA
|
||||
DEG, RAD, GRA
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public class Calculator {
|
||||
public ArrayList<Function> f2;
|
||||
public ArrayList<VariableValue> variablesValues;
|
||||
public int resultsCount;
|
||||
|
||||
|
||||
public Calculator() {
|
||||
f = new ArrayList<>();
|
||||
f2 = new ArrayList<>();
|
||||
@ -34,9 +34,9 @@ public class Calculator {
|
||||
if (!string.startsWith("{")) {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
String[] parts = string.substring(1).split("\\{");
|
||||
EquationsSystem s = new EquationsSystem(this);
|
||||
for (String part : parts) {
|
||||
final String[] parts = string.substring(1).split("\\{");
|
||||
final EquationsSystem s = new EquationsSystem(this);
|
||||
for (final String part : parts) {
|
||||
s.addFunctionToEnd(parseEquationString(part));
|
||||
}
|
||||
return s;
|
||||
@ -46,16 +46,16 @@ public class Calculator {
|
||||
return new Expression(this, string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Function parseEquationString(String string) throws Error {
|
||||
String[] parts = string.split("=");
|
||||
final String[] parts = string.split("=");
|
||||
if (parts.length == 1) {
|
||||
Equation e = new Equation(this, null, null);
|
||||
final Equation e = new Equation(this, null, null);
|
||||
e.setVariable1(new Expression(this, parts[0]));
|
||||
e.setVariable2(new Number(this, BigInteger.ZERO));
|
||||
return e;
|
||||
} else if (parts.length == 2) {
|
||||
Equation e = new Equation(this, null, null);
|
||||
final Equation e = new Equation(this, null, null);
|
||||
e.setVariable1(new Expression(this, parts[0]));
|
||||
e.setVariable2(new Expression(this, parts[1]));
|
||||
return e;
|
||||
@ -66,19 +66,19 @@ public class Calculator {
|
||||
|
||||
public ArrayList<Function> solveExpression(ArrayList<Function> input) throws Error {
|
||||
ArrayList<Function> results = new ArrayList<>();
|
||||
ArrayList<Function> partialResults = new ArrayList<>();
|
||||
for (Function f : input) {
|
||||
final ArrayList<Function> partialResults = new ArrayList<>();
|
||||
for (final Function f : input) {
|
||||
if (f instanceof Equation) {
|
||||
throw new IllegalArgumentException("Not an expression!");
|
||||
} else {
|
||||
results.add(f);
|
||||
while (Utils.allSolved(results) == false) {
|
||||
for (Function itm : results) {
|
||||
for (final Function itm : results) {
|
||||
if (itm.isSolved() == false) {
|
||||
long t1 = System.currentTimeMillis();
|
||||
List<Function> dt = itm.solveOneStep();
|
||||
long t2 = System.currentTimeMillis();
|
||||
if (t2-t1 >= 3000) {
|
||||
final long t1 = System.currentTimeMillis();
|
||||
final List<Function> dt = itm.solveOneStep();
|
||||
final long t2 = System.currentTimeMillis();
|
||||
if (t2 - t1 >= 3000) {
|
||||
throw new Error(Errors.TIMEOUT);
|
||||
}
|
||||
partialResults.addAll(dt);
|
||||
@ -108,24 +108,24 @@ public class Calculator {
|
||||
}
|
||||
|
||||
public void parseInputString(String eqn) throws Error {
|
||||
ArrayList<Function> fncs = new ArrayList<>();
|
||||
final ArrayList<Function> fncs = new ArrayList<>();
|
||||
if (eqn.length() > 0) {
|
||||
try {
|
||||
fncs.add(parseString(eqn.replace("sqrt", "Ⓐ").replace("^", "Ⓑ")));
|
||||
} catch (Exception ex) {
|
||||
|
||||
} catch (final Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
f = fncs;
|
||||
for (Function f : f) {
|
||||
for (final Function f : f) {
|
||||
try {
|
||||
f.generateGraphics();
|
||||
} catch (NullPointerException ex) {
|
||||
} catch (final NullPointerException ex) {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*public void solve(EquationScreen equationScreen, char letter) throws Error {
|
||||
if (Calculator.currentSession == 0 && Calculator.sessions[0] instanceof EquationScreen) {
|
||||
EquationScreen es = (EquationScreen) Calculator.sessions[0];
|
||||
|
@ -51,7 +51,7 @@ public class MathematicalSymbols {
|
||||
}
|
||||
|
||||
public static String[] variables() {
|
||||
return new String[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "ⓧ", "Ⓨ", "Z", PI};
|
||||
return new String[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "ⓧ", "Ⓨ", "Z", PI };
|
||||
}
|
||||
|
||||
public static String[] genericSyntax() {
|
||||
@ -59,13 +59,6 @@ public class MathematicalSymbols {
|
||||
}
|
||||
|
||||
public static String getGraphicRepresentation(String string) {
|
||||
return string
|
||||
.replace("Ⓑ", "^")
|
||||
.replace("Ⓒ", "SIN")
|
||||
.replace("Ⓓ", "COS")
|
||||
.replace("Ⓔ", "TAN")
|
||||
.replace("Ⓕ", "ASIN")
|
||||
.replace("Ⓖ", "ACOS")
|
||||
.replace("Ⓗ", "ATAN");
|
||||
return string.replace("Ⓑ", "^").replace("Ⓒ", "SIN").replace("Ⓓ", "COS").replace("Ⓔ", "TAN").replace("Ⓕ", "ASIN").replace("Ⓖ", "ACOS").replace("Ⓗ", "ATAN");
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import java.util.ArrayList;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
|
||||
@ -12,17 +12,17 @@ import com.rits.cloning.Cloner;
|
||||
|
||||
public abstract class AnteriorFunction implements Function {
|
||||
public AnteriorFunction(Function value) {
|
||||
this.root = value.getRoot();
|
||||
root = value.getRoot();
|
||||
variable = value;
|
||||
}
|
||||
|
||||
|
||||
public AnteriorFunction(Calculator root, Function value) {
|
||||
this.root = root;
|
||||
variable = value;
|
||||
}
|
||||
|
||||
|
||||
protected abstract Function NewInstance(Calculator root, Function value);
|
||||
|
||||
|
||||
protected final Calculator root;
|
||||
protected Function variable;
|
||||
protected int width;
|
||||
@ -49,54 +49,54 @@ public abstract class AnteriorFunction implements Function {
|
||||
@Override
|
||||
public final ArrayList<Function> solveOneStep() throws Error {
|
||||
final boolean solved = variable.isSolved();
|
||||
ArrayList<Function> result = solved?solve():null;
|
||||
|
||||
ArrayList<Function> result = solved ? solve() : null;
|
||||
|
||||
if (result == null || result.isEmpty()) {
|
||||
result = new ArrayList<>();
|
||||
|
||||
ArrayList<Function> l1 = new ArrayList<>();
|
||||
|
||||
final ArrayList<Function> l1 = new ArrayList<>();
|
||||
if (variable.isSolved()) {
|
||||
l1.add(variable);
|
||||
} else {
|
||||
l1.addAll(variable.solveOneStep());
|
||||
}
|
||||
|
||||
for (Function f : l1) {
|
||||
result.add(NewInstance(this.root, f));
|
||||
|
||||
for (final Function f : l1) {
|
||||
result.add(NewInstance(root, f));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract ArrayList<Function> solve() throws Error;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSolved() {
|
||||
return variable.isSolved() ? !isSolvable() : false;
|
||||
}
|
||||
|
||||
|
||||
protected abstract boolean isSolvable();
|
||||
|
||||
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
variable.setSmall(small);
|
||||
variable.generateGraphics();
|
||||
|
||||
width = PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), getSymbol()) + 1 + getVariable().getWidth();
|
||||
|
||||
width = DisplayManager.renderer.glGetStringWidth(Utils.getFont(small), getSymbol()) + 1 + getVariable().getWidth();
|
||||
height = variable.getHeight();
|
||||
line = variable.getLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
float h1 = getVariable().getHeight();
|
||||
int wsegno = PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), getSymbol());
|
||||
float hsegno = Utils.getFontHeight(small);
|
||||
float maxh = getHeight();
|
||||
PIDisplay.renderer.glSetFont(Utils.getFont(small));
|
||||
|
||||
PIDisplay.renderer.glDrawStringLeft(x, (int) Math.floor(y + (maxh - hsegno) / 2), getSymbol());
|
||||
final float h1 = getVariable().getHeight();
|
||||
final int wsegno = DisplayManager.renderer.glGetStringWidth(Utils.getFont(small), getSymbol());
|
||||
final float hsegno = Utils.getFontHeight(small);
|
||||
final float maxh = getHeight();
|
||||
DisplayManager.renderer.glSetFont(Utils.getFont(small));
|
||||
|
||||
DisplayManager.renderer.glDrawStringLeft(x, (int) Math.floor(y + (maxh - hsegno) / 2), getSymbol());
|
||||
getVariable().draw(x + wsegno + 1, (int) Math.floor(y + (maxh - h1) / 2));
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ public abstract class AnteriorFunction implements Function {
|
||||
if (variable != null) {
|
||||
val1 = variable.toString();
|
||||
}
|
||||
return getSymbol()+val1;
|
||||
return getSymbol() + val1;
|
||||
// } catch (Error e) {
|
||||
// return e.id.toString();
|
||||
// }
|
||||
@ -131,20 +131,20 @@ public abstract class AnteriorFunction implements Function {
|
||||
|
||||
@Override
|
||||
public AnteriorFunction clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
final Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return variable.hashCode()+883*getSymbol().hashCode();
|
||||
return variable.hashCode() + 883 * getSymbol().hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract boolean equals(Object o);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import java.util.ArrayList;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
import org.warp.picalculator.math.MathematicalSymbols;
|
||||
@ -29,19 +29,26 @@ public class Division extends FunctionTwoValues {
|
||||
return MathematicalSymbols.DIVISION;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isSolvable() {
|
||||
if (FractionsRule1.compare(this)) return true;
|
||||
if (FractionsRule2.compare(this)) return true;
|
||||
if (FractionsRule3.compare(this)) return true;
|
||||
if (UndefinedRule2.compare(this)) return true;
|
||||
if (FractionsRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (FractionsRule2.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (FractionsRule3.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (UndefinedRule2.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (variable1 instanceof Number && variable2 instanceof Number && root.exactMode == false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ArrayList<Function> solve() throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
@ -52,15 +59,15 @@ public class Division extends FunctionTwoValues {
|
||||
} else if (FractionsRule3.compare(this)) {
|
||||
result = FractionsRule3.execute(this);
|
||||
} else if (UndefinedRule2.compare(this)) {
|
||||
result = UndefinedRule2.execute(this);
|
||||
result = UndefinedRule2.execute(this);
|
||||
} else if (variable1 instanceof Number && variable2 instanceof Number && root.exactMode == false) {
|
||||
result.add(((Number)variable1).divide((Number)variable2));
|
||||
result.add(((Number) variable1).divide((Number) variable2));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean hasMinus() {
|
||||
String numerator = variable1.toString();
|
||||
final String numerator = variable1.toString();
|
||||
if (numerator.startsWith("-")) {
|
||||
return true;
|
||||
}
|
||||
@ -68,7 +75,7 @@ public class Division extends FunctionTwoValues {
|
||||
}
|
||||
|
||||
public void draw(int x, int y, boolean small, boolean drawMinus) {
|
||||
boolean beforedrawminus = this.drawMinus;
|
||||
final boolean beforedrawminus = this.drawMinus;
|
||||
this.drawMinus = drawMinus;
|
||||
draw(x, y);
|
||||
this.drawMinus = beforedrawminus;
|
||||
@ -79,22 +86,22 @@ public class Division extends FunctionTwoValues {
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
variable1.generateGraphics();
|
||||
|
||||
|
||||
variable2.generateGraphics();
|
||||
|
||||
|
||||
width = calcWidth();
|
||||
height = calcHeight();
|
||||
line = variable1.getHeight() + 1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
// glColor3f(255, 127-50+new Random().nextInt(50), 0);
|
||||
// glFillRect(x,y,width,height);
|
||||
// glColor3f(0, 0, 0);
|
||||
|
||||
Object var1 = variable1;
|
||||
Object var2 = variable2;
|
||||
|
||||
final Object var1 = variable1;
|
||||
final Object var2 = variable2;
|
||||
boolean minus = false;
|
||||
int minusw = 0;
|
||||
int minush = 0;
|
||||
@ -105,15 +112,15 @@ public class Division extends FunctionTwoValues {
|
||||
}
|
||||
int w1 = 0;
|
||||
int h1 = 0;
|
||||
PIDisplay.renderer.glSetFont(Utils.getFont(small));
|
||||
Utils.getFont(small).use(DisplayManager.display);
|
||||
if (minus) {
|
||||
w1 = PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), numerator);
|
||||
h1 = Utils.getFont(small).charH;
|
||||
w1 = Utils.getFont(small).getStringWidth(numerator);
|
||||
h1 = Utils.getFont(small).getCharacterHeight();
|
||||
} else {
|
||||
w1 = ((Function) var1).getWidth();
|
||||
h1 = ((Function) var1).getHeight();
|
||||
}
|
||||
int w2 = ((Function) var2).getWidth();
|
||||
final int w2 = ((Function) var2).getWidth();
|
||||
int maxw;
|
||||
if (w1 > w2) {
|
||||
maxw = 1 + w1;
|
||||
@ -121,22 +128,22 @@ public class Division extends FunctionTwoValues {
|
||||
maxw = 1 + w2;
|
||||
}
|
||||
if (minus && drawMinus) {
|
||||
minusw = PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), "-") + 1;
|
||||
minush = Utils.getFont(small).charH;
|
||||
PIDisplay.renderer.glDrawStringLeft(x+1, y + h1 + 1 + 1 - (minush / 2), "-");
|
||||
PIDisplay.renderer.glDrawStringLeft((int) (x+1 + minusw + 1 + (maxw - w1) / 2d), y, numerator);
|
||||
minusw = Utils.getFont(small).getCharacterWidth() /* Width of minus */ + 1;
|
||||
minush = Utils.getFont(small).getCharacterHeight();
|
||||
DisplayManager.renderer.glDrawStringLeft(x + 1, y + h1 + 1 + 1 - (minush / 2), "-");
|
||||
DisplayManager.renderer.glDrawStringLeft((int) (x + 1 + minusw + 1 + (maxw - w1) / 2d), y, numerator);
|
||||
} else {
|
||||
((Function) var1).draw((int) (x+1 + minusw + (maxw - w1) / 2d), y);
|
||||
((Function) var1).draw((int) (x + 1 + minusw + (maxw - w1) / 2d), y);
|
||||
}
|
||||
((Function) var2).draw((int) (x+1 + minusw + (maxw - w2) / 2d), y + h1 + 1 + 1 + 1);
|
||||
PIDisplay.renderer.glFillRect(x+1+ minusw, y + h1 + 1, maxw, 1);
|
||||
((Function) var2).draw((int) (x + 1 + minusw + (maxw - w2) / 2d), y + h1 + 1 + 1 + 1);
|
||||
DisplayManager.renderer.glFillColor(x + 1 + minusw, y + h1 + 1, maxw, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int calcHeight() {
|
||||
|
||||
@ -152,7 +159,7 @@ public class Division extends FunctionTwoValues {
|
||||
} else {
|
||||
h1 = variable1.getHeight();
|
||||
}
|
||||
int h2 = variable2.getHeight();
|
||||
final int h2 = variable2.getHeight();
|
||||
return h1 + 3 + h2;
|
||||
}
|
||||
|
||||
@ -160,12 +167,12 @@ public class Division extends FunctionTwoValues {
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int calcWidth() {
|
||||
boolean minus = false;
|
||||
@ -176,28 +183,28 @@ public class Division extends FunctionTwoValues {
|
||||
}
|
||||
int w1 = 0;
|
||||
if (minus) {
|
||||
w1 = PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), numerator);
|
||||
w1 = Utils.getFont(small).getStringWidth(numerator);
|
||||
} else {
|
||||
w1 = variable1.getWidth();
|
||||
}
|
||||
int w2 = variable2.getWidth();
|
||||
final int w2 = variable2.getWidth();
|
||||
int maxw = 0;
|
||||
if (w1 > w2) {
|
||||
maxw = w1+1;
|
||||
maxw = w1 + 1;
|
||||
} else {
|
||||
maxw = w2+1;
|
||||
maxw = w2 + 1;
|
||||
}
|
||||
if (minus && drawMinus) {
|
||||
return 1 + PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), "-") + 1 + maxw;
|
||||
return 1 + Utils.getFont(small).getCharacterWidth() /* Width of minus */ + 1 + maxw;
|
||||
} else {
|
||||
return 1 + maxw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Division) {
|
||||
FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
final FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
|
||||
}
|
||||
return false;
|
||||
|
@ -4,7 +4,7 @@ import java.util.List;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
|
||||
@ -13,9 +13,9 @@ public class EmptyNumber implements Function {
|
||||
public EmptyNumber(Calculator root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
|
||||
private final Calculator root;
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return " ";
|
||||
@ -39,12 +39,12 @@ public class EmptyNumber implements Function {
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
PIDisplay.renderer.glDrawStringLeft(x, y, "␀");
|
||||
DisplayManager.renderer.glDrawStringLeft(x, y, "␀");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), "␀");
|
||||
return DisplayManager.renderer.glGetStringWidth(Utils.getFont(small), "␀");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -54,7 +54,7 @@ public class EmptyNumber implements Function {
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
return Utils.getFont(small).charH/2;
|
||||
return Utils.getFont(small).charH / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -63,12 +63,12 @@ public class EmptyNumber implements Function {
|
||||
}
|
||||
|
||||
private boolean small = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof EmptyNumber;
|
||||
|
@ -12,7 +12,7 @@ import java.util.regex.Pattern;
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Errors;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
import org.warp.picalculator.math.MathematicalSymbols;
|
||||
import org.warp.picalculator.math.functions.trigonometry.ArcCosine;
|
||||
@ -27,7 +27,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
public Expression(Calculator root) {
|
||||
super(root);
|
||||
}
|
||||
|
||||
|
||||
public Expression(Calculator root, Function[] values) {
|
||||
super(root, values);
|
||||
}
|
||||
@ -48,19 +48,19 @@ public class Expression extends FunctionMultipleValues {
|
||||
try {
|
||||
new Number(root, string);
|
||||
isNumber = true;
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch (final NumberFormatException ex) {
|
||||
isNumber = false;
|
||||
}
|
||||
|
||||
|
||||
String processExpression = string;
|
||||
Utils.debug.println(debugSpaces + "•Analyzing expression:" + processExpression);
|
||||
|
||||
|
||||
isNumber = false; //TODO: rimuovere isNumber, alcune semplificazione come la divisione per zero altrimenti verrebbero saltate.
|
||||
|
||||
if (isNumber){
|
||||
|
||||
if (isNumber) {
|
||||
// If the expression is already a number:
|
||||
// Se l'espressione è già un numero:
|
||||
Number t = new Number(root, string);
|
||||
final Number t = new Number(root, string);
|
||||
setVariables(new Function[] { t });
|
||||
Utils.debug.println(debugSpaces + "•Result:" + t.toString());
|
||||
} else {
|
||||
@ -75,7 +75,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
// Controlla se ci sono più di un uguale (=)
|
||||
int equationsFound = 0;
|
||||
int systemsFound = 0;
|
||||
for (char c : processExpression.toCharArray()) {
|
||||
for (final char c : processExpression.toCharArray()) {
|
||||
if (("" + c).equals(MathematicalSymbols.EQUATION)) {
|
||||
equationsFound += 1;
|
||||
}
|
||||
@ -98,7 +98,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
boolean symbolsChanged = false;
|
||||
while (matcher.find()) {
|
||||
symbolsChanged = true;
|
||||
String correzione = "+";
|
||||
final 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);
|
||||
}
|
||||
@ -109,11 +109,11 @@ public class Expression extends FunctionMultipleValues {
|
||||
matcher = pattern.matcher(processExpression);
|
||||
while (matcher.find()) {
|
||||
symbolsChanged = true;
|
||||
String correzione = "-";
|
||||
final 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("(+")) {
|
||||
symbolsChanged = true;
|
||||
@ -138,11 +138,11 @@ public class Expression extends FunctionMultipleValues {
|
||||
symbolsChanged = false;
|
||||
while (matcher.find()) {
|
||||
symbolsChanged = true;
|
||||
String correzione = matcher.group(0).replaceFirst(Matcher.quoteReplacement("+"), "");
|
||||
final 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 −
|
||||
processExpression = processExpression.replace("-", MathematicalSymbols.SUBTRACTION);
|
||||
|
||||
@ -151,11 +151,11 @@ public class Expression extends FunctionMultipleValues {
|
||||
matcher = pattern.matcher(processExpression);
|
||||
while (matcher.find()) {
|
||||
symbolsChanged = true;
|
||||
String correzione = MathematicalSymbols.MINUS;
|
||||
final String correzione = MathematicalSymbols.MINUS;
|
||||
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + 2, processExpression.length());
|
||||
matcher = pattern.matcher(processExpression);
|
||||
}
|
||||
|
||||
|
||||
// Cambia il segno iniziale − in -
|
||||
if (processExpression.startsWith("−")) {
|
||||
symbolsChanged = true;
|
||||
@ -186,7 +186,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
symbolsChanged = 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);
|
||||
final String newexp = matcher.group(0).substring(1, matcher.group(0).length() - 1);
|
||||
String afterexp = processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
|
||||
if (Pattern.compile("[^\\-" + Utils.ArrayToRegex(Utils.add(concat(MathematicalSymbols.functions(), concat(MathematicalSymbols.signums(true), MathematicalSymbols.genericSyntax())), "(")) + "]$").matcher(beforeexp).find()) {
|
||||
// Se la stringa precedente finisce con un numero
|
||||
@ -211,13 +211,13 @@ public class Expression extends FunctionMultipleValues {
|
||||
debugSpaces += " ";
|
||||
|
||||
// Convert the expression to a list of objects
|
||||
Expression imputRawParenthesis = new Expression(root);
|
||||
final Expression imputRawParenthesis = new Expression(root);
|
||||
imputRawParenthesis.setVariables(new Function[] {});
|
||||
String tmp = "";
|
||||
final String[] functions = concat(concat(concat(concat(MathematicalSymbols.functions(), MathematicalSymbols.parentheses()), MathematicalSymbols.signums(true)), MathematicalSymbols.variables()), MathematicalSymbols.genericSyntax());
|
||||
for (int i = 0; i < processExpression.length(); i++) {
|
||||
// Per ogni carattere cerca se è un numero o una funzione:
|
||||
String charI = processExpression.charAt(i) + "";
|
||||
final String charI = processExpression.charAt(i) + "";
|
||||
if (Utils.isInArray(charI, functions)) {
|
||||
|
||||
// Finds the type of function fron the following list
|
||||
@ -326,7 +326,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
Utils.debug.println(debugSpaces + "•Added multiplication to expression:" + new Multiplication(root, null, null).getSymbol());
|
||||
}
|
||||
} else {
|
||||
Function precedentFunction = imputRawParenthesis.getVariable(imputRawParenthesis.getVariablesLength() - 1);
|
||||
final Function precedentFunction = imputRawParenthesis.getVariable(imputRawParenthesis.getVariablesLength() - 1);
|
||||
if (tmp.length() > 0) {
|
||||
if (precedentFunction instanceof Number || precedentFunction instanceof Variable) {
|
||||
imputRawParenthesis.addFunctionToEnd(new Multiplication(root, null, null));
|
||||
@ -366,7 +366,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
// Se il carattere è un numero intero, un segno
|
||||
// negativo, o un punto
|
||||
tmp += charI;
|
||||
} catch (Exception exc) {
|
||||
} catch (final 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!");
|
||||
}
|
||||
}
|
||||
@ -375,7 +375,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
Utils.debug.println(debugSpaces + "•Added variable to expression:" + tmp);
|
||||
try {
|
||||
imputRawParenthesis.addFunctionToEnd(new Number(root, tmp));
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch (final NumberFormatException ex) {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
tmp = "";
|
||||
@ -392,9 +392,9 @@ public class Expression extends FunctionMultipleValues {
|
||||
Utils.debug.println(debugSpaces + "•Removing useless parentheses");
|
||||
for (int i = 0; i < imputRawParenthesis.functions.length; i++) {
|
||||
if (imputRawParenthesis.functions[i] instanceof Expression) {
|
||||
Expression par = (Expression) imputRawParenthesis.functions[i];
|
||||
final Expression par = (Expression) imputRawParenthesis.functions[i];
|
||||
if (par.functions.length == 1) {
|
||||
Function subFunz = par.functions[0];
|
||||
final Function subFunz = par.functions[0];
|
||||
if (subFunz instanceof Expression || subFunz instanceof Number || subFunz instanceof Variable) {
|
||||
imputRawParenthesis.functions[i] = subFunz;
|
||||
Utils.debug.println(debugSpaces + " •Useless parentheses removed");
|
||||
@ -402,21 +402,21 @@ public class Expression extends FunctionMultipleValues {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Inizia l'affinazione dell'espressione
|
||||
Utils.debug.println(debugSpaces + "•Pushing classes...");
|
||||
|
||||
Function[] oldFunctionsArray = imputRawParenthesis.getVariables();
|
||||
ArrayList<Function> oldFunctionsList = new ArrayList<>();
|
||||
final Function[] oldFunctionsArray = imputRawParenthesis.getVariables();
|
||||
final ArrayList<Function> oldFunctionsList = new ArrayList<>();
|
||||
for (int i = 0; i < oldFunctionsArray.length; i++) {
|
||||
Function funzione = oldFunctionsArray[i];
|
||||
if (funzione != null) {
|
||||
//Affinazione
|
||||
if (funzione instanceof Root) {
|
||||
if ((i - 1) >= 0 && oldFunctionsArray[i-1] instanceof Number && ((Number)oldFunctionsArray[i-1]).getTerm().compareTo(new BigDecimal(2)) == 0) {
|
||||
if (funzione instanceof Root) {
|
||||
if ((i - 1) >= 0 && oldFunctionsArray[i - 1] instanceof Number && ((Number) oldFunctionsArray[i - 1]).getTerm().compareTo(new BigDecimal(2)) == 0) {
|
||||
oldFunctionsArray[i] = null;
|
||||
oldFunctionsArray[i-1] = null;
|
||||
oldFunctionsList.remove(oldFunctionsList.size()-1);
|
||||
oldFunctionsArray[i - 1] = null;
|
||||
oldFunctionsList.remove(oldFunctionsList.size() - 1);
|
||||
i -= 1;
|
||||
funzione = new RootSquare(root, null);
|
||||
}
|
||||
@ -452,64 +452,12 @@ public class Expression extends FunctionMultipleValues {
|
||||
oldFunctionsList.set(0, new Multiplication(root, oldFunctionsList.get(0), oldFunctionsList.remove(1)));
|
||||
}
|
||||
}
|
||||
Utils.debug.println(debugSpaces + " •Phase: "+step);
|
||||
Utils.debug.println(debugSpaces + " •Phase: " + step);
|
||||
while (i < oldFunctionsList.size() && change == false && oldFunctionsList.size() > 1) {
|
||||
Function funzioneTMP = oldFunctionsList.get(i);
|
||||
final Function funzioneTMP = oldFunctionsList.get(i);
|
||||
if (funzioneTMP instanceof FunctionTwoValues) {
|
||||
if (step != "SN Functions") {
|
||||
if (
|
||||
(step == "sums" && (funzioneTMP instanceof Sum || funzioneTMP instanceof SumSubtraction || funzioneTMP instanceof Subtraction) == true && ((funzioneTMP instanceof AnteriorFunction && ((AnteriorFunction) funzioneTMP).variable == null) || (funzioneTMP instanceof FunctionTwoValues && ((FunctionTwoValues) funzioneTMP).variable1 == null && ((FunctionTwoValues) funzioneTMP).variable2 == null) || (!(funzioneTMP instanceof AnteriorFunction) && !(funzioneTMP instanceof FunctionTwoValues))))
|
||||
||
|
||||
(
|
||||
step.equals("multiplications")
|
||||
&&
|
||||
(
|
||||
(funzioneTMP instanceof Multiplication)
|
||||
||
|
||||
(funzioneTMP instanceof Division)
|
||||
)
|
||||
&&
|
||||
((FunctionTwoValues) funzioneTMP).variable1 == null
|
||||
&&
|
||||
((FunctionTwoValues) funzioneTMP).variable2 == null
|
||||
)
|
||||
||
|
||||
(
|
||||
step == "NSN Functions"
|
||||
&&
|
||||
(funzioneTMP instanceof Sum) == false
|
||||
&&
|
||||
(funzioneTMP instanceof SumSubtraction) == false
|
||||
&&
|
||||
(funzioneTMP instanceof Subtraction) == false
|
||||
&&
|
||||
(funzioneTMP instanceof Multiplication) == false
|
||||
&&
|
||||
(funzioneTMP instanceof Division) == false
|
||||
&&
|
||||
(
|
||||
(
|
||||
funzioneTMP instanceof AnteriorFunction
|
||||
&&
|
||||
((AnteriorFunction) funzioneTMP).variable == null
|
||||
)
|
||||
||
|
||||
(
|
||||
funzioneTMP instanceof FunctionTwoValues
|
||||
&&
|
||||
((FunctionTwoValues) funzioneTMP).variable1 == null
|
||||
&&
|
||||
((FunctionTwoValues) funzioneTMP).variable2 == null
|
||||
)
|
||||
||
|
||||
(
|
||||
!(funzioneTMP instanceof AnteriorFunction)
|
||||
&&
|
||||
!(funzioneTMP instanceof FunctionTwoValues)
|
||||
)
|
||||
)
|
||||
)
|
||||
) {
|
||||
if ((step == "sums" && (funzioneTMP instanceof Sum || funzioneTMP instanceof SumSubtraction || funzioneTMP instanceof Subtraction) == true && ((funzioneTMP instanceof AnteriorFunction && ((AnteriorFunction) funzioneTMP).variable == null) || (funzioneTMP instanceof FunctionTwoValues && ((FunctionTwoValues) funzioneTMP).variable1 == null && ((FunctionTwoValues) funzioneTMP).variable2 == null) || (!(funzioneTMP instanceof AnteriorFunction) && !(funzioneTMP instanceof FunctionTwoValues)))) || (step.equals("multiplications") && ((funzioneTMP instanceof Multiplication) || (funzioneTMP instanceof Division)) && ((FunctionTwoValues) funzioneTMP).variable1 == null && ((FunctionTwoValues) funzioneTMP).variable2 == null) || (step == "NSN Functions" && (funzioneTMP instanceof Sum) == false && (funzioneTMP instanceof SumSubtraction) == false && (funzioneTMP instanceof Subtraction) == false && (funzioneTMP instanceof Multiplication) == false && (funzioneTMP instanceof Division) == false && ((funzioneTMP instanceof AnteriorFunction && ((AnteriorFunction) funzioneTMP).variable == null) || (funzioneTMP instanceof FunctionTwoValues && ((FunctionTwoValues) funzioneTMP).variable1 == null && ((FunctionTwoValues) funzioneTMP).variable2 == null) || (!(funzioneTMP instanceof AnteriorFunction) && !(funzioneTMP instanceof FunctionTwoValues))))) {
|
||||
change = true;
|
||||
|
||||
if (i + 1 < oldFunctionsList.size() && i - 1 >= 0) {
|
||||
@ -526,13 +474,13 @@ public class Expression extends FunctionMultipleValues {
|
||||
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getSymbol());
|
||||
try {
|
||||
Utils.debug.println(debugSpaces + " " + "var1=" + ((FunctionTwoValues) funzioneTMP).getVariable1().toString());
|
||||
} catch (NullPointerException ex2) {}
|
||||
} catch (final NullPointerException ex2) {}
|
||||
try {
|
||||
Utils.debug.println(debugSpaces + " " + "var2=" + ((FunctionTwoValues) funzioneTMP).getVariable2().toString());
|
||||
} catch (NullPointerException ex2) {}
|
||||
} catch (final NullPointerException ex2) {}
|
||||
try {
|
||||
Utils.debug.println(debugSpaces + " " + "(result)=" + ((FunctionTwoValues) funzioneTMP).toString());
|
||||
} catch (NullPointerException ex2) {}
|
||||
} catch (final NullPointerException ex2) {}
|
||||
|
||||
} else {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
@ -542,9 +490,9 @@ public class Expression extends FunctionMultipleValues {
|
||||
} else if (funzioneTMP instanceof AnteriorFunction) {
|
||||
if ((step == "SN Functions" && ((AnteriorFunction) funzioneTMP).variable == null)) {
|
||||
if (i + 1 < oldFunctionsList.size()) {
|
||||
Function nextFunc = oldFunctionsList.get(i + 1);
|
||||
if (nextFunc instanceof AnteriorFunction && ((AnteriorFunction)nextFunc).variable == null) {
|
||||
|
||||
final Function nextFunc = oldFunctionsList.get(i + 1);
|
||||
if (nextFunc instanceof AnteriorFunction && ((AnteriorFunction) nextFunc).variable == null) {
|
||||
|
||||
} else {
|
||||
change = true;
|
||||
((AnteriorFunction) funzioneTMP).setVariable(nextFunc);
|
||||
@ -556,7 +504,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
oldFunctionsList.remove(i + 1);
|
||||
|
||||
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getSymbol());
|
||||
Function var = ((AnteriorFunction) funzioneTMP).getVariable();
|
||||
final Function var = ((AnteriorFunction) funzioneTMP).getVariable();
|
||||
if (var == null) {
|
||||
Utils.debug.println(debugSpaces + " " + "var=null");
|
||||
} else {
|
||||
@ -580,8 +528,8 @@ public class Expression extends FunctionMultipleValues {
|
||||
}
|
||||
} while (((oldFunctionsList.size() != before || step != "sums") && oldFunctionsList.size() > 1));
|
||||
}
|
||||
if(oldFunctionsList.isEmpty()) {
|
||||
setVariables(new Function[]{new Number(root, 0)});
|
||||
if (oldFunctionsList.isEmpty()) {
|
||||
setVariables(new Function[] { new Number(root, 0) });
|
||||
} else {
|
||||
setVariables(oldFunctionsList);
|
||||
}
|
||||
@ -593,7 +541,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
}
|
||||
Utils.debug.println(debugSpaces + "•Finished correcting classes.");
|
||||
|
||||
String result = toString();
|
||||
final String result = toString();
|
||||
Utils.debug.println(debugSpaces + "•Result:" + result);
|
||||
}
|
||||
}
|
||||
@ -608,7 +556,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
if (functions.length > 1) {
|
||||
return true;
|
||||
} else if (functions.length == 1) {
|
||||
Function f = functions[0];
|
||||
final Function f = functions[0];
|
||||
if (f.isSolved() == false) {
|
||||
return true;
|
||||
} else {
|
||||
@ -617,31 +565,31 @@ public class Expression extends FunctionMultipleValues {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Function> solveOneStep() throws Error {
|
||||
List<Function> ret = new ArrayList<>();
|
||||
final List<Function> ret = new ArrayList<>();
|
||||
if (functions.length == 1) {
|
||||
if (functions[0].isSolved() || !parenthesisNeeded()) {
|
||||
ret.add(functions[0]);
|
||||
return ret;
|
||||
} else {
|
||||
List<Function> l = functions[0].solveOneStep();
|
||||
for (Function f : l) {
|
||||
final List<Function> l = functions[0].solveOneStep();
|
||||
for (final Function f : l) {
|
||||
if (f instanceof Number || f instanceof Variable) {
|
||||
ret.add(f);
|
||||
} else {
|
||||
ret.add(new Expression(root, new Function[]{f}));
|
||||
ret.add(new Expression(root, new Function[] { f }));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
for (Function f : functions) {
|
||||
for (final Function f : functions) {
|
||||
if (f.isSolved() == false) {
|
||||
List<Function> partial = f.solveOneStep();
|
||||
for (Function fnc : partial) {
|
||||
ret.add(new Expression(root, new Function[]{fnc}));
|
||||
final List<Function> partial = f.solveOneStep();
|
||||
for (final Function fnc : partial) {
|
||||
ret.add(new Expression(root, new Function[] { fnc }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -651,34 +599,32 @@ public class Expression extends FunctionMultipleValues {
|
||||
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
for (Function var : functions) {
|
||||
for (final Function var : functions) {
|
||||
var.setSmall(small);
|
||||
var.generateGraphics();
|
||||
}
|
||||
|
||||
|
||||
width = calcWidth();
|
||||
height = calcHeight();
|
||||
line = calcLine();
|
||||
}
|
||||
|
||||
|
||||
public boolean parenthesisNeeded() {
|
||||
boolean parenthesisneeded = true;
|
||||
if (initialParenthesis) {
|
||||
parenthesisneeded = false;
|
||||
} else {
|
||||
if (functions.length == 1) {
|
||||
Function f = functions[0];
|
||||
if (f instanceof Number || f instanceof Variable || f instanceof Expression || f instanceof Division || f instanceof Joke
|
||||
|| f instanceof Undefined || f instanceof Power || f instanceof Sine || f instanceof Cosine || f instanceof Tangent
|
||||
|| f instanceof ArcSine || f instanceof ArcCosine || f instanceof ArcTangent) {
|
||||
final Function f = functions[0];
|
||||
if (f instanceof Number || f instanceof Variable || f instanceof Expression || f instanceof Division || f instanceof Joke || f instanceof Undefined || f instanceof Power || f instanceof Sine || f instanceof Cosine || f instanceof Tangent || f instanceof ArcSine || f instanceof ArcCosine || f instanceof ArcTangent) {
|
||||
parenthesisneeded = false;
|
||||
}
|
||||
if (f instanceof Multiplication) {
|
||||
if (((Multiplication)f).getVariable1() instanceof Number) {
|
||||
parenthesisneeded = !(((Multiplication)f).getVariable2() instanceof Variable);
|
||||
} else if (((Multiplication)f).getVariable2() instanceof Number) {
|
||||
parenthesisneeded = !(((Multiplication)f).getVariable1() instanceof Variable);
|
||||
} else if (((Multiplication) f).getVariable1() instanceof Variable || ((Multiplication)f).getVariable2() instanceof Variable) {
|
||||
if (((Multiplication) f).getVariable1() instanceof Number) {
|
||||
parenthesisneeded = !(((Multiplication) f).getVariable2() instanceof Variable);
|
||||
} else if (((Multiplication) f).getVariable2() instanceof Number) {
|
||||
parenthesisneeded = !(((Multiplication) f).getVariable1() instanceof Variable);
|
||||
} else if (((Multiplication) f).getVariable1() instanceof Variable || ((Multiplication) f).getVariable2() instanceof Variable) {
|
||||
parenthesisneeded = false;
|
||||
}
|
||||
}
|
||||
@ -686,30 +632,30 @@ public class Expression extends FunctionMultipleValues {
|
||||
}
|
||||
return parenthesisneeded;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
if (parenthesisNeeded() == false) {
|
||||
this.functions[0].draw(x, y);
|
||||
functions[0].draw(x, y);
|
||||
} else {
|
||||
float miny = y;
|
||||
float maxy = y + getHeight();
|
||||
int h = getHeight();
|
||||
final float miny = y;
|
||||
final float maxy = y + getHeight();
|
||||
final int h = getHeight();
|
||||
x += 1;
|
||||
PIDisplay.renderer.glDrawLine(x, y + 2, x + 2, y);
|
||||
PIDisplay.renderer.glDrawLine(x, y + 2, x, y + h - 3);
|
||||
PIDisplay.renderer.glDrawLine(x, y + h - 3, x + 2, y + h - 1);
|
||||
DisplayManager.renderer.glDrawLine(x, y + 2, x + 2, y);
|
||||
DisplayManager.renderer.glDrawLine(x, y + 2, x, y + h - 3);
|
||||
DisplayManager.renderer.glDrawLine(x, y + h - 3, x + 2, y + h - 1);
|
||||
x += 4;
|
||||
for (Function f : functions) {
|
||||
float fheight = f.getHeight();
|
||||
float y2 = miny + ((maxy - miny) / 2 - fheight / 2);
|
||||
for (final Function f : functions) {
|
||||
final float fheight = f.getHeight();
|
||||
final float y2 = miny + ((maxy - miny) / 2 - fheight / 2);
|
||||
f.draw(x, (int) y2);
|
||||
x += f.getWidth();
|
||||
}
|
||||
x += 2;
|
||||
PIDisplay.renderer.glDrawLine(x, y, x + 2, y + 2);
|
||||
PIDisplay.renderer.glDrawLine(x + 2, y + 2, x + 2, y + h - 3);
|
||||
PIDisplay.renderer.glDrawLine(x, y + h - 1, x + 2, y + h - 3);
|
||||
DisplayManager.renderer.glDrawLine(x, y, x + 2, y + 2);
|
||||
DisplayManager.renderer.glDrawLine(x + 2, y + 2, x + 2, y + h - 3);
|
||||
DisplayManager.renderer.glDrawLine(x, y + h - 1, x + 2, y + h - 3);
|
||||
x += 4;
|
||||
}
|
||||
}
|
||||
@ -721,28 +667,28 @@ public class Expression extends FunctionMultipleValues {
|
||||
|
||||
private int calcWidth() {
|
||||
if (parenthesisNeeded() == false) {
|
||||
return this.functions[0].getWidth();
|
||||
return functions[0].getWidth();
|
||||
} else {
|
||||
int w = 0;
|
||||
for (Function f : functions) {
|
||||
for (final Function f : functions) {
|
||||
w += f.getWidth();
|
||||
}
|
||||
return 1 + 4 + w + 2 + 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
private int calcHeight() {
|
||||
if (initialParenthesis || functions.length == 1) {
|
||||
return this.functions[0].getHeight();
|
||||
return functions[0].getHeight();
|
||||
} else {
|
||||
Function tmin = null;
|
||||
Function tmax = null;
|
||||
for (Function t : functions) {
|
||||
for (final Function t : functions) {
|
||||
if (tmin == null || t.getLine() >= tmin.getLine()) {
|
||||
tmin = t;
|
||||
}
|
||||
@ -750,8 +696,9 @@ public class Expression extends FunctionMultipleValues {
|
||||
tmax = t;
|
||||
}
|
||||
}
|
||||
if (tmin == null)
|
||||
if (tmin == null) {
|
||||
return Utils.getFontHeight(small);
|
||||
}
|
||||
return tmin.getLine() + tmax.getHeight() - tmax.getLine();
|
||||
}
|
||||
}
|
||||
@ -760,23 +707,24 @@ public class Expression extends FunctionMultipleValues {
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
private int calcLine() {
|
||||
if (initialParenthesis || functions.length == 1) {
|
||||
return this.functions[0].getLine();
|
||||
return functions[0].getLine();
|
||||
} else {
|
||||
Function tl = null;
|
||||
for (Function t : functions) {
|
||||
for (final Function t : functions) {
|
||||
if (tl == null || t.getLine() >= tl.getLine()) {
|
||||
tl = t;
|
||||
}
|
||||
}
|
||||
if (tl == null)
|
||||
if (tl == null) {
|
||||
return Utils.getFontHeight(small) / 2;
|
||||
}
|
||||
return tl.getLine();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String vars = "null";
|
||||
@ -786,7 +734,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
vars = functions[0].toString();
|
||||
}
|
||||
} else {
|
||||
for (Function variable : functions) {
|
||||
for (final Function variable : functions) {
|
||||
if (variable != null) {
|
||||
vars += ", " + variable.toString();
|
||||
}
|
||||
@ -794,15 +742,15 @@ public class Expression extends FunctionMultipleValues {
|
||||
vars = vars.substring(2);
|
||||
}
|
||||
}
|
||||
return "("+vars+")";
|
||||
return "(" + vars + ")";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Expression) {
|
||||
Expression f = (Expression) o;
|
||||
Function[] exprFuncs1 = functions;
|
||||
Function[] exprFuncs2 = f.functions;
|
||||
final Expression f = (Expression) o;
|
||||
final Function[] exprFuncs1 = functions;
|
||||
final Function[] exprFuncs2 = f.functions;
|
||||
if (exprFuncs1.length == exprFuncs2.length) {
|
||||
for (int i = 0; i < exprFuncs1.length; i++) {
|
||||
if (exprFuncs1[i].equals(exprFuncs2[i]) == false) {
|
||||
@ -812,7 +760,7 @@ public class Expression extends FunctionMultipleValues {
|
||||
return true;
|
||||
}
|
||||
} else if (o != null & getVariablesLength() == 1) {
|
||||
Function f = (Function) o;
|
||||
final Function f = (Function) o;
|
||||
return (functions[0].equals(f));
|
||||
} else if (o == null & getVariablesLength() == 0) {
|
||||
return true;
|
||||
|
@ -21,14 +21,14 @@ public interface Function {
|
||||
public int getHeight();
|
||||
|
||||
public int getLine();
|
||||
|
||||
|
||||
public Calculator getRoot();
|
||||
|
||||
|
||||
public void setSmall(boolean small);
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode();
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ public abstract class FunctionMultipleValues implements Function {
|
||||
|
||||
public FunctionMultipleValues(Function[] values) {
|
||||
if (values.length > 0) {
|
||||
this.root = values[0].getRoot();
|
||||
root = values[0].getRoot();
|
||||
} else {
|
||||
throw new NullPointerException("Nessun elemento nell'array. Impossibile ricavare il nodo root");
|
||||
}
|
||||
@ -39,8 +39,8 @@ public abstract class FunctionMultipleValues implements Function {
|
||||
}
|
||||
|
||||
public void setVariables(final List<Function> value) {
|
||||
int vsize = value.size();
|
||||
Function[] tmp = new Function[vsize];
|
||||
final int vsize = value.size();
|
||||
final Function[] tmp = new Function[vsize];
|
||||
for (int i = 0; i < vsize; i++) {
|
||||
tmp[i] = value.get(i);
|
||||
}
|
||||
@ -60,7 +60,7 @@ public abstract class FunctionMultipleValues implements Function {
|
||||
}
|
||||
|
||||
public void addFunctionToEnd(Function value) {
|
||||
int index = functions.length;
|
||||
final int index = functions.length;
|
||||
setVariablesLength(index + 1);
|
||||
functions[index] = value;
|
||||
}
|
||||
@ -75,32 +75,32 @@ public abstract class FunctionMultipleValues implements Function {
|
||||
|
||||
@Override
|
||||
public abstract String getSymbol();
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSolved() {
|
||||
for (Function variable : functions) {
|
||||
for (final Function variable : functions) {
|
||||
if (!variable.isSolved()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !isSolvable();
|
||||
}
|
||||
|
||||
|
||||
protected abstract boolean isSolvable();
|
||||
|
||||
@Override
|
||||
public Calculator getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void generateGraphics();
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// try {
|
||||
// return solve().toString();
|
||||
return "TODO: fare una nuova alternativa a solve().toString()";
|
||||
return "TODO: fare una nuova alternativa a solve().toString()";
|
||||
// } catch (Error e) {
|
||||
// return e.id.toString();
|
||||
// }
|
||||
@ -108,20 +108,20 @@ public abstract class FunctionMultipleValues implements Function {
|
||||
|
||||
@Override
|
||||
public Function clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
final Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return functions.hashCode()+883*getSymbol().hashCode();
|
||||
return functions.hashCode() + 883 * getSymbol().hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return false;
|
||||
|
@ -4,7 +4,7 @@ import java.util.ArrayList;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
|
||||
@ -16,11 +16,11 @@ public abstract class FunctionTwoValues implements Function {
|
||||
variable1 = value1;
|
||||
variable2 = value2;
|
||||
}
|
||||
|
||||
|
||||
protected abstract Function NewInstance(Calculator root, Function value1, Function value2);
|
||||
|
||||
protected final Calculator root;
|
||||
|
||||
|
||||
protected Function variable1 = null;
|
||||
protected Function variable2 = null;
|
||||
protected int width;
|
||||
@ -40,7 +40,7 @@ public abstract class FunctionTwoValues implements Function {
|
||||
public Calculator getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
public Function getVariable2() {
|
||||
return variable2;
|
||||
}
|
||||
@ -51,24 +51,24 @@ public abstract class FunctionTwoValues implements Function {
|
||||
|
||||
@Override
|
||||
public abstract String getSymbol();
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSolved() {
|
||||
return (variable1.isSolved() & variable2.isSolved()) ? !isSolvable() : false;
|
||||
}
|
||||
|
||||
|
||||
protected abstract boolean isSolvable();
|
||||
|
||||
|
||||
@Override
|
||||
public final ArrayList<Function> solveOneStep() throws Error {
|
||||
final boolean solved = variable1.isSolved() & variable2.isSolved();
|
||||
ArrayList<Function> result = solved?solve():null;;
|
||||
|
||||
ArrayList<Function> result = solved ? solve() : null;;
|
||||
|
||||
if (result == null || result.isEmpty()) {
|
||||
result = new ArrayList<>();
|
||||
|
||||
ArrayList<Function> l1 = new ArrayList<>();
|
||||
ArrayList<Function> l2 = new ArrayList<>();
|
||||
|
||||
final ArrayList<Function> l1 = new ArrayList<>();
|
||||
final ArrayList<Function> l2 = new ArrayList<>();
|
||||
if (variable1.isSolved()) {
|
||||
l1.add(variable1);
|
||||
} else {
|
||||
@ -79,27 +79,27 @@ public abstract class FunctionTwoValues implements Function {
|
||||
} else {
|
||||
l2.addAll(variable2.solveOneStep());
|
||||
}
|
||||
|
||||
Function[][] results = Utils.joinFunctionsResults(l1, l2);
|
||||
|
||||
for (Function[] f : results) {
|
||||
result.add(NewInstance(this.root, f[0], f[1]));
|
||||
|
||||
final Function[][] results = Utils.joinFunctionsResults(l1, l2);
|
||||
|
||||
for (final Function[] f : results) {
|
||||
result.add(NewInstance(root, f[0], f[1]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected abstract ArrayList<Function> solve() throws Error;
|
||||
|
||||
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
variable1.setSmall(small);
|
||||
variable1.generateGraphics();
|
||||
|
||||
|
||||
variable2.setSmall(small);
|
||||
variable2.generateGraphics();
|
||||
|
||||
|
||||
width = calcWidth();
|
||||
height = calcHeight();
|
||||
line = calcLine();
|
||||
@ -107,14 +107,14 @@ public abstract class FunctionTwoValues implements Function {
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
int ln = getLine();
|
||||
final int ln = getLine();
|
||||
int dx = 0;
|
||||
variable1.draw(dx + x, ln - variable1.getLine() + y);
|
||||
dx += 1+variable1.getWidth();
|
||||
dx += 1 + variable1.getWidth();
|
||||
if (drawSignum()) {
|
||||
PIDisplay.renderer.glSetFont(Utils.getFont(small));
|
||||
PIDisplay.renderer.glDrawStringLeft(dx + x, ln - Utils.getFontHeight(small) / 2 + y, getSymbol());
|
||||
dx += PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), getSymbol());
|
||||
Utils.getFont(small).use(DisplayManager.display);
|
||||
DisplayManager.renderer.glDrawStringLeft(dx + x, ln - Utils.getFontHeight(small) / 2 + y, getSymbol());
|
||||
dx += Utils.getFont(small).getStringWidth(getSymbol());
|
||||
}
|
||||
variable2.draw(dx + x, ln - variable2.getLine() + y);
|
||||
}
|
||||
@ -144,28 +144,28 @@ public abstract class FunctionTwoValues implements Function {
|
||||
if (variable2 != null) {
|
||||
val2 = variable2.toString();
|
||||
}
|
||||
return val1+getSymbol()+val2;
|
||||
return val1 + getSymbol() + val2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionTwoValues clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
final Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
public boolean drawSignum() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
}
|
||||
|
||||
protected int calcWidth() {
|
||||
return variable1.getWidth() + 1 + (drawSignum() ? PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), getSymbol()) : 0) + variable2.getWidth();
|
||||
return variable1.getWidth() + 1 + (drawSignum() ? Utils.getFont(small).getStringWidth(getSymbol()) : 0) + variable2.getWidth();
|
||||
}
|
||||
|
||||
|
||||
protected int calcHeight() {
|
||||
|
||||
Function tmin = variable1;
|
||||
@ -178,7 +178,7 @@ public abstract class FunctionTwoValues implements Function {
|
||||
}
|
||||
return tmin.getLine() + tmax.getHeight() - tmax.getLine();
|
||||
}
|
||||
|
||||
|
||||
protected int calcLine() {
|
||||
Function tl = variable1;
|
||||
if (tl == null || variable2.getLine() >= tl.getLine()) {
|
||||
@ -186,12 +186,12 @@ public abstract class FunctionTwoValues implements Function {
|
||||
}
|
||||
return tl.getLine();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return variable1.hashCode()+7*variable2.hashCode()+883*getSymbol().hashCode();
|
||||
return variable1.hashCode() + 7 * variable2.hashCode() + 883 * getSymbol().hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract boolean equals(Object o);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import java.util.List;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
@ -14,16 +14,16 @@ public class Joke implements Function {
|
||||
public static final byte FISH = 0;
|
||||
public static final byte TORNADO = 1;
|
||||
public static final byte SHARKNADO = 2;
|
||||
private static final String[] jokes = new String[]{"♓", "TORNADO", "SHARKNADO"};
|
||||
private static final int[] jokesFont = new int[]{4, -1, -1};
|
||||
private static final String[] jokes = new String[] { "♓", "TORNADO", "SHARKNADO" };
|
||||
private static final int[] jokesFont = new int[] { 4, -1, -1 };
|
||||
private final byte joke;
|
||||
private final Calculator root;
|
||||
|
||||
|
||||
public Joke(Calculator root, byte joke) {
|
||||
this.root = root;
|
||||
this.joke = joke;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return "joke";
|
||||
@ -41,34 +41,34 @@ public class Joke implements Function {
|
||||
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
RAWFont rf = PIDisplay.renderer.getCurrentFont();
|
||||
final RAWFont rf = DisplayManager.renderer.getCurrentFont();
|
||||
if (jokesFont[joke] >= 0) {
|
||||
PIDisplay.renderer.glSetFont(PIDisplay.fonts[jokesFont[joke]]);
|
||||
DisplayManager.renderer.glSetFont(DisplayManager.fonts[jokesFont[joke]]);
|
||||
}
|
||||
PIDisplay.renderer.glDrawStringLeft(x, y, jokes[joke]);
|
||||
DisplayManager.renderer.glDrawStringLeft(x, y, jokes[joke]);
|
||||
if (jokesFont[joke] >= 0) {
|
||||
PIDisplay.renderer.glSetFont(rf);
|
||||
DisplayManager.renderer.glSetFont(rf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
if (jokesFont[joke] >= 0) {
|
||||
return PIDisplay.renderer.glGetStringWidth(PIDisplay.fonts[jokesFont[joke]], jokes[joke]);
|
||||
return DisplayManager.renderer.glGetStringWidth(DisplayManager.fonts[jokesFont[joke]], jokes[joke]);
|
||||
} else {
|
||||
return PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), jokes[joke]);
|
||||
return DisplayManager.renderer.glGetStringWidth(Utils.getFont(small), jokes[joke]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
if (jokesFont[joke] >= 0) {
|
||||
return PIDisplay.fonts[jokesFont[joke]].charH;
|
||||
return DisplayManager.fonts[jokesFont[joke]].charH;
|
||||
} else {
|
||||
return Utils.getFont(small).charH;
|
||||
}
|
||||
@ -76,7 +76,7 @@ public class Joke implements Function {
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
return getHeight()/2;
|
||||
return getHeight() / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,7 +85,7 @@ public class Joke implements Function {
|
||||
}
|
||||
|
||||
private boolean small = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
|
@ -21,7 +21,7 @@ public class Multiplication extends FunctionTwoValues {
|
||||
variable2 = value1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Function NewInstance(Calculator root, Function value1, Function value2) {
|
||||
return new Multiplication(root, value1, value2);
|
||||
@ -37,12 +37,24 @@ public class Multiplication extends FunctionTwoValues {
|
||||
if (variable1 instanceof Number & variable2 instanceof Number) {
|
||||
return true;
|
||||
}
|
||||
if (SyntaxRule1.compare(this)) return true;
|
||||
if (NumberRule1.compare(this)) return true;
|
||||
if (NumberRule2.compare(this)) return true;
|
||||
if (NumberRule6.compare(this)) return true;
|
||||
if (ExponentRule15.compare(this)) return true;
|
||||
if (MultiplicationMethod1.compare(this)) return true;
|
||||
if (SyntaxRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule2.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule6.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (ExponentRule15.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (MultiplicationMethod1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -62,15 +74,15 @@ public class Multiplication extends FunctionTwoValues {
|
||||
} else if (MultiplicationMethod1.compare(this)) {
|
||||
result = MultiplicationMethod1.execute(this);
|
||||
} else if (variable1.isSolved() & variable2.isSolved()) {
|
||||
result.add(((Number)variable1).multiply((Number)variable2));
|
||||
result.add(((Number) variable1).multiply((Number) variable2));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawSignum() {
|
||||
Function[] tmpVar = new Function[] { variable1, variable2 };
|
||||
boolean[] ok = new boolean[] { false, false };
|
||||
final Function[] tmpVar = new Function[] { variable1, variable2 };
|
||||
final boolean[] ok = new boolean[] { false, false };
|
||||
for (int val = 0; val < 2; val++) {
|
||||
while (!ok[val]) {
|
||||
if (tmpVar[val] instanceof Division) {
|
||||
@ -132,11 +144,11 @@ public class Multiplication extends FunctionTwoValues {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Multiplication) {
|
||||
FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
final FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
if (variable1.equals(f.variable1) && variable2.equals(f.variable2)) {
|
||||
return true;
|
||||
} else if (variable1.equals(f.variable2) && variable2.equals(f.variable1)) {
|
||||
|
@ -5,7 +5,7 @@ import java.util.ArrayList;
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Errors;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
import org.warp.picalculator.math.MathematicalSymbols;
|
||||
@ -27,25 +27,31 @@ public class Negative extends AnteriorFunction {
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.MINUS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
variable.setSmall(small);
|
||||
variable.generateGraphics();
|
||||
|
||||
|
||||
height = getVariable().getHeight();
|
||||
width = PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), "-") + getVariable().getWidth();
|
||||
width = DisplayManager.renderer.glGetStringWidth(Utils.getFont(small), "-") + getVariable().getWidth();
|
||||
line = getVariable().getLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSolvable() {
|
||||
if (variable instanceof Number) return true;
|
||||
if (ExpandRule1.compare(this)) return true;
|
||||
if (ExpandRule5.compare(this)) return true;
|
||||
if (variable instanceof Number) {
|
||||
return true;
|
||||
}
|
||||
if (ExpandRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (ExpandRule5.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ArrayList<Function> solve() throws Error {
|
||||
if (variable == null) {
|
||||
@ -58,24 +64,24 @@ public class Negative extends AnteriorFunction {
|
||||
result = ExpandRule5.execute(this);
|
||||
} else if (variable.isSolved()) {
|
||||
try {
|
||||
Number var = (Number) getVariable();
|
||||
final Number var = (Number) getVariable();
|
||||
result.add(var.multiply(new Number(root, "-1")));
|
||||
} catch(NullPointerException ex) {
|
||||
} catch (final NullPointerException ex) {
|
||||
throw new Error(Errors.ERROR);
|
||||
} catch(NumberFormatException ex) {
|
||||
} catch (final NumberFormatException ex) {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
} catch(ArithmeticException ex) {
|
||||
} catch (final ArithmeticException ex) {
|
||||
throw new Error(Errors.NUMBER_TOO_SMALL);
|
||||
}
|
||||
} else {
|
||||
ArrayList<Function> l1 = new ArrayList<>();
|
||||
final ArrayList<Function> l1 = new ArrayList<>();
|
||||
if (variable.isSolved()) {
|
||||
l1.add(variable);
|
||||
} else {
|
||||
l1.addAll(variable.solveOneStep());
|
||||
}
|
||||
|
||||
for (Function f : l1) {
|
||||
|
||||
for (final Function f : l1) {
|
||||
result.add(new Negative(root, f));
|
||||
}
|
||||
}
|
||||
@ -96,11 +102,11 @@ public class Negative extends AnteriorFunction {
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Negative) {
|
||||
return ((Negative)o).variable.equals(variable);
|
||||
return ((Negative) o).variable.equals(variable);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -9,9 +9,8 @@ import java.util.List;
|
||||
import org.nevec.rjm.BigDecimalMath;
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.RAWFont;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
@ -29,7 +28,7 @@ public class Number implements Function {
|
||||
this.root = root;
|
||||
term = new BigDecimal(val).setScale(Utils.scale, Utils.scaleMode2);
|
||||
}
|
||||
|
||||
|
||||
public Number(Calculator root, BigDecimal val) {
|
||||
this.root = root;
|
||||
term = val.setScale(Utils.scale, Utils.scaleMode2);
|
||||
@ -72,26 +71,26 @@ public class Number implements Function {
|
||||
}
|
||||
|
||||
public Number add(Number f) {
|
||||
Number ret = new Number(this.root, getTerm().add(f.getTerm()));
|
||||
final Number ret = new Number(root, getTerm().add(f.getTerm()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Number multiply(Number f) {
|
||||
Number ret = new Number(this.root, getTerm().multiply(f.getTerm()));
|
||||
final Number ret = new Number(root, getTerm().multiply(f.getTerm()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Number divide(Number f) throws Error {
|
||||
Number ret = new Number(this.root, BigDecimalMath.divideRound(getTerm(), f.getTerm()));
|
||||
final Number ret = new Number(root, BigDecimalMath.divideRound(getTerm(), f.getTerm()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public Number pow(Number f) throws Error {
|
||||
Number ret = new Number(this.root, BigDecimal.ONE);
|
||||
Number ret = new Number(root, BigDecimal.ONE);
|
||||
if (Utils.isIntegerValue(f.term)) {
|
||||
final BigInteger bi = f.term.toBigInteger();
|
||||
for (BigInteger i = BigInteger.ZERO; i.compareTo(bi) < 0; i = i.add(BigInteger.ONE)) {
|
||||
ret = ret.multiply(new Number(this.root, getTerm()));
|
||||
ret = ret.multiply(new Number(root, getTerm()));
|
||||
}
|
||||
} else {
|
||||
ret.term = BigDecimalMath.pow(term, f.term);
|
||||
@ -101,20 +100,20 @@ public class Number implements Function {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String sWith0 = getTerm().setScale(Utils.displayScale, Utils.scaleMode2).toPlainString();
|
||||
String sExtendedWith0 = getTerm().toPlainString();
|
||||
final String sWith0 = getTerm().setScale(Utils.displayScale, Utils.scaleMode2).toPlainString();
|
||||
final String sExtendedWith0 = getTerm().toPlainString();
|
||||
//Remove trailing zeroes. Thanks to Kent, http://stackoverflow.com/questions/14984664/remove-trailing-zero-in-java
|
||||
String s = sWith0.indexOf(".") < 0 ? sWith0 : sWith0.replaceAll("0*$", "").replaceAll("\\.$", "");
|
||||
String sExtended = sExtendedWith0.indexOf(".") < 0 ? sExtendedWith0 : sExtendedWith0.replaceAll("0*$", "").replaceAll("\\.$", "");
|
||||
|
||||
final String sExtended = sExtendedWith0.indexOf(".") < 0 ? sExtendedWith0 : sExtendedWith0.replaceAll("0*$", "").replaceAll("\\.$", "");
|
||||
|
||||
if (sExtended.length() > s.length()) {
|
||||
s = s+"…";
|
||||
s = s + "…";
|
||||
}
|
||||
|
||||
|
||||
if (root.exactMode == false) {
|
||||
String cuttedNumber = s.split("\\.")[0];
|
||||
final String cuttedNumber = s.split("\\.")[0];
|
||||
if (cuttedNumber.length() > 8) {
|
||||
return cuttedNumber.substring(0, 1)+","+cuttedNumber.substring(1, 8)+"ℯ℮"+(cuttedNumber.length()-1);
|
||||
return cuttedNumber.substring(0, 1) + "," + cuttedNumber.substring(1, 8) + "ℯ℮" + (cuttedNumber.length() - 1);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
@ -131,7 +130,7 @@ public class Number implements Function {
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
PIDisplay.renderer.glSetFont(Utils.getFont(small));
|
||||
Utils.getFont(small).use(DisplayManager.display);
|
||||
String t = toString();
|
||||
|
||||
if (t.startsWith("-")) {
|
||||
@ -144,20 +143,20 @@ public class Number implements Function {
|
||||
if (t.contains("ℯ℮")) {
|
||||
final RAWFont defaultf = Utils.getFont(small);
|
||||
final RAWFont smallf = Utils.getFont(true);
|
||||
String s = t.substring(0, t.indexOf("ℯ℮")+2);
|
||||
int sw = PIDisplay.renderer.glGetStringWidth(defaultf, s);
|
||||
PIDisplay.renderer.glDrawStringLeft(x+1, y+smallf.charH-2, s);
|
||||
PIDisplay.renderer.glSetFont(smallf);
|
||||
PIDisplay.renderer.glDrawStringLeft(x+1+sw-3, y, t.substring(t.indexOf("ℯ℮")+2));
|
||||
final String s = t.substring(0, t.indexOf("ℯ℮") + 2);
|
||||
final int sw = defaultf.getStringWidth(s);
|
||||
DisplayManager.renderer.glDrawStringLeft(x + 1, y + smallf.getCharacterHeight() - 2, s);
|
||||
smallf.use(DisplayManager.display);
|
||||
DisplayManager.renderer.glDrawStringLeft(x + 1 + sw - 3, y, t.substring(t.indexOf("ℯ℮") + 2));
|
||||
} else {
|
||||
PIDisplay.renderer.glDrawStringLeft(x+1, y, t);
|
||||
DisplayManager.renderer.glDrawStringLeft(x + 1, y, t);
|
||||
}
|
||||
}
|
||||
|
||||
public int getHeight(boolean drawMinus) {
|
||||
boolean beforedrawminus = this.drawMinus;
|
||||
final boolean beforedrawminus = this.drawMinus;
|
||||
this.drawMinus = drawMinus;
|
||||
int h = getHeight();
|
||||
final int h = getHeight();
|
||||
this.drawMinus = beforedrawminus;
|
||||
return h;
|
||||
}
|
||||
@ -166,21 +165,22 @@ public class Number implements Function {
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
private int calcHeight() {
|
||||
String t = toString();
|
||||
final String t = toString();
|
||||
if (t.contains("ℯ℮")) {
|
||||
return Utils.getFontHeight(small)-2+Utils.getFontHeight(true);
|
||||
return Utils.getFontHeight(small) - 2 + Utils.getFontHeight(true);
|
||||
} else {
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
final int h1 = Utils.getFontHeight(small);
|
||||
return h1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
public int calcWidth() {
|
||||
String t = toString();
|
||||
if (t.startsWith("-")) {
|
||||
@ -193,23 +193,23 @@ public class Number implements Function {
|
||||
if (t.contains("ℯ℮")) {
|
||||
final RAWFont defaultf = Utils.getFont(small);
|
||||
final RAWFont smallf = Utils.getFont(true);
|
||||
String s = t.substring(0, t.indexOf("ℯ℮")+2);
|
||||
int sw = PIDisplay.renderer.glGetStringWidth(defaultf, s);
|
||||
return 1+sw-3+PIDisplay.renderer.glGetStringWidth(smallf, t.substring(t.indexOf("ℯ℮")+2));
|
||||
final String s = t.substring(0, t.indexOf("ℯ℮") + 2);
|
||||
final int sw = defaultf.getStringWidth(s);
|
||||
return 1 + sw - 3 + smallf.getStringWidth(t.substring(t.indexOf("ℯ℮") + 2));
|
||||
} else {
|
||||
return PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), t)+1;
|
||||
return Utils.getFont(small).getStringWidth(t) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
private int calcLine() {
|
||||
String t = toString();
|
||||
final String t = toString();
|
||||
if (t.contains("ℯ℮")) {
|
||||
return (Utils.getFontHeight(small) / 2)-2+Utils.getFontHeight(true);
|
||||
return (Utils.getFontHeight(small) / 2) - 2 + Utils.getFontHeight(true);
|
||||
} else {
|
||||
return Utils.getFontHeight(small) / 2;
|
||||
}
|
||||
@ -217,10 +217,10 @@ public class Number implements Function {
|
||||
|
||||
@Override
|
||||
public Number clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
final Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
@ -233,23 +233,23 @@ public class Number implements Function {
|
||||
|
||||
@Override
|
||||
public List<Function> solveOneStep() throws Error {
|
||||
List<Function> result = new ArrayList<>();
|
||||
final List<Function> result = new ArrayList<>();
|
||||
result.add(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o != null & term != null) {
|
||||
if (o instanceof Number) {
|
||||
BigDecimal nav = ((Number) o).getTerm();
|
||||
boolean na1 = term.compareTo(BigDecimal.ZERO) == 0;
|
||||
boolean na2 = nav.compareTo(BigDecimal.ZERO) == 0;
|
||||
final BigDecimal nav = ((Number) o).getTerm();
|
||||
final boolean na1 = term.compareTo(BigDecimal.ZERO) == 0;
|
||||
final boolean na2 = nav.compareTo(BigDecimal.ZERO) == 0;
|
||||
if (na1 == na2) {
|
||||
if (na1 == true) {
|
||||
return true;
|
||||
@ -283,49 +283,41 @@ public class Number implements Function {
|
||||
* return 6*toString().length()-1;
|
||||
* }
|
||||
*/
|
||||
|
||||
|
||||
public boolean canBeFactorized() {
|
||||
if (Utils.isIntegerValue(getTerm())) {
|
||||
return getTerm().toBigIntegerExact().compareTo(BigInteger.valueOf(1)) > 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public LinkedList<BigInteger> getFactors()
|
||||
{
|
||||
|
||||
public LinkedList<BigInteger> getFactors() {
|
||||
BigInteger n = getTerm().toBigIntegerExact();
|
||||
BigInteger two = BigInteger.valueOf(2);
|
||||
LinkedList<BigInteger> fs = new LinkedList<>();
|
||||
final BigInteger two = BigInteger.valueOf(2);
|
||||
final LinkedList<BigInteger> fs = new LinkedList<>();
|
||||
|
||||
if (n.compareTo(two) < 0)
|
||||
{
|
||||
throw new IllegalArgumentException("must be greater than one");
|
||||
}
|
||||
if (n.compareTo(two) < 0) {
|
||||
throw new IllegalArgumentException("must be greater than one");
|
||||
}
|
||||
|
||||
while (n.mod(two).equals(BigInteger.ZERO))
|
||||
{
|
||||
fs.add(two);
|
||||
n = n.divide(two);
|
||||
}
|
||||
while (n.mod(two).equals(BigInteger.ZERO)) {
|
||||
fs.add(two);
|
||||
n = n.divide(two);
|
||||
}
|
||||
|
||||
if (n.compareTo(BigInteger.ONE) > 0)
|
||||
{
|
||||
BigInteger f = BigInteger.valueOf(3);
|
||||
while (f.multiply(f).compareTo(n) <= 0)
|
||||
{
|
||||
if (n.mod(f).equals(BigInteger.ZERO))
|
||||
{
|
||||
fs.add(f);
|
||||
n = n.divide(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
f = f.add(two);
|
||||
}
|
||||
}
|
||||
fs.add(n);
|
||||
}
|
||||
if (n.compareTo(BigInteger.ONE) > 0) {
|
||||
BigInteger f = BigInteger.valueOf(3);
|
||||
while (f.multiply(f).compareTo(n) <= 0) {
|
||||
if (n.mod(f).equals(BigInteger.ZERO)) {
|
||||
fs.add(f);
|
||||
n = n.divide(f);
|
||||
} else {
|
||||
f = f.add(two);
|
||||
}
|
||||
}
|
||||
fs.add(n);
|
||||
}
|
||||
|
||||
return fs;
|
||||
return fs;
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,11 @@ import org.warp.picalculator.math.rules.FractionsRule5;
|
||||
import org.warp.picalculator.math.rules.UndefinedRule1;
|
||||
|
||||
public class Power extends FunctionTwoValues {
|
||||
|
||||
|
||||
public Power(Calculator root, Function value1, Function value2) {
|
||||
super(root, value1, value2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Function NewInstance(Calculator root, Function value1, Function value2) {
|
||||
return new Power(root, value1, value2);
|
||||
@ -34,32 +34,46 @@ public class Power extends FunctionTwoValues {
|
||||
if (variable1 instanceof Number & variable2 instanceof Number) {
|
||||
return true;
|
||||
}
|
||||
if (UndefinedRule1.compare(this)) return true;
|
||||
if (ExponentRule1.compare(this)) return true;
|
||||
if (ExponentRule2.compare(this)) return true;
|
||||
if (ExponentRule3.compare(this)) return true;
|
||||
if (ExponentRule4.compare(this)) return true;
|
||||
if (FractionsRule4.compare(this)) return true;
|
||||
if (FractionsRule5.compare(this)) return true;
|
||||
if (UndefinedRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (ExponentRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (ExponentRule2.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (ExponentRule3.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (ExponentRule4.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (FractionsRule4.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (FractionsRule5.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
variable1.setSmall(small);
|
||||
variable1.generateGraphics();
|
||||
|
||||
|
||||
variable2.setSmall(true);
|
||||
variable2.generateGraphics();
|
||||
|
||||
|
||||
height = variable1.getHeight() + variable2.getHeight() - 4;
|
||||
line = variable2.getHeight() - 4 + variable1.getLine();
|
||||
width = getVariable1().getWidth() + getVariable2().getWidth()+1;
|
||||
width = getVariable1().getWidth() + getVariable2().getWidth() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<Function> solve() throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
if (UndefinedRule1.compare(this)) {
|
||||
result.addAll(UndefinedRule1.execute(this));
|
||||
} else if (ExponentRule1.compare(this)) {
|
||||
@ -75,17 +89,17 @@ public class Power extends FunctionTwoValues {
|
||||
} else if (FractionsRule5.compare(this)) {
|
||||
result.addAll(FractionsRule5.execute(this));
|
||||
} else if (variable1 instanceof Number & variable2 instanceof Number) {
|
||||
result.add(((Number)variable1).pow((Number)variable2));
|
||||
result.add(((Number) variable1).pow((Number) variable2));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
// glColor3f(0, 127-50+new Random().nextInt(50), 0);
|
||||
// glFillRect(x,y,width,height);
|
||||
// glColor3f(0, 0, 0);
|
||||
|
||||
|
||||
int dx = 0;
|
||||
variable1.draw(dx + x, getHeight() - variable1.getHeight() + y);
|
||||
dx += variable1.getWidth();
|
||||
@ -106,11 +120,11 @@ public class Power extends FunctionTwoValues {
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Power) {
|
||||
FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
final FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
|
||||
}
|
||||
return false;
|
||||
|
@ -5,7 +5,7 @@ import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
import org.warp.picalculator.math.MathematicalSymbols;
|
||||
|
||||
@ -14,12 +14,12 @@ public class Root extends FunctionTwoValues {
|
||||
public Root(Calculator root, Function value1, Function value2) {
|
||||
super(root, value1, value2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Function NewInstance(Calculator root, Function value1, Function value2) {
|
||||
return new Root(root, value1, value2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.NTH_ROOT;
|
||||
@ -29,10 +29,10 @@ public class Root extends FunctionTwoValues {
|
||||
public void generateGraphics() {
|
||||
variable1.setSmall(true);
|
||||
variable1.generateGraphics();
|
||||
|
||||
|
||||
variable2.setSmall(small);
|
||||
variable2.generateGraphics();
|
||||
|
||||
|
||||
width = 1 + variable1.getWidth() + 2 + variable2.getWidth() + 2;
|
||||
height = variable1.getHeight() + variable2.getHeight() - 2;
|
||||
line = variable1.getHeight() + variable2.getLine() - 2;
|
||||
@ -47,36 +47,36 @@ public class Root extends FunctionTwoValues {
|
||||
try {
|
||||
Number exponent = new Number(root, BigDecimal.ONE);
|
||||
exponent = exponent.divide((Number) variable1);
|
||||
Number resultVal = ((Number)variable2).pow(exponent);
|
||||
Number originalVariable = resultVal.pow(new Number(root, 2));
|
||||
final Number resultVal = ((Number) variable2).pow(exponent);
|
||||
final Number originalVariable = resultVal.pow(new Number(root, 2));
|
||||
if (originalVariable.equals(variable2)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception | Error ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (variable1 instanceof Number && ((Number)variable1).equals(new Number(root, 2))) {
|
||||
if (variable1 instanceof Number && ((Number) variable1).equals(new Number(root, 2))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ArrayList<Function> solve() throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
if (root.exactMode) {
|
||||
if (variable1 instanceof Number && ((Number)variable1).equals(new Number(root, 2))) {
|
||||
if (variable1 instanceof Number && ((Number) variable1).equals(new Number(root, 2))) {
|
||||
result.add(new RootSquare(root, variable2));
|
||||
} else {
|
||||
Number exponent = new Number(root, BigInteger.ONE);
|
||||
exponent = exponent.divide((Number) variable1);
|
||||
result.add(((Number)variable2).pow(exponent));
|
||||
result.add(((Number) variable2).pow(exponent));
|
||||
}
|
||||
} else {
|
||||
Number exp = (Number) variable1;
|
||||
Number numb = (Number) variable2;
|
||||
|
||||
final Number exp = (Number) variable1;
|
||||
final Number numb = (Number) variable2;
|
||||
|
||||
result.add(numb.pow(new Number(root, 1).divide(exp)));
|
||||
}
|
||||
return result;
|
||||
@ -87,21 +87,21 @@ public class Root extends FunctionTwoValues {
|
||||
// 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);
|
||||
|
||||
final int w1 = getVariable2().getWidth();
|
||||
final int h1 = getVariable2().getHeight();
|
||||
final int w2 = getVariable1().getWidth();
|
||||
final int h2 = getVariable1().getHeight();
|
||||
final int height = getHeight();
|
||||
final int hh = (int) Math.ceil((double) h1 / 2);
|
||||
|
||||
getVariable1().draw(x + 1, y);
|
||||
getVariable2().draw(x + 1 + w2 + 2, y + h2 - 2);
|
||||
|
||||
PIDisplay.renderer.glDrawLine(x + 1 + w2 - 2, y + height - 3, x + 1 + w2, y + height);
|
||||
PIDisplay.renderer.glDrawLine(x + 1 + w2, y + height - 1 - hh, x + 1 + w2, y + height - 1);
|
||||
PIDisplay.renderer.glDrawLine(x + 1 + w2 + 1, y + height - 2 - h1, x + 1 + w2 + 1, y + height - 1 - hh - 1);
|
||||
PIDisplay.renderer.glDrawLine(x + 1 + w2 + 1, y + height - h1 - 2, x + 1 + w2 + 2 + w1 + 1, y + height - h1 - 2);
|
||||
DisplayManager.renderer.glDrawLine(x + 1 + w2 - 2, y + height - 3, x + 1 + w2, y + height);
|
||||
DisplayManager.renderer.glDrawLine(x + 1 + w2, y + height - 1 - hh, x + 1 + w2, y + height - 1);
|
||||
DisplayManager.renderer.glDrawLine(x + 1 + w2 + 1, y + height - 2 - h1, x + 1 + w2 + 1, y + height - 1 - hh - 1);
|
||||
DisplayManager.renderer.glDrawLine(x + 1 + w2 + 1, y + height - h1 - 2, x + 1 + w2 + 2 + w1 + 1, y + height - h1 - 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -118,11 +118,11 @@ public class Root extends FunctionTwoValues {
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Root) {
|
||||
FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
final FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
|
||||
}
|
||||
return false;
|
||||
|
@ -18,17 +18,17 @@ public class RootSquare extends AnteriorFunction {
|
||||
public Function NewInstance(Calculator root, Function value) {
|
||||
return new RootSquare(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.SQUARE_ROOT;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
variable.setSmall(small);
|
||||
variable.generateGraphics();
|
||||
|
||||
|
||||
height = getVariable().getHeight() + 2;
|
||||
width = 1 + 4 + getVariable().getWidth() + 1;
|
||||
line = getVariable().getLine() + 2;
|
||||
@ -43,29 +43,29 @@ public class RootSquare extends AnteriorFunction {
|
||||
try {
|
||||
Number exponent = new Number(root, BigInteger.ONE);
|
||||
exponent = exponent.divide(new Number(root, 2));
|
||||
Number resultVal = ((Number)variable).pow(exponent);
|
||||
Number originalVariable = resultVal.pow(new Number(root, 2));
|
||||
final Number resultVal = ((Number) variable).pow(exponent);
|
||||
final Number originalVariable = resultVal.pow(new Number(root, 2));
|
||||
if (originalVariable.equals(variable)) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception | Error ex) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ArrayList<Function> solve() throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
if (root.exactMode) {
|
||||
Number exponent = new Number(root, BigInteger.ONE);
|
||||
exponent = exponent.divide(new Number(root, 2));
|
||||
result.add(((Number)variable).pow(exponent));
|
||||
result.add(((Number) variable).pow(exponent));
|
||||
} else {
|
||||
Number exp = new Number(root, 2);
|
||||
Number numb = (Number) variable;
|
||||
|
||||
final Number exp = new Number(root, 2);
|
||||
final Number numb = (Number) variable;
|
||||
|
||||
result.add(numb.pow(new Number(root, 1).divide(exp)));
|
||||
}
|
||||
return result;
|
||||
@ -76,7 +76,7 @@ public class RootSquare extends AnteriorFunction {
|
||||
// glColor3f(0, 255, 0);
|
||||
// glFillRect(x,y,width,height);
|
||||
// glColor3f(0, 0, 0);
|
||||
|
||||
|
||||
Utils.writeSquareRoot(getVariable(), x, y, small);
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ public class RootSquare extends AnteriorFunction {
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof RootSquare) {
|
||||
|
@ -19,12 +19,12 @@ public class Subtraction extends FunctionTwoValues {
|
||||
public Subtraction(Calculator root, Function value1, Function value2) {
|
||||
super(root, value1, value2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Function NewInstance(Calculator root, Function value1, Function value2) {
|
||||
return new Subtraction(root, value1, value2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.SUBTRACTION;
|
||||
@ -35,17 +35,33 @@ public class Subtraction extends FunctionTwoValues {
|
||||
if (variable1 instanceof Number & variable2 instanceof Number) {
|
||||
return true;
|
||||
}
|
||||
if (VariableRule1.compare(this)) return true;
|
||||
if (VariableRule2.compare(this)) return true;
|
||||
if (VariableRule3.compare(this)) return true;
|
||||
if (NumberRule3.compare(this)) return true;
|
||||
if (ExpandRule1.compare(this)) return true;
|
||||
if (ExpandRule5.compare(this)) return true;
|
||||
if (NumberRule5.compare(this)) return true;
|
||||
if (SumMethod1.compare(this)) return true;
|
||||
if (VariableRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (VariableRule2.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (VariableRule3.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule3.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (ExpandRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (ExpandRule5.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule5.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (SumMethod1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ArrayList<Function> solve() throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
@ -66,15 +82,15 @@ public class Subtraction extends FunctionTwoValues {
|
||||
} else if (SumMethod1.compare(this)) {
|
||||
result = SumMethod1.execute(this);
|
||||
} else if (variable1.isSolved() & variable2.isSolved()) {
|
||||
result.add(((Number)variable1).add(((Number)variable2).multiply(new Number(root, "-1"))));
|
||||
result.add(((Number) variable1).add(((Number) variable2).multiply(new Number(root, "-1"))));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Subtraction) {
|
||||
FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
final FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
|
||||
}
|
||||
return false;
|
||||
|
@ -6,7 +6,7 @@ import java.util.ArrayList;
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Errors;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
import org.warp.picalculator.math.MathematicalSymbols;
|
||||
import org.warp.picalculator.math.rules.NumberRule3;
|
||||
@ -28,25 +28,41 @@ public class Sum extends FunctionTwoValues {
|
||||
protected Function NewInstance(Calculator root, Function value1, Function value2) {
|
||||
return new Sum(root, value1, value2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.SUM;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isSolvable() {
|
||||
if (variable1 instanceof Number & variable2 instanceof Number) {
|
||||
return true;
|
||||
}
|
||||
if (SyntaxRule2.compare(this)) return true;
|
||||
if (VariableRule1.compare(this)) return true;
|
||||
if (VariableRule2.compare(this)) return true;
|
||||
if (VariableRule3.compare(this)) return true;
|
||||
if (NumberRule3.compare(this)) return true;
|
||||
if (NumberRule5.compare(this)) return true;
|
||||
if (NumberRule7.compare(this)) return true;
|
||||
if (SumMethod1.compare(this)) return true;
|
||||
if (SyntaxRule2.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (VariableRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (VariableRule2.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (VariableRule3.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule3.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule5.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule7.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (SumMethod1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -74,18 +90,18 @@ public class Sum extends FunctionTwoValues {
|
||||
result = SumMethod1.execute(this);
|
||||
} else if (variable1.isSolved() & variable2.isSolved()) {
|
||||
if ((root.getChild().equals(this))) {
|
||||
if (((Number)variable1).term.compareTo(new BigDecimal(2)) == 0 && ((Number)variable2).term.compareTo(new BigDecimal(2)) == 0) {
|
||||
if (((Number) variable1).term.compareTo(new BigDecimal(2)) == 0 && ((Number) variable2).term.compareTo(new BigDecimal(2)) == 0) {
|
||||
result.add(new Joke(root, Joke.FISH));
|
||||
return result;
|
||||
} else if (((Number)variable1).term.compareTo(new BigDecimal(20)) == 0 && ((Number)variable2).term.compareTo(new BigDecimal(20)) == 0) {
|
||||
} else if (((Number) variable1).term.compareTo(new BigDecimal(20)) == 0 && ((Number) variable2).term.compareTo(new BigDecimal(20)) == 0) {
|
||||
result.add(new Joke(root, Joke.TORNADO));
|
||||
return result;
|
||||
} else if (((Number)variable1).term.compareTo(new BigDecimal(29)) == 0 && ((Number)variable2).term.compareTo(new BigDecimal(29)) == 0) {
|
||||
} else if (((Number) variable1).term.compareTo(new BigDecimal(29)) == 0 && ((Number) variable2).term.compareTo(new BigDecimal(29)) == 0) {
|
||||
result.add(new Joke(root, Joke.SHARKNADO));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result.add(((Number)variable1).add((Number)variable2));
|
||||
result.add(((Number) variable1).add((Number) variable2));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -94,10 +110,10 @@ public class Sum extends FunctionTwoValues {
|
||||
public void generateGraphics() {
|
||||
variable1.setSmall(small);
|
||||
variable1.generateGraphics();
|
||||
|
||||
|
||||
variable2.setSmall(small);
|
||||
variable2.generateGraphics();
|
||||
|
||||
|
||||
width = calcWidth();
|
||||
height = calcHeight();
|
||||
line = calcLine();
|
||||
@ -107,20 +123,20 @@ public class Sum extends FunctionTwoValues {
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int calcWidth() {
|
||||
int dx = 0;
|
||||
dx += variable1.getWidth();
|
||||
dx += 1;
|
||||
dx += PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), getSymbol());
|
||||
dx += DisplayManager.renderer.glGetStringWidth(Utils.getFont(small), getSymbol());
|
||||
return dx += variable2.getWidth();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Sum) {
|
||||
FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
final FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
if (variable1.equals(f.variable1) && variable2.equals(f.variable2)) {
|
||||
return true;
|
||||
} else if (variable1.equals(f.variable2) && variable2.equals(f.variable1)) {
|
||||
|
@ -5,7 +5,7 @@ import java.util.ArrayList;
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Errors;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
import org.warp.picalculator.math.MathematicalSymbols;
|
||||
@ -19,7 +19,7 @@ public class SumSubtraction extends FunctionTwoValues {
|
||||
public SumSubtraction(Calculator root, Function value1, Function value2) {
|
||||
super(root, value1, value2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Function NewInstance(Calculator root, Function value1, Function value2) {
|
||||
return new SumSubtraction(root, value1, value2);
|
||||
@ -35,13 +35,21 @@ public class SumSubtraction extends FunctionTwoValues {
|
||||
if (variable1 instanceof Number & variable2 instanceof Number) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule3.compare(this)) return true;
|
||||
if (ExpandRule1.compare(this)) return true;
|
||||
if (NumberRule4.compare(this)) return true;
|
||||
if (NumberRule5.compare(this)) return true;
|
||||
if (NumberRule3.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (ExpandRule1.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule4.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
if (NumberRule5.compare(this)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ArrayList<Function> solve() throws Error {
|
||||
if (variable1 == null || variable2 == null) {
|
||||
@ -57,8 +65,8 @@ public class SumSubtraction extends FunctionTwoValues {
|
||||
} else if (NumberRule5.compare(this)) {
|
||||
result = NumberRule5.execute(this);
|
||||
} else if (variable1.isSolved() & variable2.isSolved()) {
|
||||
result.add(((Number)variable1).add((Number)variable2));
|
||||
result.add(((Number)variable1).add(((Number)variable2).multiply(new Number(root, "-1"))));
|
||||
result.add(((Number) variable1).add((Number) variable2));
|
||||
result.add(((Number) variable1).add(((Number) variable2).multiply(new Number(root, "-1"))));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -67,29 +75,29 @@ public class SumSubtraction extends FunctionTwoValues {
|
||||
public void generateGraphics() {
|
||||
variable1.setSmall(small);
|
||||
variable1.generateGraphics();
|
||||
|
||||
|
||||
variable2.setSmall(small);
|
||||
variable2.generateGraphics();
|
||||
|
||||
|
||||
width = calcWidth();
|
||||
height = calcHeight();
|
||||
line = calcLine();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
// glColor3f(127, 127-50+new Random().nextInt(50), 255);
|
||||
// glFillRect(x,y,width,height);
|
||||
// glColor3f(0, 0, 0);
|
||||
|
||||
int ln = getLine();
|
||||
|
||||
final int ln = getLine();
|
||||
int dx = 0;
|
||||
variable1.draw(dx + x, ln - variable1.getLine() + y);
|
||||
dx += variable1.getWidth();
|
||||
PIDisplay.renderer.glSetFont(Utils.getFont(small));
|
||||
DisplayManager.renderer.glSetFont(Utils.getFont(small));
|
||||
dx += 1;
|
||||
PIDisplay.renderer.glDrawStringLeft(dx + x, ln - Utils.getFontHeight(small) / 2 + y, getSymbol());
|
||||
dx += PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), getSymbol());
|
||||
DisplayManager.renderer.glDrawStringLeft(dx + x, ln - Utils.getFontHeight(small) / 2 + y, getSymbol());
|
||||
dx += DisplayManager.renderer.glGetStringWidth(Utils.getFont(small), getSymbol());
|
||||
variable2.draw(dx + x, ln - variable2.getLine() + y);
|
||||
}
|
||||
|
||||
@ -97,20 +105,20 @@ public class SumSubtraction extends FunctionTwoValues {
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int calcWidth() {
|
||||
int dx = 0;
|
||||
dx += variable1.getWidth();
|
||||
dx += 1;
|
||||
dx += PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), getSymbol());
|
||||
dx += DisplayManager.renderer.glGetStringWidth(Utils.getFont(small), getSymbol());
|
||||
return dx += variable2.getWidth();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof SumSubtraction) {
|
||||
FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
final FunctionTwoValues f = (FunctionTwoValues) o;
|
||||
return variable1.equals(f.variable1) && variable2.equals(f.variable2);
|
||||
}
|
||||
return false;
|
||||
|
@ -4,12 +4,12 @@ import java.util.List;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
|
||||
public class Undefined implements Function {
|
||||
|
||||
|
||||
protected final Calculator root;
|
||||
|
||||
public Undefined(Calculator root) {
|
||||
@ -33,18 +33,18 @@ public class Undefined implements Function {
|
||||
|
||||
private int width, height, line;
|
||||
private boolean small;
|
||||
|
||||
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
width = PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), "UNDEFINED");
|
||||
width = DisplayManager.renderer.glGetStringWidth(Utils.getFont(small), "UNDEFINED");
|
||||
height = Utils.getFontHeight(small);
|
||||
line = height/2;
|
||||
line = height / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
PIDisplay.renderer.glSetFont(Utils.getFont(small));
|
||||
PIDisplay.renderer.glDrawStringLeft(x, y, "UNDEFINED");
|
||||
DisplayManager.renderer.glSetFont(Utils.getFont(small));
|
||||
DisplayManager.renderer.glDrawStringLeft(x, y, "UNDEFINED");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,7 +71,7 @@ public class Undefined implements Function {
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Undefined) {
|
||||
|
@ -5,7 +5,7 @@ import java.util.List;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
@ -18,7 +18,7 @@ public class Variable implements Function {
|
||||
protected int line;
|
||||
protected boolean small;
|
||||
protected final Calculator root;
|
||||
|
||||
|
||||
public Variable(Calculator root, char val) {
|
||||
this.root = root;
|
||||
var = val;
|
||||
@ -50,7 +50,7 @@ public class Variable implements Function {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ""+getChar();
|
||||
return "" + getChar();
|
||||
}
|
||||
|
||||
// public void draw(int x, int y, PIDisplay g, boolean small, boolean drawMinus) {
|
||||
@ -62,42 +62,42 @@ public class Variable implements Function {
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
PIDisplay.renderer.glSetFont(Utils.getFont(small));
|
||||
PIDisplay.renderer.glDrawStringLeft(x+1, y, toString());
|
||||
Utils.getFont(small).use(DisplayManager.display);
|
||||
DisplayManager.renderer.glDrawStringLeft(x + 1, y, toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
private int calcHeight() {
|
||||
int h1 = Utils.getFontHeight(small);
|
||||
final int h1 = Utils.getFontHeight(small);
|
||||
return h1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
public int calcWidth() {
|
||||
return PIDisplay.renderer.glGetStringWidth(Utils.getFont(small), toString())+1;
|
||||
return Utils.getFont(small).getStringWidth(toString()) + 1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
private int calcLine() {
|
||||
return Utils.getFontHeight(small) / 2;
|
||||
}
|
||||
|
||||
|
||||
public static class VariableValue {
|
||||
public final Variable v;
|
||||
public final Number n;
|
||||
|
||||
|
||||
public VariableValue(Variable v, Number n) {
|
||||
this.v = v;
|
||||
this.n = n;
|
||||
@ -106,10 +106,10 @@ public class Variable implements Function {
|
||||
|
||||
@Override
|
||||
public Variable clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
final Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSmall(boolean small) {
|
||||
this.small = small;
|
||||
@ -122,16 +122,16 @@ public class Variable implements Function {
|
||||
|
||||
@Override
|
||||
public List<Function> solveOneStep() throws Error {
|
||||
List<Function> result = new ArrayList<>();
|
||||
final List<Function> result = new ArrayList<>();
|
||||
result.add(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Variable) {
|
||||
|
@ -21,7 +21,7 @@ import com.rits.cloning.Cloner;
|
||||
public class Equation extends FunctionTwoValues {
|
||||
|
||||
public Equation(Calculator root, Function value1, Function value2) {
|
||||
super(root, value1,value2);
|
||||
super(root, value1, value2);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -33,7 +33,7 @@ public class Equation extends FunctionTwoValues {
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.EQUATION;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isSolvable() {
|
||||
if (variable1 instanceof Number & variable2 instanceof Number) {
|
||||
@ -41,45 +41,45 @@ public class Equation extends FunctionTwoValues {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ArrayList<Function> solve() throws Error {
|
||||
if (variable1 == null || variable2 == null) {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
if (variable1.isSolved() & variable2.isSolved()) {
|
||||
if (((Number)variable2).getTerm().compareTo(new BigDecimal(0)) == 0) {
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
if (variable1.isSolved() & variable2.isSolved()) {
|
||||
if (((Number) variable2).getTerm().compareTo(new BigDecimal(0)) == 0) {
|
||||
result.add(this);
|
||||
} else {
|
||||
Equation e = new Equation(root, null, null);
|
||||
final Equation e = new Equation(root, null, null);
|
||||
e.setVariable1(new Subtraction(root, variable1, variable2));
|
||||
e.setVariable2(new Number(root, "0"));
|
||||
result.add(e);
|
||||
result.add(e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public List<Function> solve(char variableCharacter) {
|
||||
@SuppressWarnings("unused")
|
||||
ArrayList<Equation> e;
|
||||
final ArrayList<Equation> e;
|
||||
//TODO: WORK IN PROGRESS.
|
||||
//TODO: Finire. Fare in modo che risolva i passaggi fino a che non ce ne sono più
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
//WORK IN PROGRESS
|
||||
public ArrayList<Equation> solveStep(char charIncognita) {
|
||||
ArrayList<Equation> result = new ArrayList<>();
|
||||
result.add(this.clone());
|
||||
for (SolveMethod t : SolveMethod.techniques) {
|
||||
ArrayList<Equation> newResults = new ArrayList<>();
|
||||
result.add(clone());
|
||||
for (final SolveMethod t : SolveMethod.techniques) {
|
||||
final ArrayList<Equation> newResults = new ArrayList<>();
|
||||
final int sz = result.size();
|
||||
for (int n = 0; n < sz; n++) {
|
||||
newResults.addAll(t.solve(result.get(n)));
|
||||
}
|
||||
Set<Equation> hs = new HashSet<>();
|
||||
final Set<Equation> hs = new HashSet<>();
|
||||
hs.addAll(newResults);
|
||||
newResults.clear();
|
||||
newResults.addAll(hs);
|
||||
@ -91,8 +91,14 @@ public class Equation extends FunctionTwoValues {
|
||||
|
||||
@Override
|
||||
public Equation clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
final Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.gui.PIDisplay;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
import org.warp.picalculator.math.functions.Expression;
|
||||
import org.warp.picalculator.math.functions.Function;
|
||||
@ -17,11 +17,11 @@ public class EquationsSystem extends FunctionMultipleValues {
|
||||
public EquationsSystem(Calculator root) {
|
||||
super(root);
|
||||
}
|
||||
|
||||
|
||||
public EquationsSystem(Calculator root, Function value) {
|
||||
super(root, new Function[]{value});
|
||||
super(root, new Function[] { value });
|
||||
}
|
||||
|
||||
|
||||
public EquationsSystem(Calculator root, Function[] value) {
|
||||
super(root, value);
|
||||
}
|
||||
@ -38,31 +38,31 @@ public class EquationsSystem extends FunctionMultipleValues {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Function> solveOneStep() throws Error {
|
||||
List<Function> ret = new ArrayList<>();
|
||||
final List<Function> ret = new ArrayList<>();
|
||||
if (functions.length == 1) {
|
||||
if (functions[0].isSolved()) {
|
||||
ret.add(functions[0]);
|
||||
return ret;
|
||||
} else {
|
||||
List<Function> l = functions[0].solveOneStep();
|
||||
for (Function f : l) {
|
||||
final List<Function> l = functions[0].solveOneStep();
|
||||
for (final Function f : l) {
|
||||
if (f instanceof Number) {
|
||||
ret.add(f);
|
||||
} else {
|
||||
ret.add(new Expression(this.root, new Function[]{f}));
|
||||
ret.add(new Expression(root, new Function[] { f }));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
for (Function f : functions) {
|
||||
for (final Function f : functions) {
|
||||
if (f.isSolved() == false) {
|
||||
List<Function> partial = f.solveOneStep();
|
||||
for (Function fnc : partial) {
|
||||
ret.add(new Expression(this.root, new Function[]{fnc}));
|
||||
final List<Function> partial = f.solveOneStep();
|
||||
for (final Function fnc : partial) {
|
||||
ret.add(new Expression(root, new Function[] { fnc }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -72,49 +72,48 @@ public class EquationsSystem extends FunctionMultipleValues {
|
||||
|
||||
@Override
|
||||
public void generateGraphics() {
|
||||
for (Function f : functions) {
|
||||
for (final Function f : functions) {
|
||||
f.setSmall(false);
|
||||
f.generateGraphics();
|
||||
}
|
||||
|
||||
|
||||
width = 0;
|
||||
for (Function f : functions) {
|
||||
for (final Function f : functions) {
|
||||
if (f.getWidth() > width) {
|
||||
width = f.getWidth();
|
||||
}
|
||||
}
|
||||
width += 5;
|
||||
|
||||
|
||||
height = 3;
|
||||
for (Function f : functions) {
|
||||
height += f.getHeight()+spacing;
|
||||
for (final Function f : functions) {
|
||||
height += f.getHeight() + spacing;
|
||||
}
|
||||
height = height - spacing + 2;
|
||||
|
||||
line = height/2;
|
||||
|
||||
line = height / 2;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
|
||||
final int h = this.getHeight() - 1;
|
||||
final int h = getHeight() - 1;
|
||||
final int marginTop = 3;
|
||||
final int marginBottom = (h - 3 - 2) / 2 + marginTop;
|
||||
final int spazioSopra = h - marginBottom;
|
||||
int dy = marginTop;
|
||||
for (Function f : functions) {
|
||||
for (final Function f : functions) {
|
||||
f.draw(x + 5, y + dy);
|
||||
dy+=f.getHeight()+spacing;
|
||||
dy += f.getHeight() + spacing;
|
||||
}
|
||||
|
||||
|
||||
PIDisplay.renderer.glDrawLine(x + 2, y + 0, x + 3, y + 0);
|
||||
PIDisplay.renderer.glDrawLine(x + 1, y + 1, x + 1, y + marginBottom / 2);
|
||||
PIDisplay.renderer.glDrawLine(x + 2, y + marginBottom / 2 + 1, x + 2, y + marginBottom - 1);
|
||||
PIDisplay.renderer.glDrawLine(x + 0, y + marginBottom, x + 1, y + marginBottom);
|
||||
PIDisplay.renderer.glDrawLine(x + 2, y + marginBottom + 1, x + 2, y + marginBottom + spazioSopra / 2 - 1);
|
||||
PIDisplay.renderer.glDrawLine(x + 1, y + marginBottom + spazioSopra / 2, x + 1, y + h - 1);
|
||||
PIDisplay.renderer.glDrawLine(x + 2, y + h, x + 3, y + h);
|
||||
|
||||
DisplayManager.renderer.glDrawLine(x + 2, y + 0, x + 3, y + 0);
|
||||
DisplayManager.renderer.glDrawLine(x + 1, y + 1, x + 1, y + marginBottom / 2);
|
||||
DisplayManager.renderer.glDrawLine(x + 2, y + marginBottom / 2 + 1, x + 2, y + marginBottom - 1);
|
||||
DisplayManager.renderer.glDrawLine(x + 0, y + marginBottom, x + 1, y + marginBottom);
|
||||
DisplayManager.renderer.glDrawLine(x + 2, y + marginBottom + 1, x + 2, y + marginBottom + spazioSopra / 2 - 1);
|
||||
DisplayManager.renderer.glDrawLine(x + 1, y + marginBottom + spazioSopra / 2, x + 1, y + h - 1);
|
||||
DisplayManager.renderer.glDrawLine(x + 2, y + h, x + 3, y + h);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.warp.picalculator.math.functions.equations;
|
||||
|
||||
import static org.warp.picalculator.gui.graphicengine.cpu.CPUDisplay.Render.glDrawLine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -21,7 +19,7 @@ public class EquationsSystemPart extends AnteriorFunction {
|
||||
protected Function NewInstance(Calculator root, Function value) {
|
||||
return new EquationsSystemPart(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.SYSTEM;
|
||||
@ -31,15 +29,15 @@ public class EquationsSystemPart extends AnteriorFunction {
|
||||
public void generateGraphics() {
|
||||
variable.setSmall(false);
|
||||
variable.generateGraphics();
|
||||
|
||||
|
||||
width = 5 + getVariable().getWidth();
|
||||
height = 3 + getVariable().getHeight() + 2;
|
||||
line = 3 + getVariable().getLine();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
final int h = this.getHeight() - 1;
|
||||
final int h = getHeight() - 1;
|
||||
final int paddingTop = 3;
|
||||
final int spazioSotto = (h - 3 - 2) / 2 + paddingTop;
|
||||
final int spazioSopra = h - spazioSotto;
|
||||
@ -67,4 +65,22 @@ public class EquationsSystemPart extends AnteriorFunction {
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayList<Function> solve() throws Error {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSolvable() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -9,16 +9,16 @@ import org.warp.picalculator.math.functions.AnteriorFunction;
|
||||
import org.warp.picalculator.math.functions.Function;
|
||||
|
||||
public class ArcCosine extends AnteriorFunction {
|
||||
|
||||
|
||||
public ArcCosine(Calculator root, Function value) {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Function NewInstance(Calculator root, Function value) {
|
||||
return new ArcCosine(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.ARC_COSINE);
|
||||
|
@ -9,16 +9,16 @@ import org.warp.picalculator.math.functions.AnteriorFunction;
|
||||
import org.warp.picalculator.math.functions.Function;
|
||||
|
||||
public class ArcSine extends AnteriorFunction {
|
||||
|
||||
|
||||
public ArcSine(Calculator root, Function value) {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Function NewInstance(Calculator root, Function value) {
|
||||
return new ArcSine(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.ARC_SINE);
|
||||
|
@ -9,16 +9,16 @@ import org.warp.picalculator.math.functions.AnteriorFunction;
|
||||
import org.warp.picalculator.math.functions.Function;
|
||||
|
||||
public class ArcTangent extends AnteriorFunction {
|
||||
|
||||
|
||||
public ArcTangent(Calculator root, Function value) {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Function NewInstance(Calculator root, Function value) {
|
||||
return new ArcTangent(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.ARC_TANGENT);
|
||||
|
@ -9,16 +9,16 @@ import org.warp.picalculator.math.functions.AnteriorFunction;
|
||||
import org.warp.picalculator.math.functions.Function;
|
||||
|
||||
public class Cosine extends AnteriorFunction {
|
||||
|
||||
|
||||
public Cosine(Calculator root, Function value) {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Function NewInstance(Calculator root, Function value) {
|
||||
return new Cosine(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.COSINE);
|
||||
|
@ -12,16 +12,16 @@ import org.warp.picalculator.math.functions.Function;
|
||||
import org.warp.picalculator.math.functions.Number;
|
||||
|
||||
public class Sine extends AnteriorFunction {
|
||||
|
||||
|
||||
public Sine(Calculator root, Function value) {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Function NewInstance(Calculator root, Function value) {
|
||||
return new Sine(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.SINE);
|
||||
@ -35,14 +35,14 @@ public class Sine extends AnteriorFunction {
|
||||
}
|
||||
}
|
||||
if (root.angleMode == AngleMode.DEG) {
|
||||
Function[] solvableValues = new Function[]{new Number(root, 0), new Number(root, 30), new Number(root, 90), };
|
||||
final Function[] solvableValues = new Function[] { new Number(root, 0), new Number(root, 30), new Number(root, 90), };
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<Function> solve() throws Error {
|
||||
ArrayList<Function> results = new ArrayList<>();
|
||||
final ArrayList<Function> results = new ArrayList<>();
|
||||
if (variable instanceof Number) {
|
||||
if (root.exactMode == false) {
|
||||
results.add(new Number(root, BigDecimalMath.sin(((Number) variable).getTerm())));
|
||||
@ -54,7 +54,7 @@ public class Sine extends AnteriorFunction {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Sine) {
|
||||
AnteriorFunction f = (AnteriorFunction) o;
|
||||
final AnteriorFunction f = (AnteriorFunction) o;
|
||||
if (variable.equals(f.getVariable())) {
|
||||
return true;
|
||||
}
|
||||
|
@ -9,16 +9,16 @@ import org.warp.picalculator.math.functions.AnteriorFunction;
|
||||
import org.warp.picalculator.math.functions.Function;
|
||||
|
||||
public class Tangent extends AnteriorFunction {
|
||||
|
||||
|
||||
public Tangent(Calculator root, Function value) {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Function NewInstance(Calculator root, Function value) {
|
||||
return new Tangent(root, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSymbol() {
|
||||
return MathematicalSymbols.getGraphicRepresentation(MathematicalSymbols.TANGENT);
|
||||
|
@ -16,6 +16,7 @@ import org.warp.picalculator.math.functions.SumSubtraction;
|
||||
* Expand rule<br>
|
||||
* <b>-(+a+b) = -a-b</b><br>
|
||||
* <b>-(+a-b) = -a+b</b>
|
||||
*
|
||||
* @author Andrea Cavalli
|
||||
*
|
||||
*/
|
||||
@ -23,9 +24,9 @@ public class ExpandRule1 {
|
||||
|
||||
public static boolean compare(Function f) {
|
||||
if (f instanceof Negative) {
|
||||
Negative fnc = (Negative) f;
|
||||
final Negative fnc = (Negative) f;
|
||||
if (fnc.getVariable() instanceof Expression) {
|
||||
Expression expr = (Expression) fnc.getVariable();
|
||||
final Expression expr = (Expression) fnc.getVariable();
|
||||
if (expr.getVariablesLength() == 1) {
|
||||
if (expr.getVariable(0) instanceof Sum) {
|
||||
return true;
|
||||
@ -37,9 +38,9 @@ public class ExpandRule1 {
|
||||
}
|
||||
}
|
||||
} else if (f instanceof Subtraction || f instanceof SumSubtraction) {
|
||||
FunctionTwoValues fnc = (FunctionTwoValues) f;
|
||||
final FunctionTwoValues fnc = (FunctionTwoValues) f;
|
||||
if (fnc.getVariable2() instanceof Expression) {
|
||||
Expression expr = (Expression) fnc.getVariable2();
|
||||
final Expression expr = (Expression) fnc.getVariable2();
|
||||
if (expr.getVariablesLength() == 1) {
|
||||
if (expr.getVariable(0) instanceof Sum) {
|
||||
return true;
|
||||
@ -55,68 +56,68 @@ public class ExpandRule1 {
|
||||
}
|
||||
|
||||
public static ArrayList<Function> execute(Function f) throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
Calculator root = f.getRoot();
|
||||
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
final Calculator root = f.getRoot();
|
||||
|
||||
Expression expr = null;
|
||||
int fromSubtraction = 0;
|
||||
FunctionTwoValues subtraction = null;
|
||||
if (f instanceof Negative) {
|
||||
expr = ((Expression)((Negative) f).getVariable());
|
||||
expr = ((Expression) ((Negative) f).getVariable());
|
||||
} else if (f instanceof Subtraction || f instanceof SumSubtraction) {
|
||||
expr = ((Expression)((FunctionTwoValues) f).getVariable2());
|
||||
expr = ((Expression) ((FunctionTwoValues) f).getVariable2());
|
||||
if (f instanceof Subtraction) {
|
||||
fromSubtraction = 1;
|
||||
} else {
|
||||
fromSubtraction = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (f instanceof SumSubtraction) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
Function fnc = expr.getVariable(0);
|
||||
final Function fnc = expr.getVariable(0);
|
||||
if (fnc instanceof Sum) {
|
||||
Function a = ((Sum) fnc).getVariable1();
|
||||
Function b = ((Sum) fnc).getVariable2();
|
||||
Subtraction fnc2 = new Subtraction(root, null, b);
|
||||
final Function a = ((Sum) fnc).getVariable1();
|
||||
final Function b = ((Sum) fnc).getVariable2();
|
||||
final Subtraction fnc2 = new Subtraction(root, null, b);
|
||||
fnc2.setVariable1(new Negative(root, a));
|
||||
if (fromSubtraction > 0) {
|
||||
subtraction = new Subtraction(root, null, null);
|
||||
subtraction.setVariable1(((FunctionTwoValues)f).getVariable1());
|
||||
subtraction.setVariable1(((FunctionTwoValues) f).getVariable1());
|
||||
subtraction.setVariable2(fnc2);
|
||||
result.add(subtraction);
|
||||
} else {
|
||||
result.add(fnc2);
|
||||
}
|
||||
} else if (fnc instanceof Subtraction) {
|
||||
Function a = ((Subtraction) fnc).getVariable1();
|
||||
Function b = ((Subtraction) fnc).getVariable2();
|
||||
Sum fnc2 = new Sum(root, null, b);
|
||||
final Function a = ((Subtraction) fnc).getVariable1();
|
||||
final Function b = ((Subtraction) fnc).getVariable2();
|
||||
final Sum fnc2 = new Sum(root, null, b);
|
||||
fnc2.setVariable1(new Negative(root, a));
|
||||
if (fromSubtraction > 0) {
|
||||
subtraction = new Subtraction(root, null, null);
|
||||
subtraction.setVariable1(((FunctionTwoValues)f).getVariable1());
|
||||
subtraction.setVariable1(((FunctionTwoValues) f).getVariable1());
|
||||
subtraction.setVariable2(fnc2);
|
||||
result.add(subtraction);
|
||||
} else {
|
||||
result.add(fnc2);
|
||||
}
|
||||
} else if (fnc instanceof SumSubtraction) {
|
||||
Function a = ((SumSubtraction) fnc).getVariable1();
|
||||
Function b = ((SumSubtraction) fnc).getVariable2();
|
||||
Sum fnc2 = new Sum(root, null, b);
|
||||
final Function a = ((SumSubtraction) fnc).getVariable1();
|
||||
final Function b = ((SumSubtraction) fnc).getVariable2();
|
||||
final Sum fnc2 = new Sum(root, null, b);
|
||||
fnc2.setVariable1(new Negative(root, a));
|
||||
Subtraction fnc3 = new Subtraction(root, null, b);
|
||||
final Subtraction fnc3 = new Subtraction(root, null, b);
|
||||
fnc3.setVariable1(new Negative(root, a));
|
||||
if (fromSubtraction > 0) {
|
||||
subtraction = new SumSubtraction(root, null, null);
|
||||
subtraction.setVariable1(((FunctionTwoValues)f).getVariable1());
|
||||
subtraction.setVariable1(((FunctionTwoValues) f).getVariable1());
|
||||
subtraction.setVariable2(fnc2);
|
||||
result.add(subtraction);
|
||||
subtraction = new SumSubtraction(root, null, null);
|
||||
subtraction.setVariable1(((FunctionTwoValues)f).getVariable1());
|
||||
subtraction.setVariable1(((FunctionTwoValues) f).getVariable1());
|
||||
subtraction.setVariable2(fnc3);
|
||||
result.add(subtraction);
|
||||
result.add(subtraction);
|
||||
|
@ -3,7 +3,6 @@ package org.warp.picalculator.math.rules;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.math.Calculator;
|
||||
import org.warp.picalculator.math.functions.Expression;
|
||||
import org.warp.picalculator.math.functions.Function;
|
||||
import org.warp.picalculator.math.functions.Negative;
|
||||
@ -12,6 +11,7 @@ import org.warp.picalculator.math.functions.Subtraction;
|
||||
/**
|
||||
* Expand rule<br>
|
||||
* <b>-(-a) = a</b>
|
||||
*
|
||||
* @author Andrea Cavalli
|
||||
*
|
||||
*/
|
||||
@ -19,15 +19,15 @@ public class ExpandRule5 {
|
||||
|
||||
public static boolean compare(Function f) {
|
||||
if (f instanceof Negative) {
|
||||
Negative fnc = (Negative) f;
|
||||
final Negative fnc = (Negative) f;
|
||||
if (fnc.getVariable() instanceof Expression) {
|
||||
Expression e = (Expression)fnc.getVariable();
|
||||
final Expression e = (Expression) fnc.getVariable();
|
||||
return e.getVariablesLength() == 1 && e.getVariable(0) instanceof Negative;
|
||||
}
|
||||
} else if (f instanceof Subtraction) {
|
||||
Subtraction fnc = (Subtraction) f;
|
||||
final Subtraction fnc = (Subtraction) f;
|
||||
if (fnc.getVariable2() instanceof Expression) {
|
||||
Expression e = (Expression)fnc.getVariable2();
|
||||
final Expression e = (Expression) fnc.getVariable2();
|
||||
return e.getVariablesLength() == 1 && e.getVariable(0) instanceof Negative;
|
||||
}
|
||||
}
|
||||
@ -35,15 +35,15 @@ public class ExpandRule5 {
|
||||
}
|
||||
|
||||
public static ArrayList<Function> execute(Function f) throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
Function a = null;
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
final Function a = null;
|
||||
|
||||
if (f instanceof Negative) {
|
||||
Negative fnc = (Negative) f;
|
||||
result.add(((Negative)((Expression)fnc.getVariable()).getVariable(0)).getVariable());
|
||||
final Negative fnc = (Negative) f;
|
||||
result.add(((Negative) ((Expression) fnc.getVariable()).getVariable(0)).getVariable());
|
||||
} else if (f instanceof Subtraction) {
|
||||
Subtraction fnc = (Subtraction) f;
|
||||
result.add(((Negative)((Expression)fnc.getVariable2()).getVariable(0)).getVariable());
|
||||
final Subtraction fnc = (Subtraction) f;
|
||||
result.add(((Negative) ((Expression) fnc.getVariable2()).getVariable(0)).getVariable());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -11,14 +11,15 @@ import org.warp.picalculator.math.functions.Power;
|
||||
/**
|
||||
* Exponent rule<br>
|
||||
* <b>1^a=1</b>
|
||||
*
|
||||
* @author Andrea Cavalli
|
||||
*
|
||||
*/
|
||||
public class ExponentRule1 {
|
||||
|
||||
public static boolean compare(Function f) {
|
||||
Power fnc = (Power) f;
|
||||
Calculator root = f.getRoot();
|
||||
final Power fnc = (Power) f;
|
||||
final Calculator root = f.getRoot();
|
||||
if (fnc.getVariable1().equals(new Number(root, 1))) {
|
||||
return true;
|
||||
}
|
||||
@ -26,8 +27,8 @@ public class ExponentRule1 {
|
||||
}
|
||||
|
||||
public static ArrayList<Function> execute(Function f) throws Error {
|
||||
Calculator root = f.getRoot();
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
final Calculator root = f.getRoot();
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
result.add(new Number(root, 1));
|
||||
return result;
|
||||
}
|
||||
|
@ -13,13 +13,14 @@ import org.warp.picalculator.math.functions.Power;
|
||||
/**
|
||||
* Exponent rule<br>
|
||||
* <b>a*a=a^2</b>
|
||||
*
|
||||
* @author Andrea Cavalli
|
||||
*
|
||||
*/
|
||||
public class ExponentRule15 {
|
||||
|
||||
public static boolean compare(Function f) {
|
||||
Multiplication fnc = (Multiplication) f;
|
||||
final Multiplication fnc = (Multiplication) f;
|
||||
if (fnc.getVariable1().equals(fnc.getVariable2())) {
|
||||
return true;
|
||||
}
|
||||
@ -27,14 +28,14 @@ public class ExponentRule15 {
|
||||
}
|
||||
|
||||
public static ArrayList<Function> execute(Function f) throws Error {
|
||||
Calculator root = f.getRoot();
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
Multiplication fnc = (Multiplication) f;
|
||||
Power p = new Power(root, null, null);
|
||||
Expression expr = new Expression(root);
|
||||
Function a = fnc.getVariable1();
|
||||
final Calculator root = f.getRoot();
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
final Multiplication fnc = (Multiplication) f;
|
||||
final Power p = new Power(root, null, null);
|
||||
final Expression expr = new Expression(root);
|
||||
final Function a = fnc.getVariable1();
|
||||
expr.addFunctionToEnd(a);
|
||||
Number two = new Number(root, 2);
|
||||
final Number two = new Number(root, 2);
|
||||
p.setVariable1(expr);
|
||||
p.setVariable2(two);
|
||||
result.add(p);
|
||||
|
@ -14,6 +14,7 @@ import org.warp.picalculator.math.functions.Root;
|
||||
/**
|
||||
* Exponent rule<br>
|
||||
* <b>a√x=x^1/a</b>
|
||||
*
|
||||
* @author Andrea Cavalli
|
||||
*
|
||||
*/
|
||||
@ -21,7 +22,7 @@ public class ExponentRule16 {
|
||||
|
||||
public static boolean compare(Function f) {
|
||||
if (f instanceof Root) {
|
||||
Root fnc = (Root) f;
|
||||
final Root fnc = (Root) f;
|
||||
if (fnc.getVariable1().equals(fnc.getVariable2())) {
|
||||
return true;
|
||||
}
|
||||
@ -30,14 +31,14 @@ public class ExponentRule16 {
|
||||
}
|
||||
|
||||
public static ArrayList<Function> execute(Function f) throws Error {
|
||||
Calculator root = f.getRoot();
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
Multiplication fnc = (Multiplication) f;
|
||||
Power p = new Power(fnc.getRoot(), null, null);
|
||||
Expression expr = new Expression(root);
|
||||
Function a = fnc.getVariable1();
|
||||
final Calculator root = f.getRoot();
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
final Multiplication fnc = (Multiplication) f;
|
||||
final Power p = new Power(fnc.getRoot(), null, null);
|
||||
final Expression expr = new Expression(root);
|
||||
final Function a = fnc.getVariable1();
|
||||
expr.addFunctionToEnd(a);
|
||||
Number two = new Number(root, 2);
|
||||
final Number two = new Number(root, 2);
|
||||
p.setVariable1(expr);
|
||||
p.setVariable2(two);
|
||||
result.add(p);
|
||||
|
@ -10,13 +10,14 @@ import org.warp.picalculator.math.functions.Power;
|
||||
/**
|
||||
* Exponent rule<br>
|
||||
* <b>a^1=a</b>
|
||||
*
|
||||
* @author Andrea Cavalli
|
||||
*
|
||||
*/
|
||||
public class ExponentRule2 {
|
||||
|
||||
public static boolean compare(Function f) {
|
||||
Power fnc = (Power) f;
|
||||
final Power fnc = (Power) f;
|
||||
if (fnc.getVariable2().equals(new Number(f.getRoot(), 1))) {
|
||||
return true;
|
||||
}
|
||||
@ -24,8 +25,8 @@ public class ExponentRule2 {
|
||||
}
|
||||
|
||||
public static ArrayList<Function> execute(Function f) throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
result.add(((Power)f).getVariable1());
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
result.add(((Power) f).getVariable1());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -10,13 +10,14 @@ import org.warp.picalculator.math.functions.Power;
|
||||
/**
|
||||
* Exponent rule<br>
|
||||
* <b>a^0=1</b>
|
||||
*
|
||||
* @author Andrea Cavalli
|
||||
*
|
||||
*/
|
||||
public class ExponentRule3 {
|
||||
|
||||
public static boolean compare(Function f) {
|
||||
Power fnc = (Power) f;
|
||||
final Power fnc = (Power) f;
|
||||
if (fnc.getVariable2().equals(new Number(f.getRoot(), 0))) {
|
||||
return true;
|
||||
}
|
||||
@ -24,7 +25,7 @@ public class ExponentRule3 {
|
||||
}
|
||||
|
||||
public static ArrayList<Function> execute(Function f) throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
result.add(new Number(f.getRoot(), 1));
|
||||
return result;
|
||||
}
|
||||
|
@ -13,13 +13,14 @@ import org.warp.picalculator.math.functions.Power;
|
||||
/**
|
||||
* Exponent rule<br>
|
||||
* <b>(a*b)^n=a^n*b^n</b>
|
||||
*
|
||||
* @author Andrea Cavalli
|
||||
*
|
||||
*/
|
||||
public class ExponentRule4 {
|
||||
|
||||
public static boolean compare(Function f) {
|
||||
Power fnc = (Power) f;
|
||||
final Power fnc = (Power) f;
|
||||
if (fnc.getVariable1() instanceof Expression && ((Expression) fnc.getVariable1()).getVariablesLength() == 1 && ((Expression) fnc.getVariable1()).getVariable(0) instanceof Multiplication && fnc.getVariable2() instanceof Number) {
|
||||
return true;
|
||||
}
|
||||
@ -27,22 +28,22 @@ public class ExponentRule4 {
|
||||
}
|
||||
|
||||
public static ArrayList<Function> execute(Function f) throws Error {
|
||||
Calculator root = f.getRoot();
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
Power fnc = (Power) f;
|
||||
Expression expr = (Expression) fnc.getVariable1();
|
||||
Multiplication mult = (Multiplication) expr.getVariable(0);
|
||||
Function a = mult.getVariable1();
|
||||
Function b = mult.getVariable2();
|
||||
Number n = (Number) fnc.getVariable2();
|
||||
Multiplication retMult = new Multiplication(root, null, null);
|
||||
Power p1 = new Power(root, null, null);
|
||||
Expression e1 = new Expression(root);
|
||||
final Calculator root = f.getRoot();
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
final Power fnc = (Power) f;
|
||||
final Expression expr = (Expression) fnc.getVariable1();
|
||||
final Multiplication mult = (Multiplication) expr.getVariable(0);
|
||||
final Function a = mult.getVariable1();
|
||||
final Function b = mult.getVariable2();
|
||||
final Number n = (Number) fnc.getVariable2();
|
||||
final Multiplication retMult = new Multiplication(root, null, null);
|
||||
final Power p1 = new Power(root, null, null);
|
||||
final Expression e1 = new Expression(root);
|
||||
e1.addFunctionToEnd(a);
|
||||
p1.setVariable1(e1);
|
||||
p1.setVariable2(n);
|
||||
Power p2 = new Power(root, null, null);
|
||||
Expression e2 = new Expression(root);
|
||||
final Power p2 = new Power(root, null, null);
|
||||
final Expression e2 = new Expression(root);
|
||||
e2.addFunctionToEnd(b);
|
||||
p2.setVariable1(e2);
|
||||
p2.setVariable2(n);
|
||||
|
@ -11,19 +11,20 @@ import org.warp.picalculator.math.functions.Number;
|
||||
/**
|
||||
* Fractions rule<br>
|
||||
* <b>0 / a = 0</b>
|
||||
*
|
||||
* @author Andrea Cavalli
|
||||
*
|
||||
*/
|
||||
public class FractionsRule1 {
|
||||
|
||||
public static boolean compare(Function f) {
|
||||
Calculator root = f.getRoot();
|
||||
Division fnc = (Division) f;
|
||||
final Calculator root = f.getRoot();
|
||||
final Division fnc = (Division) f;
|
||||
if (fnc.getVariable1() instanceof Number) {
|
||||
Number numb1 = (Number) fnc.getVariable1();
|
||||
final Number numb1 = (Number) fnc.getVariable1();
|
||||
if (numb1.equals(new Number(root, 0))) {
|
||||
if (fnc.getVariable2() instanceof Number) {
|
||||
Number numb2 = (Number) fnc.getVariable2();
|
||||
final Number numb2 = (Number) fnc.getVariable2();
|
||||
if (numb2.equals(new Number(root, 0))) {
|
||||
return false;
|
||||
}
|
||||
@ -35,7 +36,7 @@ public class FractionsRule1 {
|
||||
}
|
||||
|
||||
public static ArrayList<Function> execute(Function f) throws Error {
|
||||
ArrayList<Function> result = new ArrayList<>();
|
||||
final ArrayList<Function> result = new ArrayList<>();
|
||||
result.add(new Number(f.getRoot(), 0));
|
||||
return result;
|
||||
}
|
||||
|
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