예제 #1
0
  public GeoElement[] processFunction(ExpressionNode funNode, Function fun) {
    fun.initFunction();

    String label = fun.getLabel();
    GeoFunction f;
    GeoElement[] ret = new GeoElement[1];

    GeoElement[] vars = fun.getGeoElementVariables();
    boolean isIndependent = (vars == null || vars.length == 0);

    // check for interval

    ExpressionNode en = fun.getExpression();
    if (en.operation.equals(Operation.AND)) {
      ExpressionValue left = en.left;
      ExpressionValue right = en.right;

      if (left.isExpressionNode() && right.isExpressionNode()) {
        ExpressionNode enLeft = (ExpressionNode) left;
        ExpressionNode enRight = (ExpressionNode) right;

        Operation opLeft = enLeft.operation;
        Operation opRight = enRight.operation;

        ExpressionValue leftLeft = enLeft.left;
        ExpressionValue leftRight = enLeft.right;
        ExpressionValue rightLeft = enRight.left;
        ExpressionValue rightRight = enRight.right;

        // directions of inequalities, need one + and one - for an interval
        int leftDir = 0;
        int rightDir = 0;

        if ((opLeft.equals(Operation.LESS) || opLeft.equals(Operation.LESS_EQUAL))) {
          if (leftLeft instanceof FunctionVariable && leftRight.isNumberValue()) leftDir = -1;
          else if (leftRight instanceof FunctionVariable && leftLeft.isNumberValue()) leftDir = +1;

        } else if ((opLeft.equals(Operation.GREATER) || opLeft.equals(Operation.GREATER_EQUAL))) {
          if (leftLeft instanceof FunctionVariable && leftRight.isNumberValue()) leftDir = +1;
          else if (leftRight instanceof FunctionVariable && leftLeft.isNumberValue()) leftDir = -1;
        }

        if ((opRight.equals(Operation.LESS) || opRight.equals(Operation.LESS_EQUAL))) {
          if (rightLeft instanceof FunctionVariable && rightRight.isNumberValue()) rightDir = -1;
          else if (rightRight instanceof FunctionVariable && rightLeft.isNumberValue())
            rightDir = +1;

        } else if ((opRight.equals(Operation.GREATER) || opRight.equals(Operation.GREATER_EQUAL))) {
          if (rightLeft instanceof FunctionVariable && rightRight.isNumberValue()) rightDir = +1;
          else if (rightRight instanceof FunctionVariable && rightLeft.isNumberValue())
            rightDir = -1;
        }

        // Application.debug(leftDir+" "+rightDir);
        // Application.debug(leftLeft.getClass()+" "+leftRight.getClass());
        // Application.debug(rightLeft.getClass()+" "+rightRight.getClass());

        // opposite directions -> OK
        if (leftDir * rightDir < 0) {
          if (isIndependent) {
            f = kernel.Interval(label, fun);
          } else {
            f = kernel.DependentInterval(label, fun);
          }
          ret[0] = f;
          return ret;
        }

        // Application.debug(enLeft.operation+"");
        // Application.debug(enLeft.left.getClass()+"");
        // Application.debug(enLeft.right.getClass()+"");

      }
      // Application.debug(left.getClass()+"");
      // Application.debug(right.getClass()+"");
      // Application.debug("");
    } else if (en.operation.equals(Operation.FUNCTION)) {
      ExpressionValue left = en.left;
      ExpressionValue right = en.right;
      if (left.isLeaf()
          && left.isGeoElement()
          && right.isLeaf()
          && right.isNumberValue()
          && !isIndependent) {
        f = (GeoFunction) kernel.DependentGeoCopy(label, (GeoElement) left);
        ret[0] = f;
        return ret;
      }
    }

    if (isIndependent) {
      f = kernel.Function(label, fun);
    } else {
      f = kernel.DependentFunction(label, fun);
    }
    ret[0] = f;
    return ret;
  }
예제 #2
0
  public GeoElement[] processEquation(Equation equ) throws MyError {
    //		Application.debug("EQUATION: " + equ);
    //		Application.debug("NORMALFORM POLYNOMIAL: " + equ.getNormalForm());

    try {
      equ.initEquation();
      // Application.debug("EQUATION: " + equ.getNormalForm());
      // check no terms in z
      checkNoTermsInZ(equ);

      if (equ.isFunctionDependent()) {
        return processImplicitPoly(equ);
      }

      // consider algebraic degree of equation
      // check not equation of eg plane
      switch (equ.degree()) {
          // linear equation -> LINE
        case 1:
          return processLine(equ, false);

          // quadratic equation -> CONIC
        case 2:
          return processConic(equ);

        default:
          // test for "y= <rhs>" here as well
          if (equ.getLHS().toString().trim().equals("y")) {
            Function fun = new Function(equ.getRHS());
            // try to use label of equation
            fun.setLabel(equ.getLabel());
            return processFunction(null, fun);
          }
          return processImplicitPoly(equ);
      }
    } catch (MyError eqnError) {
      eqnError.printStackTrace();

      // invalid equation: maybe a function of form "y = <rhs>"?
      String lhsStr = equ.getLHS().toString().trim();
      if (lhsStr.equals("y")) {
        try {
          // try to create function from right hand side
          Function fun = new Function(equ.getRHS());

          // try to use label of equation
          fun.setLabel(equ.getLabel());
          return processFunction(null, fun);
        } catch (MyError funError) {
          funError.printStackTrace();
        }
      }

      // throw invalid equation error if we get here
      if (eqnError.getMessage() == "InvalidEquation") throw eqnError;
      else {
        String[] errors = {"InvalidEquation", eqnError.getLocalizedMessage()};
        throw new MyError(app, errors);
      }
    }
  }
예제 #3
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;
  }