diff --git a/B12NumbersV3/B12Base.pde b/B12NumbersV3/B12Base.pde index df988d4..f2b4147 100644 --- a/B12NumbersV3/B12Base.pde +++ b/B12NumbersV3/B12Base.pde @@ -1,7 +1,5 @@ abstract interface Number{ abstract PVector getPos(); - - abstract Number addn(Number num); abstract void display(); } @@ -19,7 +17,7 @@ class B12Digit implements Number{ } B12Digit(char _c){ - String valid = "+-*/.:"; // Defines valid input characters + String valid = "+-*/.:()"; // Defines valid input characters if(!inStr(valid, _c)){ throw new IllegalArgumentException("B12Char only accepts \'+ - * / . :'"); } value = byte(_c); refPos = new PVector(0,0); @@ -29,7 +27,6 @@ class B12Digit implements Number{ B12Digit setRefPos(PVector _refPos){ refPos = _refPos; return this;} B12Digit setRefPos(float _x, float _y){ refPos = new PVector(_x,_y); return this;} B12Digit setValue(int _value){ value = byte(_value); return this;} - Number addn(Number num){throw new UnsupportedOperationException("B12Digit does not support adding characters");} // GETTERS PVector getPos(){ return refPos; } @@ -84,12 +81,16 @@ class B12Digit implements Number{ strokeWeight(2); period(); break; case ':': strokeWeight(2); colon(); break; + case '(': + parenl(); break; + case ')': + parenr(); break; } popMatrix(); } // Individual shape components to build any B12 number - private void line0(){ ellipse(0,-13,8,0); } + private void line0(){ quad(4,0,7,-6.5,4,-13,1,-6.5); }// ellipse(0,-13,8,0); } private void line1(){ line(6,0,9,-10); } private void line2(){ line(3,-10,6,0); } private void line3(){ line(0,0,3,-10); } @@ -103,6 +104,8 @@ class B12Digit implements Number{ private void linePlus(){ line(6,-8,6,-2); } private void period(){ point(5,0); } private void colon(){ point(5,-2); point(5,-8); } + private void parenl(){ line(5,-13,3,-6.5); line(5,0,3,-6.5); } + private void parenr(){ line(1,-13,3,-6.5); line(1,0,3,-6.5);} // HELPER FUNCTIONS // @@ -153,24 +156,6 @@ class B12Int implements Number { return this; } - Number addn(Number num){ - /*if(num.getClass() == ByteE.class){ - ByteE b = (ByteE)num; - value += int(b.getValue()); - return new B12Int(value); - }*/ - if(num.getClass() == B12Int.class){ - B12Int i = (B12Int)num; - value += i.getValue(); - return new B12Int(value); - } - if(num.getClass() == B12Float.class){ - B12Float i = (B12Float)num; - return i.addn(this); - } - throw new IllegalArgumentException("addn only takes types B12Int and B12Float"); - } - void display(){ if(!arrayLoaded){ loadArray(); } if(!inPosition){ positionDigits(); } @@ -266,25 +251,6 @@ class B12Float implements Number{ return this; } - Number addn(Number num){ - /*if(num.getClass() == ByteE.class){ - ByteE b = (ByteE)num; - value += float(b.getValue()); - return new B12Float(vlaue); - }*/ - if(num.getClass() == B12Int.class){ - B12Int i = (B12Int)num; - value += float(i.getValue()); - return new B12Float(value); - } - if(num.getClass() == B12Float.class){ - B12Float i = (B12Float)num; - value += i.getValue(); - return new B12Float(value); - } - throw new IllegalArgumentException("addn only takes types B12Int and B12Float"); - } - void display(){ if(!arrayLoaded){ loadArray(); } if(!inPosition){ positionDigits(); } diff --git a/B12NumbersV3/B12NumbersV3.pde b/B12NumbersV3/B12NumbersV3.pde index ada1289..aa050b1 100644 --- a/B12NumbersV3/B12NumbersV3.pde +++ b/B12NumbersV3/B12NumbersV3.pde @@ -11,12 +11,12 @@ Button eval; void setup(){ size(400,400); - offset = new PVector(width/2, height/2); + offset = new PVector(width/4, height/4); mh = new MouseHandler(new MouseData(offset, scale)); calc = new Calculator(mh); - reset = new Button(mh).setPos(new PVector(20,-20), new PVector(40,20)).setRadius(2).setColor(#06BA63).autoHighlight().setText("Reset").setFunction(new MethodRelay(this, "changeMode")); + reset = new Button(mh).setPos(new PVector(20,-20), new PVector(40,20)).setRadius(2).setColor(#06BA63).autoHighlight().setText("Reset").setFunction(new MethodRelay(this, "reset")); eval = new Button(mh).setPos(new PVector(20,-40), new PVector(40,20)).setRadius(2).setColor(#06BA63).autoHighlight().setText("Eval").setFunction(new MethodRelay(calc.ex, "evaluate")); @@ -28,8 +28,7 @@ void draw(){ mh.frameUpdate(offset, scale); stroke(0); strokeWeight(1); - line(width/2,0,width/2,height); - line(0,height/2,width,height/2); + crossMark(); translate(offset.x,offset.y); scale(scale); @@ -57,8 +56,18 @@ void call(String _call){ void changeMode(){ if(calc == null){ calc = new Calculator(mh); + eval.setFunction(new MethodRelay(calc.ex, "evaluate")); return; } calc = null; Runtime.getRuntime().gc(); } + +void reset(){ + calc.ex.clear(); +} + +void crossMark(){ + line(offset.x,0,offset.x,height); + line(0,offset.y,width,offset.y); +} diff --git a/B12NumbersV3/guiB12Expression.pde b/B12NumbersV3/guiB12Expression.pde index 51d750f..88741b4 100644 --- a/B12NumbersV3/guiB12Expression.pde +++ b/B12NumbersV3/guiB12Expression.pde @@ -24,78 +24,114 @@ class B12Expression { return this; } + void clear(){ + expression = new B12Digit[0]; + } + void evaluate(){ + //db println("evaluate"); //<>// String valid = "+*-/"; // valid characters to accept - String evalString = ""; // gets filled with the expression up for evaluation in base - Number cnum = null; // used to sum numbers as the array is parsed - int count = 0; // counts what column we're at for multiplying base 12 to base 10 + String evalString = ""; // gets filled with the expression up for evaluation in base 10 + B12Digit[] cnum = new B12Digit[0]; // used to sum numbers as the array is parsed + boolean cfs = false; // float status of currently building number + //int count = 0; // counts what column we're at for multiplying base 12 to base 10 // Parse expression[] into a base 10 string that can be evaluated mathematically - if(!expression[expression.length - 1].isNum()){throw new IllegalArgumentException("Invalid input");} // check that final character is a number + if(!(expression[expression.length - 1].isNum() || expression[expression.length -1].getValue() == ')' )){throw new IllegalArgumentException("Invalid input");} // check that final character is a number + //db println("final char is valid"); for (int c = expression.length; c >= 0; c--){ + //db println("top of for loop " + c); int i = c - 1; if (i == -1){ // At the end, add the final number if neccessary //<>// // add number to string if present - if(cnum != null && cnum.getClass() == B12Int.class){ - B12Int t = (B12Int)cnum; - evalString = evalString + str(t.getValue()); - cnum = null; + if(cnum.length != 0 && cfs == false){ + B12Int num = (B12Int)convert(cnum,cfs); + evalString = str(num.getValue()) + evalString; + cnum = new B12Digit[0]; } - else if(cnum != null && cnum.getClass() == B12Float.class){ - B12Float t = (B12Float)cnum; - evalString = evalString + str(t.getValue()); - cnum = null; + else if(cnum.length != 0 && cfs == true){ + B12Float num = (B12Float)convert(cnum,cfs); + evalString = str(num.getValue()) + evalString; + cnum = new B12Digit[0]; + cfs = false; } break; } - + //db println("passed finish clause loop " + c); // If there is no number currently being built and the current character is a number start building a new number - if (expression[i].isNum() && cnum == null){ - count = 0; - cnum = new B12Int(int(expression[i].getValue())); + if (expression[i].isNum() && cnum.length == 0){ + //count = 0; + cnum = (B12Digit[])append(cnum,expression[i]); } // If the current character is a number and there IS a number currently being built add the character into the number - else if (expression[i].isNum() && cnum != null){ - count += 1; - cnum = cnum.addn(new B12Int(int(expression[i].getValue() * (pow(12,count))))); + else if (expression[i].isNum() && cnum.length != 0){ + //count += 1; + cnum = (B12Digit[])append(cnum,expression[i]); } - // If we run into a period and are currently building an int, switch to float and make current number the decimal. (MAY BE BROKEN) - else if (expression[i].value == '.' && cnum != null && cnum.getClass() == B12Int.class){ - B12Int temp = (B12Int)cnum; - //float f = float("." + str((B12Int)cnum.getValue())); - cnum = new B12Float(float("." + str(temp.getValue()))); + else if (expression[i].value == '.' && cnum.length != 0){ + if(cfs == true){throw new IllegalArgumentException("Invalid input");} + cnum = (B12Digit[])append(cnum,expression[i]); + cfs = true; } // If any other valid character just add it to the string after making sure to add the last built number if it exists else if (inStr(valid,char(expression[i].value))){ // reset number digit multiplier count - count = 0; + //count = 0; // add number to string if present - if(cnum != null && cnum.getClass() == B12Int.class){ - B12Int t = (B12Int)cnum; - evalString = evalString + str(t.getValue()); - cnum = null; + if(cnum.length != 0 && cfs == false){ + B12Int num = (B12Int)convert(cnum,cfs); + evalString = str(num.getValue()) + evalString; + cnum = new B12Digit[0]; } - if(cnum != null && cnum.getClass() == B12Float.class){ - B12Float t = (B12Float)cnum; - evalString = evalString + str(t.getValue()); - cnum = null; + else if(cnum.length != 0 && cfs == true){ + B12Float num = (B12Float)convert(cnum,cfs); + evalString = str(num.getValue()) + evalString; + cnum = new B12Digit[0]; + cfs = false; } // add character to string - evalString = evalString + char(expression[i].getValue()); + evalString = char(expression[i].getValue()) + evalString; } // In all other cases fail else{ + //db println("throwing exception"); throw new IllegalArgumentException("Invalid input"); } } println(evalString); } - + private Number convert(B12Digit[] cnum, boolean isFloat){ + if(!isFloat){ + int out = 0; + //cnum = (B12Digit[])reverse(cnum); + for(int i = 0; i < cnum.length; i++){ + out += cnum[i].getValue() * pow(12,i); + } + return new B12Int(out); + } + + // Else if float + float out = 0; + int pInd = 0; // Index of period + while(true){// find index of period + if(!cnum[pInd].isNum()){break;} + pInd++; + } + B12Digit[] deci = (B12Digit[])reverse(subset(cnum,0,pInd)); + B12Digit[] whole = (B12Digit[])subset(cnum,pInd+1,cnum.length-pInd-1); + for(int i = 0; i < deci.length; i++){ + out += (float(deci[i].getValue())/12) * pow(10,-i); + } + for(int i = 0; i < whole.length; i++){ + out += float(whole[i].getValue()) * pow(12,i); + } + return new B12Float(out); + } // HELPER FUNCTIONS // boolean inStr(String st, char _c){ diff --git a/B12NumbersV3/guiB12Math.pde b/B12NumbersV3/guiB12Math.pde deleted file mode 100644 index e142912..0000000 --- a/B12NumbersV3/guiB12Math.pde +++ /dev/null @@ -1,15 +0,0 @@ -/*class B12Math { - ArrayList expression; - - B12Math(){ - expression = new ArrayList();; - } - - void delete(int pos){ - expression.remove(pos); - } - - void evaluate(){ - //TODO set expression to evaluation of expression - } -}*/ diff --git a/B12NumbersV3/guiMathPad.pde b/B12NumbersV3/guiMathPad.pde index fdeb079..90566eb 100644 --- a/B12NumbersV3/guiMathPad.pde +++ b/B12NumbersV3/guiMathPad.pde @@ -13,15 +13,24 @@ class MathPad{ } void initialize(){ + // Create numpad buttons for(int i = 0; i < 12; i++){ /* Button position must contain it's absolute position relative to sketch 0,0 for mouseOver to work. This means we cannot translate and traw buttons, we mumst factor the parents position into the absolute position of the button */ // x = pos.x + (width + gap) * (i%cols) // y = pos.y + (height + gap) * b2rows - (height + gap) * row - PVector bPos = new PVector(pos.x + 22 * int(i%4),pos.y + 22 * 2 - 22 * floor(i/4)); + PVector bPos = new PVector(pos.x + 22 * int(i%4),pos.y + 22 * 3 - 22 * floor(i/4)); buttons[i] = new B12Button(mh ,new B12Digit(i)).setPos(bPos).setDim(new PVector(20,20)).setFunction(new MethodRelay(this, "addChar", B12Digit.class)).setColor(220,150); } + // Create other buttons + buttons = (Button[])append(buttons, new B12Button(mh, new B12Digit('(')).setPos(new PVector(pos.x,pos.y)).setFunction(new MethodRelay(this, "addChar", B12Digit.class)).setColor(220,150)); + buttons = (Button[])append(buttons, new B12Button(mh, new B12Digit(')')).setPos(new PVector(pos.x + 22,pos.y)).setFunction(new MethodRelay(this, "addChar", B12Digit.class)).setColor(220,150)); + buttons = (Button[])append(buttons, new B12Button(mh, new B12Digit('+')).setPos(new PVector(pos.x + 22*2,pos.y)).setFunction(new MethodRelay(this, "addChar", B12Digit.class)).setColor(220,150)); + buttons = (Button[])append(buttons, new B12Button(mh, new B12Digit('-')).setPos(new PVector(pos.x + 22*3,pos.y)).setFunction(new MethodRelay(this, "addChar", B12Digit.class)).setColor(220,150)); + buttons = (Button[])append(buttons, new B12Button(mh, new B12Digit('*')).setPos(new PVector(pos.x + 22*4,pos.y)).setFunction(new MethodRelay(this, "addChar", B12Digit.class)).setColor(220,150)); + buttons = (Button[])append(buttons, new B12Button(mh, new B12Digit('/')).setPos(new PVector(pos.x + 22*4,pos.y + 22)).setFunction(new MethodRelay(this, "addChar", B12Digit.class)).setColor(220,150)); + buttons = (Button[])append(buttons, new B12Button(mh, new B12Digit('.')).setPos(new PVector(pos.x + 22*4,pos.y + 22*2)).setFunction(new MethodRelay(this, "addChar", B12Digit.class)).setColor(220,150)); } // DONE send characters to display @@ -34,7 +43,7 @@ class MathPad{ void display(){ pushMatrix(); //translate(pos.x,pos.y); - for(int i = 0; i < 12; i++){ + for(int i = 0; i < buttons.length; i++){ buttons[i].display(); } popMatrix(); diff --git a/B12NumbersV3/zchangelog.pde b/B12NumbersV3/zchangelog.pde index d00a7ac..c131488 100644 --- a/B12NumbersV3/zchangelog.pde +++ b/B12NumbersV3/zchangelog.pde @@ -3,7 +3,7 @@ Beta version of a clock in base 12. by Nayan Sawyer started Mar 2022 - version 0.1.5.4 April 30 2022 + version 0.1.5.5 April 30 2022 Characters are a variation of Kaktovik Inupiaq numerals reversed and in base 12 instead of 20. I take no credit @@ -21,6 +21,10 @@ // MAYBE start clock widget structure // MAYBE add additional operations like power, log, and trig functions + changelog 0.1.5.5 + - finished parsing input array to string in B12Expression. + Added parenthesis chars to B12Digit and changed 0 char. + changelog 0.1.5.4 - updated buttons to take minimal creation arguments, and require the use of setters to change position, dimensions,