Ejemplo n.º 1
0
  // replace every x in tree by (x - vx)
  // i.e. replace fVar with (fvar - vx)
  private void translateX(ExpressionNode en, double vx, int varNo) {
    ExpressionValue left = en.getLeft();
    ExpressionValue right = en.getRight();

    // left tree
    if (left == fVars[varNo]) {
      try { // is there a constant number to the right?
        MyDouble num = (MyDouble) right;
        double temp;
        switch (en.getOperation()) {
          case ExpressionNode.PLUS:
            temp = num.getDouble() - vx;
            if (Kernel.isZero(temp)) {
              expression = expression.replaceAndWrap(en, fVars[varNo]);
            } else if (temp < 0) {
              en.setOperation(ExpressionNode.MINUS);
              num.set(-temp);
            } else {
              num.set(temp);
            }
            return;

          case ExpressionNode.MINUS:
            temp = num.getDouble() + vx;
            if (Kernel.isZero(temp)) {
              expression = expression.replaceAndWrap(en, fVars[varNo]);
            } else if (temp < 0) {
              en.setOperation(ExpressionNode.PLUS);
              num.set(-temp);
            } else {
              num.set(temp);
            }
            return;

          default:
            en.setLeft(shiftXnode(vx, varNo));
        }
      } catch (Exception e) {
        en.setLeft(shiftXnode(vx, varNo));
      }
    } else if (left instanceof ExpressionNode) {
      translateX((ExpressionNode) left, vx, varNo);
    }

    // right tree
    if (right == fVars[varNo]) {
      en.setRight(shiftXnode(vx, varNo));
    } else if (right instanceof ExpressionNode) {
      translateX((ExpressionNode) right, vx, varNo);
    }
  }
Ejemplo n.º 2
0
  public GgbVector getCartesianEquationVector(GgbMatrix m) {
    GgbVector origin = getCoordSys().getOrigin();
    GgbVector direction = getCoordSys().getVx();

    // TODO generalize it to other planes than xOy

    // if lines is not in the plane, return null
    if (!Kernel.isZero(origin.getZ()) || !Kernel.isZero(direction.getZ())) return null;

    double x = -direction.getY();
    double y = direction.getX();
    double z = -x * origin.getX() - y * origin.getY();

    return new GgbVector(x, y, z);
  }
Ejemplo n.º 3
0
  public void translate(double vx, double vy) {

    // translate x
    if (!Kernel.isZero(vx)) {
      translateX(expression, vx, 0);
    }
    if (!Kernel.isZero(vy)) {
      translateX(expression, vy, 1);
    }

    // make sure that expression object is changed!
    // this is needed to know that the expression has changed
    if (expression.isLeaf() && expression.getLeft().isExpressionNode()) {
      expression = new ExpressionNode((ExpressionNode) expression.getLeft());
    } else {
      expression = new ExpressionNode(expression);
    }
  }
