Esempio n. 1
0
  protected final void compute() {

    size = inputList.size();

    if (!inputList.isDefined()) {
      outputList.setUndefined();
      return;
    }

    outputList.setDefined(true);
    outputList.clear();

    if (size == 0) return;
    // <Zbynek Konecny 2010-05-13>
    /*
     * If val is not numeric, we use the underlying Expression of the function and
     * plug the list element as variable.
     * Deep copy is needed so that we can plug the value repeatedly.
     */
    FunctionVariable var = boolFun.getFunction().getFunctionVariable();
    for (int i = 0; i < size; i++) {
      GeoElement geo = inputList.get(i);
      if (geo.isGeoNumeric()) {
        if (boolFun.evaluateBoolean(((GeoNumeric) geo).getValue()))
          outputList.add(geo.copyInternal(cons));
        ;
      } else {
        ExpressionNode ex = (ExpressionNode) boolFun.getFunction().getExpression().deepCopy(kernel);
        ex.replaceAndWrap(var, geo.evaluate());
        if (((MyBoolean) ex.evaluate()).getBoolean()) outputList.add(geo.copyInternal(cons));
        ;
      }
    }
    // </Zbynek>
  }
Esempio n. 2
0
  private GeoElement[] processBoolean(ExpressionNode n, ExpressionValue evaluate) {
    GeoElement[] ret = new GeoElement[1];
    String label = n.getLabel();

    boolean isIndependent = n.isConstant();

    if (isIndependent) {
      ret[0] = kernel.Boolean(label, ((BooleanValue) evaluate).getBoolean());
    } else ret[0] = kernel.DependentBoolean(label, n);
    return ret;
  }
Esempio n. 3
0
  protected final void compute() {
    // Sum[{x^2,x^3}]

    int n = truncate == null ? geoList.size() : (int) truncate.getDouble();

    if (n == 0 || n > geoList.size()) {
      resultFun.setUndefined();
      return;
    } else if (n == 1) {
      if (!geoList.get(0).isGeoFunctionable()) {
        resultFun.setUndefined();
        return;
      }

      GeoFunction fun1 = ((GeoFunctionable) geoList.get(0)).getGeoFunction();

      FunctionVariable x1 = fun1.getFunction().getFunctionVariable();
      FunctionVariable x = new FunctionVariable(kernel);

      ExpressionNode left = fun1.getFunctionExpression().getCopy(fun1.getKernel());

      Function f = new Function(left.replace(x1, x), x);

      resultFun.setFunction(f);
      resultFun.setDefined(true);
      return;
    }

    if (!geoList.get(0).isGeoFunctionable() || !geoList.get(1).isGeoFunctionable()) {
      resultFun.setUndefined();
      return;
    }

    // add first two:
    resultFun =
        GeoFunction.add(
            resultFun,
            ((GeoFunctionable) geoList.get(0)).getGeoFunction(),
            ((GeoFunctionable) geoList.get(1)).getGeoFunction());

    if (n == 2) return;

    for (int i = 2; i < n; i++) {

      if (!geoList.get(i).isGeoFunctionable()) {
        resultFun.setUndefined();
        return;
      }
      resultFun =
          GeoFunction.add(
              resultFun, resultFun, ((GeoFunctionable) geoList.get(i)).getGeoFunction());
    }
  }
Esempio n. 4
0
  /**
   * for AlgebraView changes in the tree selection and redefine dialog
   *
   * @return changed geo
   */
  public GeoElement changeGeoElementNoExceptionHandling(
      GeoElement geo, ValidExpression newValue, boolean redefineIndependent, boolean storeUndoInfo)
      throws Exception {
    String oldLabel, newLabel;
    GeoElement[] result;

    try {
      oldLabel = geo.getLabel();
      newLabel = newValue.getLabel();

      if (newLabel == null) {
        newLabel = oldLabel;
        newValue.setLabel(newLabel);
      }

      // make sure that points stay points and vectors stay vectors
      if (newValue instanceof ExpressionNode) {
        ExpressionNode n = (ExpressionNode) newValue;
        if (geo.isGeoPoint()) n.setForcePoint();
        else if (geo.isGeoVector()) n.setForceVector();
        else if (geo.isGeoFunction()) n.setForceFunction();
      }

      if (newLabel.equals(oldLabel)) {
        // try to overwrite
        result = processValidExpression(newValue, redefineIndependent);
        if (result != null && storeUndoInfo) app.storeUndoInfo();
        return result[0];
      } else if (cons.isFreeLabel(newLabel)) {
        newValue.setLabel(oldLabel);
        // rename to oldLabel to enable overwriting
        result = processValidExpression(newValue, redefineIndependent);
        result[0].setLabel(newLabel); // now we rename
        if (storeUndoInfo) app.storeUndoInfo();
        return result[0];
      } else {
        String str[] = {"NameUsed", newLabel};
        throw new MyError(app, str);
      }
    } catch (CircularDefinitionException e) {
      Application.debug("CircularDefinition");
      throw e;
    } catch (Exception e) {
      e.printStackTrace();
      throw new Exception(app.getError("InvalidInput") + ":\n" + newValue);
    } catch (MyError e) {
      e.printStackTrace();
      throw new Exception(e.getLocalizedMessage());
    } catch (Error e) {
      e.printStackTrace();
      throw new Exception(app.getError("InvalidInput") + ":\n" + newValue);
    }
  }
Esempio n. 5
0
  private GeoElement[] processText(ExpressionNode n, ExpressionValue evaluate) {
    GeoElement[] ret = new GeoElement[1];
    String label = n.getLabel();

    boolean isIndependent = n.isConstant();

    if (isIndependent) {
      MyStringBuffer eval = ((TextValue) evaluate).getText();
      ret[0] = kernel.Text(label, eval.toValueString());
    } else ret[0] = kernel.DependentText(label, n);
    return ret;
  }
Esempio n. 6
0
  private GeoElement[] processParametric(Parametric par) throws CircularDefinitionException {

    /*
    ExpressionValue temp = P.evaluate();
          if (!temp.isVectorValue()) {
              String [] str = { "VectorExpected", temp.toString() };
              throw new MyParseError(kernel.getApplication(), str);
          }

          v.resolveVariables();
          temp = v.evaluate();
          if (!(temp instanceof VectorValue)) {
              String [] str = { "VectorExpected", temp.toString() };
              throw new MyParseError(kernel.getApplication(), str);
          } */

    // point and vector are created silently
    boolean oldMacroMode = cons.isSuppressLabelsActive();
    cons.setSuppressLabelCreation(true);

    // get point
    ExpressionNode node = par.getP();
    node.setForcePoint();
    GeoElement[] temp = processExpressionNode(node);
    GeoPoint P = (GeoPoint) temp[0];

    //	get vector
    node = par.getv();
    node.setForceVector();
    temp = processExpressionNode(node);
    GeoVector v = (GeoVector) temp[0];

    // switch back to old mode
    cons.setSuppressLabelCreation(oldMacroMode);

    // Line through P with direction v
    GeoLine line;
    // independent line
    if (P.isConstant() && v.isConstant()) {
      line = new GeoLine(cons);
      line.setCoords(-v.y, v.x, v.y * P.inhomX - v.x * P.inhomY);
    }
    // dependent line
    else {
      line = kernel.Line(par.getLabel(), P, v);
    }
    line.setToParametric(par.getParameter());
    line.updateRepaint();
    GeoElement[] ret = {line};
    return ret;
  }
  // for AlgoElement
  protected void setInputOutput() {
    input = root.getGeoElementVariables();

    setOutputLength(1);
    setOutput(0, list);
    setDependencies(); // done by AlgoElement
  }
Esempio n. 8
0
  private GeoElement[] processList(ExpressionNode n, MyList evalList) {
    String label = n.getLabel();

    GeoElement[] ret = new GeoElement[1];

    // no operations or no variables are present, e.g.
    // { a, b, 7 } or  { 2, 3, 5 } + {1, 2, 4}
    if (!n.hasOperations() || n.isConstant()) {

      // PROCESS list items to generate a list of geoElements
      ArrayList<GeoElement> geoElements = new ArrayList<GeoElement>();
      boolean isIndependent = true;

      // make sure we don't create any labels for the list elements
      boolean oldMacroMode = cons.isSuppressLabelsActive();
      cons.setSuppressLabelCreation(true);

      int size = evalList.size();
      for (int i = 0; i < size; i++) {
        ExpressionNode en = (ExpressionNode) evalList.getListElement(i);
        // we only take one resulting object
        GeoElement[] results = processExpressionNode(en);
        GeoElement geo = results[0];

        // add to list
        geoElements.add(geo);
        if (geo.isLabelSet() || !geo.isIndependent()) isIndependent = false;
      }
      cons.setSuppressLabelCreation(oldMacroMode);

      // Create GeoList object
      ret[0] = kernel.List(label, geoElements, isIndependent);
    }

    // operations and variables are present
    // e.g. {3, 2, 1} + {a, b, 2}
    else {
      ret[0] = kernel.ListExpression(label, n);
    }

    return ret;
  }