Ejemplo n.º 4
0
  public final void update() {
    isVisible = geo.isEuclidianVisible();
    if (!isVisible) return;
    labelVisible = geo.isLabelVisible();
    updateStrokes(geo);

    Coords A = view.getCoordsForView(s.getStartInhomCoords());
    Coords B = view.getCoordsForView(s.getEndInhomCoords());

    // check if in view
    if (!Kernel.isZero(A.getZ()) || !Kernel.isZero(B.getZ())) {
      isVisible = false;
      return;
    }

    /*
    if (s.getEndPoint().getLabel().equals("S3'"))
    	Application.debug("start=\n"+s.getStartInhomCoords()+"\nA=\n"+A);
    	*/

    coordsA[0] = A.getX();
    coordsA[1] = A.getY();
    coordsB[0] = B.getX();
    coordsB[1] = B.getY();

    boolean onscreenA = view.toScreenCoords(coordsA);
    boolean onscreenB = view.toScreenCoords(coordsB);

    if (line == null) line = new Line2D.Double();

    if (onscreenA && onscreenB) {
      // A and B on screen
      line.setLine(coordsA[0], coordsA[1], coordsB[0], coordsB[1]);
    } else {
      // A or B off screen
      // clip at screen, that's important for huge coordinates
      Point2D.Double[] clippedPoints =
          ClipLine.getClipped(
              coordsA[0],
              coordsA[1],
              coordsB[0],
              coordsB[1],
              -EuclidianView.CLIP_DISTANCE,
              view.width + EuclidianView.CLIP_DISTANCE,
              -EuclidianView.CLIP_DISTANCE,
              view.height + EuclidianView.CLIP_DISTANCE);
      if (clippedPoints == null) {
        isVisible = false;
      } else {
        line.setLine(
            clippedPoints[0].x, clippedPoints[0].y, clippedPoints[1].x, clippedPoints[1].y);
      }
    }

    // draw trace
    if (s.getTrace()) {
      isTracing = true;
      Graphics2D g2 = view.getBackgroundGraphics();
      if (g2 != null) drawTrace(g2);
    } else {
      if (isTracing) {
        isTracing = false;
        view.updateBackground();
      }
    }

    // if no label and no decoration then we're done
    if (!labelVisible && geo.decorationType == GeoElement.DECORATION_NONE) return;

    // calc midpoint (midX, midY) and perpendicular vector (nx, ny)
    double midX = (coordsA[0] + coordsB[0]) / 2.0;
    double midY = (coordsA[1] + coordsB[1]) / 2.0;
    double nx = coordsA[1] - coordsB[1];
    double ny = coordsB[0] - coordsA[0];
    double nLength = GeoVec2D.length(nx, ny);

    // label position
    // use unit perpendicular vector to move away from line
    if (labelVisible) {
      labelDesc = geo.getLabelDescription();
      if (nLength > 0.0) {
        xLabel = (int) (midX + nx * 16 / nLength);
        yLabel = (int) (midY + ny * 16 / nLength);
      } else {
        xLabel = (int) midX;
        yLabel = (int) (midY + 16);
      }
      addLabelOffset();
    }

    // update decoration
    // added by Lo�c and Markus BEGIN,
    if (geo.decorationType != GeoElement.DECORATION_NONE && nLength > 0) {
      if (decoTicks == null) {
        // only create these object when they are really needed
        decoTicks = new Line2D.Double[6]; // Michael Borcherds 20071006 changed from 3 to 6
        for (int i = 0; i < decoTicks.length; i++) decoTicks[i] = new Line2D.Double();
      }

      // tick spacing and length.
      double tickSpacing = 2.5 + geo.lineThickness / 2d;
      double tickLength = tickSpacing + 1;
      //			 Michael Borcherds 20071006 start
      double arrowlength = 1.5;
      //			 Michael Borcherds 20071006 end
      double vx, vy, factor;

      switch (geo.decorationType) {
        case GeoElement.DECORATION_SEGMENT_ONE_TICK:
          // use perpendicular vector to set tick
          factor = tickLength / nLength;
          nx *= factor;
          ny *= factor;
          decoTicks[0].setLine(midX - nx, midY - ny, midX + nx, midY + ny);
          break;

        case GeoElement.DECORATION_SEGMENT_TWO_TICKS:
          // vector (vx, vy) to get 2 points around midpoint
          factor = tickSpacing / (2 * nLength);
          vx = -ny * factor;
          vy = nx * factor;
          // use perpendicular vector to set ticks
          factor = tickLength / nLength;
          nx *= factor;
          ny *= factor;
          decoTicks[0].setLine(midX + vx - nx, midY + vy - ny, midX + vx + nx, midY + vy + ny);
          decoTicks[1].setLine(midX - vx - nx, midY - vy - ny, midX - vx + nx, midY - vy + ny);
          break;

        case GeoElement.DECORATION_SEGMENT_THREE_TICKS:
          // vector (vx, vy) to get 2 points around midpoint
          factor = tickSpacing / nLength;
          vx = -ny * factor;
          vy = nx * factor;
          // use perpendicular vector to set ticks
          factor = tickLength / nLength;
          nx *= factor;
          ny *= factor;
          decoTicks[0].setLine(midX + vx - nx, midY + vy - ny, midX + vx + nx, midY + vy + ny);
          decoTicks[1].setLine(midX - nx, midY - ny, midX + nx, midY + ny);
          decoTicks[2].setLine(midX - vx - nx, midY - vy - ny, midX - vx + nx, midY - vy + ny);
          break;
          //		 	 Michael Borcherds 20071006 start
        case GeoElement.DECORATION_SEGMENT_ONE_ARROW:
          // vector (vx, vy) to get 2 points around midpoint
          factor = tickSpacing / (1.5 * nLength);
          vx = -ny * factor;
          vy = nx * factor;
          // use perpendicular vector to set tick
          factor = tickLength / (1.5 * nLength);
          nx *= factor;
          ny *= factor;
          decoTicks[0].setLine(
              midX - arrowlength * vx,
              midY - arrowlength * vy,
              midX - arrowlength * vx + arrowlength * (nx + vx),
              midY - arrowlength * vy + arrowlength * (ny + vy));
          decoTicks[1].setLine(
              midX - arrowlength * vx,
              midY - arrowlength * vy,
              midX - arrowlength * vx + arrowlength * (-nx + vx),
              midY - arrowlength * vy + arrowlength * (-ny + vy));
          break;

        case GeoElement.DECORATION_SEGMENT_TWO_ARROWS:
          // vector (vx, vy) to get 2 points around midpoint
          factor = tickSpacing / (1.5 * nLength);
          vx = -ny * factor;
          vy = nx * factor;
          // use perpendicular vector to set ticks
          factor = tickLength / (1.5 * nLength);
          nx *= factor;
          ny *= factor;
          decoTicks[0].setLine(
              midX - 2 * arrowlength * vx,
              midY - 2 * arrowlength * vy,
              midX - 2 * arrowlength * vx + arrowlength * (nx + vx),
              midY - 2 * arrowlength * vy + arrowlength * (ny + vy));
          decoTicks[1].setLine(
              midX - 2 * arrowlength * vx,
              midY - 2 * arrowlength * vy,
              midX - 2 * arrowlength * vx + arrowlength * (-nx + vx),
              midY - 2 * arrowlength * vy + arrowlength * (-ny + vy));

          decoTicks[2].setLine(
              midX, midY, midX + arrowlength * (nx + vx), midY + arrowlength * (ny + vy));
          decoTicks[3].setLine(
              midX, midY, midX + arrowlength * (-nx + vx), midY + arrowlength * (-ny + vy));
          break;

        case GeoElement.DECORATION_SEGMENT_THREE_ARROWS:
          // vector (vx, vy) to get 2 points around midpoint
          factor = tickSpacing / (1.5 * nLength);
          vx = -ny * factor;
          vy = nx * factor;
          // use perpendicular vector to set ticks
          factor = tickLength / (1.5 * nLength);
          nx *= factor;
          ny *= factor;
          decoTicks[0].setLine(
              midX - arrowlength * vx,
              midY - arrowlength * vy,
              midX - arrowlength * vx + arrowlength * (nx + vx),
              midY - arrowlength * vy + arrowlength * (ny + vy));
          decoTicks[1].setLine(
              midX - arrowlength * vx,
              midY - arrowlength * vy,
              midX - arrowlength * vx + arrowlength * (-nx + vx),
              midY - arrowlength * vy + arrowlength * (-ny + vy));

          decoTicks[2].setLine(
              midX + arrowlength * vx,
              midY + arrowlength * vy,
              midX + arrowlength * vx + arrowlength * (nx + vx),
              midY + arrowlength * vy + arrowlength * (ny + vy));
          decoTicks[3].setLine(
              midX + arrowlength * vx,
              midY + arrowlength * vy,
              midX + arrowlength * vx + arrowlength * (-nx + vx),
              midY + arrowlength * vy + arrowlength * (-ny + vy));

          decoTicks[4].setLine(
              midX - 3 * arrowlength * vx,
              midY - 3 * arrowlength * vy,
              midX - 3 * arrowlength * vx + arrowlength * (nx + vx),
              midY - 3 * arrowlength * vy + arrowlength * (ny + vy));
          decoTicks[5].setLine(
              midX - 3 * arrowlength * vx,
              midY - 3 * arrowlength * vy,
              midX - 3 * arrowlength * vx + arrowlength * (-nx + vx),
              midY - 3 * arrowlength * vy + arrowlength * (-ny + vy));
          break;
          //		 	 Michael Borcherds 20071006 end
      }
    }
  }