Esempio n. 9
0
  /**
   * Parses given String str and tries to evaluate it to a GeoPoint. Returns null if something went
   * wrong.
   */
  public GeoPointND evaluateToPoint(String str, boolean showErrors) {
    boolean oldMacroMode = cons.isSuppressLabelsActive();
    cons.setSuppressLabelCreation(true);

    GeoPointND p = null;
    GeoElement[] temp = null;
    ;
    try {
      ValidExpression ve = parser.parseGeoGebraExpression(str);
      if (ve instanceof ExpressionNode) {
        ExpressionNode en = (ExpressionNode) ve;
        en.setForcePoint();
      }

      temp = processValidExpression(ve);
      p = (GeoPointND) temp[0];
    } catch (CircularDefinitionException e) {
      if (showErrors) {
        Application.debug("CircularDefinition");
        app.showError("CircularDefinition");
      }
    } catch (Exception e) {
      if (showErrors) {
        e.printStackTrace();
        app.showError("InvalidInput", str);
      }
    } catch (MyError e) {
      if (showErrors) {
        e.printStackTrace();
        app.showError(e);
      }
    } catch (Error e) {
      if (showErrors) {
        e.printStackTrace();
        app.showError("InvalidInput", str);
      }
    }

    cons.setSuppressLabelCreation(oldMacroMode);
    return p;
  }
Esempio n. 10
0
 /**
  * Parses given String str and tries to evaluate it to a double. Returns Double.NaN if something
  * went wrong.
  */
 public double evaluateToDouble(String str, boolean suppressErrors) {
   try {
     ValidExpression ve = parser.parseExpression(str);
     ExpressionNode en = (ExpressionNode) ve;
     en.resolveVariables();
     NumberValue nv = (NumberValue) en.evaluate();
     return nv.getDouble();
   } catch (Exception e) {
     e.printStackTrace();
     if (!suppressErrors) app.showError("InvalidInput", str);
     return Double.NaN;
   } catch (MyError e) {
     e.printStackTrace();
     if (!suppressErrors) app.showError(e);
     return Double.NaN;
   } catch (Error e) {
     e.printStackTrace();
     if (!suppressErrors) app.showError("InvalidInput", str);
     return Double.NaN;
   }
 }
Esempio n. 11
0
  private GeoElement[] processNumber(ExpressionNode n, ExpressionValue evaluate) {
    GeoElement[] ret = new GeoElement[1];
    String label = n.getLabel();
    boolean isIndependent = n.isConstant();
    MyDouble eval = ((NumberValue) evaluate).getNumber();
    boolean isAngle = eval.isAngle();
    double value = eval.getDouble();

    if (isIndependent) {
      if (isAngle) ret[0] = new GeoAngle(cons, label, value);
      else ret[0] = new GeoNumeric(cons, label, value);
    } else {
      ret[0] = kernel.DependentNumber(label, n, isAngle);
    }

    if (n.isForcedFunction()) {
      ret[0] = ((GeoFunctionable) (ret[0])).getGeoFunction();
    }

    return ret;
  }
Esempio n. 12
0
  private GeoElement[] processPointVector(ExpressionNode n, ExpressionValue evaluate) {
    String label = n.getLabel();

    GeoVec2D p = (GeoVec2D) ((VectorValue) evaluate).getVector();

    boolean polar = p.getMode() == Kernel.COORD_POLAR;

    // we want z = 3 + i to give a (complex) GeoPoint not a GeoVector
    boolean complex = p.getMode() == Kernel.COORD_COMPLEX;

    GeoVec3D[] ret = new GeoVec3D[1];
    boolean isIndependent = n.isConstant();

    // make point if complex parts are present, e.g. 3 + i
    if (complex) {
      n.setForcePoint();
    }
    // make vector, if label begins with lowercase character
    else if (label != null) {
      if (!(n.isForcedPoint() || n.isForcedVector())) { // may be set by MyXMLHandler
        if (Character.isLowerCase(label.charAt(0))) n.setForceVector();
        else n.setForcePoint();
      }
    }
    boolean isVector = n.isVectorValue();

    if (isIndependent) {
      // get coords
      double x = p.getX();
      double y = p.getY();
      if (isVector) ret[0] = kernel.Vector(label, x, y);
      else ret[0] = kernel.Point(label, x, y, complex);
    } else {
      if (isVector) ret[0] = kernel.DependentVector(label, n);
      else ret[0] = kernel.DependentPoint(label, n, complex);
    }
    if (polar) {
      ret[0].setMode(Kernel.COORD_POLAR);
      ret[0].updateRepaint();
    } else if (complex) {
      ret[0].setMode(Kernel.COORD_COMPLEX);
      ret[0].updateRepaint();
    }
    return ret;
  }
  // evaluate the current value of the arithmetic tree
  protected final void compute() {
    // get resulting list of ExpressionNodes
    ExpressionValue evlist = root.evaluate();
    MyList myList = (evlist instanceof MyList) ? (MyList) evlist : ((GeoList) evlist).getMyList();

    int evalListSize = myList.size();
    int cachedListSize = list.getCacheSize();

    list.clear();
    for (int i = 0; i < evalListSize; i++) {
      ExpressionValue element = myList.getListElement(i).evaluate();
      GeoElement geo = null;

      // number result
      if (element.isNumberValue()) {
        double val = ((NumberValue) element).getDouble();

        // try to use cached element of same type
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a number: set value
          if (cachedGeo.isGeoNumeric()) {
            ((GeoNumeric) cachedGeo).setValue(val);
            geo = cachedGeo;
          }
        }

        // no cached number: create new one
        if (geo == null) {
          geo = new GeoNumeric(cons, val);
        }

        // add number to list
        list.add(geo);
      }

      // point
      else if (element.isVectorValue()) {
        GeoVec2D vec = ((VectorValue) element).getVector();

        // try to use cached element of same type
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a point: set value
          if (cachedGeo.isGeoPoint()) {
            ((GeoPoint) cachedGeo).setCoords(vec);
            geo = cachedGeo;
          }
        }

        // no cached point: create new one
        if (geo == null) {
          GeoPoint point = new GeoPoint(cons);
          point.setCoords(vec);
          geo = point;
        }

        // add point to list
        list.add(geo);
      }

      // needed for matrix multiplication
      // eg {{1,3,5},{2,4,6}}*{{11,14},{12,15},{13,a}}
      else if (element instanceof MyList) {
        MyList myList2 = (MyList) element;
        GeoList list2 = new GeoList(cons);
        list2.clear();

        /* removed Michael Borcherds 20080602
         * bug: 9PointCubic.ggb (matrix multiplication)
        // try to use cached element of  type GeoList
        GeoList list2 = null;
        if (i < cachedListSize) {
        	GeoElement cachedGeo = list.getCached(i);

        	// the cached element is a number: set value
        	if (cachedGeo.isGeoList()) {
        		list2 = (GeoList) cachedGeo;
        	}
        }

        if (list2 == null) {
        	list2 = new GeoList(cons);
        } */

        for (int j = 0; j < myList2.size(); j++) {
          ExpressionValue en = myList2.getListElement(j);
          ExpressionValue ev = en.evaluate();

          if (ev instanceof MyDouble) {
            GeoNumeric geo2 = new GeoNumeric(cons);
            geo2.setValue(((NumberValue) ev).getDouble());
            list2.add(geo2);
          }
        }

        list.add(list2);
      } else if (element instanceof MyStringBuffer) {
        MyStringBuffer str = (MyStringBuffer) element;
        // try to use cached element of same type
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a point: set value
          if (cachedGeo.isGeoText()) {
            ((GeoText) cachedGeo).setTextString(str.toValueString());
            geo = cachedGeo;
          }
        }

        // no cached point: create new one
        if (geo == null) {
          GeoText text = new GeoText(cons);
          text.setTextString(str.toValueString());
          geo = text;
        }

        // add point to list
        list.add(geo);
      } else if (element instanceof MyBoolean) {
        MyBoolean bool = (MyBoolean) element;
        // try to use cached element of same type
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a point: set value
          if (cachedGeo.isGeoBoolean()) {
            ((GeoBoolean) cachedGeo).setValue(bool.getBoolean());
            geo = cachedGeo;
          }
        }

        // no cached point: create new one
        if (geo == null) {
          GeoBoolean geoBool = new GeoBoolean(cons);
          geoBool.setValue(bool.getBoolean());
          geo = geoBool;
        }

        // add point to list
        list.add(geo);
      } else if (element instanceof GeoFunction) {
        GeoFunction fun = (GeoFunction) element;
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a point: set value
          if (cachedGeo.isGeoFunction()) {
            ((GeoFunction) cachedGeo).set(fun);
            geo = cachedGeo;
          }
        }

        // no cached point: create new one
        if (geo == null) {
          GeoFunction geoFun = new GeoFunction(cons);
          geoFun.set(fun);
          geo = geoFun;
        }
        list.add(geo);

      } else {
        Application.debug("unsupported list addition: " + element.getClass() + "");
      }
    }
  }
 public final String toRealString() {
   // was defined as e.g.  L = 3 * {a, b, c}
   return root.toRealString();
 }
Esempio n. 15
0
  public GeoElement[] processExpressionNode(ExpressionNode n) throws MyError {
    // command is leaf: process command
    if (n.isLeaf()) {
      ExpressionValue leaf = n.getLeft();
      if (leaf instanceof Command) {
        Command c = (Command) leaf;
        c.setLabels(n.getLabels());
        return cmdDispatcher.processCommand(c, true);
      } else if (leaf instanceof Equation) {
        Equation eqn = (Equation) leaf;
        eqn.setLabels(n.getLabels());
        return processEquation(eqn);
      } else if (leaf instanceof Function) {
        Function fun = (Function) leaf;
        fun.setLabels(n.getLabels());
        return processFunction(n, fun);
      } else if (leaf instanceof FunctionNVar) {
        FunctionNVar fun = (FunctionNVar) leaf;
        fun.setLabels(n.getLabels());
        return processFunctionNVar(n, fun);
      }
    }

    // ELSE:  resolve variables and evaluate expressionnode
    n.resolveVariables();
    eval = n.evaluate();
    boolean dollarLabelFound = false;

    ExpressionNode myNode = n;
    if (myNode.isLeaf()) myNode = myNode.getLeftTree();
    // leaf (no new label specified): just return the existing GeoElement
    if (eval.isGeoElement()
        && n.getLabel() == null
        && !(n.operation.equals(Operation.ELEMENT_OF))) {
      // take care of spreadsheet $ names: don't loose the wrapper ExpressionNode here
      // check if we have a Variable
      switch (myNode.getOperation()) {
        case $VAR_COL:
        case $VAR_ROW:
        case $VAR_ROW_COL:
          // don't do anything here: we need to keep the wrapper ExpressionNode
          // and must not return the GeoElement here
          dollarLabelFound = true;
          break;

        default:
          // return the GeoElement
          GeoElement[] ret = {(GeoElement) eval};
          return ret;
      }
    }

    if (eval.isBooleanValue()) return processBoolean(n, eval);
    else if (eval.isNumberValue()) return processNumber(n, eval);
    else if (eval.isVectorValue()) return processPointVector(n, eval);
    else if (eval.isVector3DValue()) return processPointVector3D(n, eval);
    else if (eval.isTextValue()) return processText(n, eval);
    else if (eval instanceof MyList) {
      return processList(n, (MyList) eval);
    } else if (eval instanceof Function) {
      return processFunction(n, (Function) eval);
    } else if (eval instanceof FunctionNVar) {

      return processFunctionNVar(n, (FunctionNVar) eval);
    }
    // we have to process list in case list=matrix1(1), but not when list=list2
    else if (eval instanceof GeoList && myNode.hasOperations()) {
      Application.debug("should work");
      return processList(n, ((GeoList) eval).getMyList());
    } else if (eval.isGeoElement()) {

      // e.g. B1 = A1 where A1 is a GeoElement and B1 does not exist yet
      // create a copy of A1
      if (n.getLabel() != null || dollarLabelFound) {
        return processGeoCopy(n.getLabel(), n);
      }
    }

    // REMOVED due to issue 131: http://code.google.com/p/geogebra/issues/detail?id=131
    //		// expressions like 2 a (where a:x + y = 1)
    //		// A1=b doesn't work for these objects
    //		else if (eval instanceof GeoLine) {
    //			if (((GeoLine)eval).getParentAlgorithm() instanceof AlgoDependentLine) {
    //				GeoElement[] ret = {(GeoElement) eval };
    //				return ret;
    //			}
    //
    //		}

    // if we get here, nothing worked
    Application.debug("Unhandled ExpressionNode: " + eval + ", " + eval.getClass());
    return null;
  }