示例#1
0
 private void drawSphere(PlotterSurface surface, Coords center, double radius) {
   if (visible == Visible.CENTER_OUTSIDE) {
     int longitudeAlpha = 8;
     while (longitudeAlpha * Math.PI < alpha * longitude) {
       longitudeAlpha *= 2;
     }
     // App.debug(longitudeAlpha+"");
     surface.drawSphere(
         center, radius, longitude, beta - longitudeAlpha * Math.PI / longitude, longitudeAlpha);
   } else {
     surface.drawSphere(center, radius, longitude);
   }
 }
示例#2
0
  /**
   * update the geometry
   *
   * @return true
   */
  protected boolean updateGeometry() {

    Renderer renderer = getView3D().getRenderer();
    GeoPlane3D geo = (GeoPlane3D) getGeoElement();
    CoordSys coordsys = geo.getCoordSys();

    float xmin1 = (float) geo.getXmin(), xmax1 = (float) geo.getXmax(), xdelta1 = xmax1 - xmin1;
    float ymin1 = (float) geo.getYmin(), ymax1 = (float) geo.getYmax(), ydelta1 = ymax1 - ymin1;

    // plane
    PlotterSurface surface = renderer.getGeometryManager().getSurface();

    surface.start(geo, getReusableSurfaceIndex());

    surface.setU(xmin1, xmax1);
    surface.setNbU(2);
    surface.setV(ymin1, ymax1);
    surface.setNbV(2);

    if (!getView3D().useClippingCube()) {
      float fading;
      fading = xdelta1 * geo.getFading();
      surface.setUFading(fading, fading);
      fading = ydelta1 * geo.getFading();
      surface.setVFading(fading, fading);
    }
    surface.draw();
    setSurfaceIndex(surface.end());

    // grid
    if (isGridVisible()) {

      PlotterBrush brush = renderer.getGeometryManager().getBrush();

      if (hasTrace()) {
        brush.start(-1);
      } else {
        brush.start(gridIndex);
      }
      removeGeometryIndex(gridIndex);
      float thickness =
          brush.setThickness(getGeoElement().getLineThickness(), (float) getView3D().getScale());

      brush.setColor(getGeoElement().getObjectColor());

      double dx = geo.getGridXd();
      geo.getGridYd();
      double dy;
      if (Double.isNaN(dx)) {
        dx = getView3D().getNumbersDistance();
        dy = dx;
      } else {
        dy = geo.getGridYd();
      }

      brush.setAffineTexture((0f - xmin1) / ydelta1, 0.25f);
      int i0 = (int) (ymin1 / dy);
      if (ymin1 > 0) i0++;
      for (int i = i0; i <= ymax1 / dy; i++)
        brush.segment(
            coordsys.getPointForDrawing(xmin1, i * dy), coordsys.getPointForDrawing(xmax1, i * dy));
      // along y axis
      brush.setAffineTexture((0f - ymin1) / xdelta1, 0.25f);
      i0 = (int) (xmin1 / dx);
      if (xmin1 > 0) i0++;
      for (int i = i0; i <= xmax1 / dx; i++)
        brush.segment(
            coordsys.getPointForDrawing(i * dx, ymin1), coordsys.getPointForDrawing(i * dx, ymax1));

      gridIndex = brush.end();

      brush.start(gridOutlineIndex);
      removeGeometryIndex(gridOutlineIndex);

      boolean showClippingCube = getView3D().showClippingCube();

      // draws the rectangle outline
      if (showClippingCube) {
        brush.setAffineTexture((0f - xmin1) / ydelta1, 0.25f);
      } else brush.setPlainTexture();
      brush.segment(
          coordsys.getPointForDrawing(xmin1, ymax1 - thickness),
          coordsys.getPointForDrawing(xmax1, ymax1 - thickness));
      brush.segment(
          coordsys.getPointForDrawing(xmin1, ymin1 + thickness),
          coordsys.getPointForDrawing(xmax1, ymin1 + thickness));

      if (showClippingCube) {
        brush.setAffineTexture((0f - ymin1) / xdelta1, 0.25f);
      }
      brush.segment(
          coordsys.getPointForDrawing(xmin1 + thickness, ymin1),
          coordsys.getPointForDrawing(xmin1 + thickness, ymax1));
      brush.segment(
          coordsys.getPointForDrawing(xmax1 - thickness, ymin1),
          coordsys.getPointForDrawing(xmax1 - thickness, ymax1));

      gridOutlineIndex = brush.end();
    }

    return true;
  }
示例#3
0
  @Override
  protected void updateForView() {

    GeoQuadric3D quadric = (GeoQuadric3D) getGeoElement();
    int type = quadric.getType();

    switch (type) {
      case GeoQuadricNDConstants.QUADRIC_SPHERE:
        if (getView3D().viewChangedByZoom()) {
          Renderer renderer = getView3D().getRenderer();
          PlotterSurface surface = renderer.getGeometryManager().getSurface();

          double s = scale;
          scale = getView3D().getScale();
          // check if longitude length changes
          double radius = quadric.getHalfAxis(0);
          int l = surface.calcSphereLongitudesNeeded(radius, scale);
          // redraw if sphere was not visible, or if new longitude length,
          // or if negative zoom occured
          if (visible == Visible.TOTALLY_OUTSIDE || l != longitude || scale < s) {
            Coords center = quadric.getMidpoint3D();
            checkSphereVisible(center, radius);
            if (visible != Visible.TOTALLY_OUTSIDE) {
              // App.debug(l+","+longitude);
              longitude = l;
              surface.start(getReusableSurfaceIndex());
              drawSphere(surface, center, radius);
              setSurfaceIndex(surface.end());
              recordTrace();
            } else {
              setSurfaceIndex(-1);
            }
          }
        } else if (visible != Visible.TOTALLY_INSIDE && getView3D().viewChangedByTranslate()) {
          Renderer renderer = getView3D().getRenderer();
          PlotterSurface surface = renderer.getGeometryManager().getSurface();

          Coords center = quadric.getMidpoint3D();
          double radius = quadric.getHalfAxis(0);
          checkSphereVisible(center, radius);
          if (visible != Visible.TOTALLY_OUTSIDE) {
            surface.start(getReusableSurfaceIndex());
            drawSphere(surface, center, radius);
            setSurfaceIndex(surface.end());
            recordTrace();
          } else {
            setSurfaceIndex(-1);
          }
        }
        break;
      case GeoQuadricNDConstants.QUADRIC_ELLIPSOID:
      case GeoQuadricNDConstants.QUADRIC_CONE:
      case GeoQuadricNDConstants.QUADRIC_CYLINDER:
      case GeoQuadricNDConstants.QUADRIC_HYPERBOLOID_ONE_SHEET:
      case GeoQuadricNDConstants.QUADRIC_HYPERBOLOID_TWO_SHEETS:
      case GeoQuadricNDConstants.QUADRIC_PARABOLOID:
      case GeoQuadricNDConstants.QUADRIC_HYPERBOLIC_PARABOLOID:
      case GeoQuadricNDConstants.QUADRIC_PARABOLIC_CYLINDER:
      case GeoQuadricNDConstants.QUADRIC_HYPERBOLIC_CYLINDER:
      case GeoQuadricNDConstants.QUADRIC_SINGLE_POINT:
        if (getView3D().viewChangedByZoom() || getView3D().viewChangedByTranslate()) {
          updateForItSelf();
        }
        break;
      case GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES:
      case GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES:
        if (getView3D().viewChanged()) {
          initDrawPlanes(quadric);
          drawPlanes[0].updateForView();
          drawPlanes[1].updateForView();
          super.setWaitForUpdate();
        }
        break;

      case GeoQuadricNDConstants.QUADRIC_PLANE:
        if (getView3D().viewChanged()) {
          initDrawPlanes(quadric);
          drawPlanes[0].updateForView();
          super.setWaitForUpdate();
        }
        break;

      case GeoQuadricNDConstants.QUADRIC_LINE:
        if (getView3D().viewChanged()) {
          initDrawLine(quadric);
          drawLine.updateForView();
          super.setWaitForUpdate();
        }
        break;
    }
  }
示例#4
0
  protected void setSurfaceV(float min, float max, PlotterSurface surface) {
    float fade = (max - min) / 10f;

    switch (((GeoQuadric3D) getGeoElement()).getType()) {
      case GeoQuadricNDConstants.QUADRIC_CYLINDER:
        surface.setV(min, max);
        surface.setNbV(3);
        surface.setVFading(fade, fade);
        break;

      case GeoQuadricNDConstants.QUADRIC_CONE:
        if (min * max < 0) {
          surface.setV(min, 0);
          surface.setNbV(2);
          surface.setVFading(fade, 0);
          surface.draw();
          surface.setV(0, max);
          surface.setNbV(2);
          surface.setVFading(0, fade);
          surface.draw();
        } else {
          surface.setV(min, max);
          surface.setNbV(3);
          surface.setVFading(fade, fade);
          surface.draw();
        }
        break;
    }
  }
示例#5
0
  @Override
  protected boolean updateForItSelf() {

    Renderer renderer = getView3D().getRenderer();
    GeoQuadric3D quadric = (GeoQuadric3D) getGeoElement();
    PlotterSurface surface;
    int type = quadric.getType();

    double min, max;

    switch (type) {
      case GeoQuadricNDConstants.QUADRIC_SPHERE:
        Coords center = quadric.getMidpoint3D();
        double radius = quadric.getHalfAxis(0);
        boundsMin.setValues(center, 3);
        boundsMax.setValues(center, 3);
        boundsMin.addInside(-radius);
        boundsMax.addInside(radius);
        checkSphereVisible(center, radius);
        if (visible != Visible.TOTALLY_OUTSIDE) {
          surface = renderer.getGeometryManager().getSurface();
          surface.start(getReusableSurfaceIndex());
          scale = getView3D().getScale();
          longitude = surface.calcSphereLongitudesNeeded(radius, scale);
          drawSphere(surface, center, radius);
          setSurfaceIndex(surface.end());
        } else {
          setSurfaceIndex(-1);
        }
        break;
      case GeoQuadricNDConstants.QUADRIC_ELLIPSOID:
        center = quadric.getMidpoint3D();
        double r0 = quadric.getHalfAxis(0);
        double r1 = quadric.getHalfAxis(1);
        double r2 = quadric.getHalfAxis(2);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        scale = getView3D().getScale();
        radius = Math.max(r0, Math.max(r1, r2));
        longitude = surface.calcSphereLongitudesNeeded(radius, scale);
        Coords ev0 = quadric.getEigenvec3D(0);
        Coords ev1 = quadric.getEigenvec3D(1);
        Coords ev2 = quadric.getEigenvec3D(2);
        surface.drawEllipsoid(center, ev0, ev1, ev2, r0, r1, r2, longitude);
        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_HYPERBOLOID_ONE_SHEET:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        r2 = quadric.getHalfAxis(2);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev2.mul(r2));
        scale = getView3D().getScale();
        // get radius at max
        radius =
            Math.max(r0, r1)
                * Math.max(Math.abs(vMinMax[0]), Math.max(Math.abs(vMinMax[1]), 1))
                / r2;
        longitude = surface.calcSphereLongitudesNeeded(radius, scale);
        min = DrawConic3D.asinh(vMinMax[0]);
        max = DrawConic3D.asinh(vMinMax[1]);
        surface.drawHyperboloidOneSheet(
            center, ev0, ev1, ev2, r0, r1, r2, longitude, min, max, !getView3D().useClippingCube());
        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_HYPERBOLOID_TWO_SHEETS:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        r2 = quadric.getHalfAxis(2);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev2.mul(r2));
        scale = getView3D().getScale();
        // get radius at max
        radius = Math.max(r0, r1) * Math.max(Math.abs(vMinMax[0]), Math.abs(vMinMax[1])) / r2;
        longitude = surface.calcSphereLongitudesNeeded(radius, scale);
        if (vMinMax[0] < -1) { // bottom exists
          min = -DrawConic3D.acosh(-vMinMax[0]);
        } else if (vMinMax[0] <= 1) { // top ends at pole
          min = 0;
        } else { // top pole is cut
          min = DrawConic3D.acosh(vMinMax[0]);
        }
        if (vMinMax[1] > 1) { // top exists
          max = DrawConic3D.acosh(vMinMax[1]);
        } else if (vMinMax[1] >= -1) { // bottom ends at pole
          max = 0;
        } else { // bottom pole is cut
          max = -DrawConic3D.acosh(-vMinMax[1]);
        }
        surface.drawHyperboloidTwoSheets(
            center, ev0, ev1, ev2, r0, r1, r2, longitude, min, max, !getView3D().useClippingCube());
        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_PARABOLOID:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (quadric.getHalfAxis(2) < 0) {
          ev0 = ev0.mul(-1);
          ev2 = ev2.mul(-1);
        }
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev2);
        if (vMinMax[1] < 0) {
          // nothing to draw
          setSurfaceIndex(surface.end());
        } else {
          scale = getView3D().getScale();
          // get radius at max
          if (vMinMax[0] <= 0) {
            vMinMax[0] = 0;
          } else {
            vMinMax[0] = Math.sqrt(vMinMax[0]);
          }
          vMinMax[1] = Math.sqrt(vMinMax[1]);
          radius = Math.max(r0, r1) * vMinMax[1];
          longitude = surface.calcSphereLongitudesNeeded(radius, scale);
          surface.drawParaboloid(
              center,
              ev0,
              ev1,
              ev2,
              r0,
              r1,
              longitude,
              vMinMax[0],
              vMinMax[1],
              !getView3D().useClippingCube());
          setSurfaceIndex(surface.end());
        }
        break;

      case GeoQuadricNDConstants.QUADRIC_HYPERBOLIC_PARABOLOID:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (uMinMax == null) {
          uMinMax = new double[2];
        }
        uMinMax[0] = Double.POSITIVE_INFINITY;
        uMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(uMinMax, center, ev0);
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev1);
        surface.drawHyperbolicParaboloid(
            center,
            ev0,
            ev1,
            ev2,
            r0,
            r1,
            uMinMax[0],
            uMinMax[1],
            vMinMax[0],
            vMinMax[1],
            !getView3D().useClippingCube());
        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_PARABOLIC_CYLINDER:
        center = quadric.getMidpoint3D();
        r2 = quadric.getHalfAxis(2);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (uMinMax == null) {
          uMinMax = new double[2];
        }
        uMinMax[0] = Double.POSITIVE_INFINITY;
        uMinMax[1] = Double.NEGATIVE_INFINITY;
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev0);
        if (vMinMax[1] < 0) {
          // nothing to draw
          setSurfaceIndex(surface.end());
        } else {
          scale = getView3D().getScale();
          // get radius at max
          if (vMinMax[0] <= 0) {
            vMinMax[0] = 0;
          } else {
            vMinMax[0] = Math.sqrt(vMinMax[0]);
          }
          vMinMax[1] = Math.sqrt(vMinMax[1]);
          getView3D().getMinIntervalOutsideClipping(uMinMax, center, ev1);
          surface.drawParabolicCylinder(
              center,
              ev0,
              ev1,
              ev2,
              r2,
              vMinMax[0],
              vMinMax[1],
              uMinMax[0],
              uMinMax[1],
              !getView3D().useClippingCube());
          setSurfaceIndex(surface.end());
        }
        break;

      case GeoQuadricNDConstants.QUADRIC_HYPERBOLIC_CYLINDER:
        center = quadric.getMidpoint3D();
        r0 = quadric.getHalfAxis(0);
        r1 = quadric.getHalfAxis(1);
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        ev0 = quadric.getEigenvec3D(0);
        ev1 = quadric.getEigenvec3D(1);
        ev2 = quadric.getEigenvec3D(2);
        if (uMinMax == null) {
          uMinMax = new double[2];
        }
        uMinMax[0] = Double.POSITIVE_INFINITY;
        uMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(uMinMax, center, ev0.mul(r0));
        scale = getView3D().getScale();
        if (uMinMax[0] < -1) { // bottom exists
          min = -DrawConic3D.acosh(-uMinMax[0]);
        } else if (uMinMax[0] <= 1) { // top ends at pole
          min = 0;
        } else { // top pole is cut
          min = DrawConic3D.acosh(uMinMax[0]);
        }
        if (uMinMax[1] > 1) { // top exists
          max = DrawConic3D.acosh(uMinMax[1]);
        } else if (uMinMax[1] >= -1) { // bottom ends at pole
          max = 0;
        } else { // bottom pole is cut
          max = -DrawConic3D.acosh(-uMinMax[1]);
        }
        if (vMinMax == null) {
          vMinMax = new double[2];
        }
        vMinMax[0] = Double.POSITIVE_INFINITY;
        vMinMax[1] = Double.NEGATIVE_INFINITY;
        getView3D().getMinIntervalOutsideClipping(vMinMax, center, ev2);
        if (min < 0) {
          surface.drawHyperbolicCylinder(
              center,
              ev0.mul(-1),
              ev1.mul(-1),
              ev2,
              r0,
              r1,
              -max,
              -min,
              vMinMax[0],
              vMinMax[1],
              !getView3D().useClippingCube());
        }
        if (max > 0) {
          surface.drawHyperbolicCylinder(
              center,
              ev0,
              ev1,
              ev2,
              r0,
              r1,
              min,
              max,
              vMinMax[0],
              vMinMax[1],
              !getView3D().useClippingCube());
        }
        uMinMax[0] = Math.sinh(min);
        uMinMax[1] = Math.sinh(max);
        setSurfaceIndex(surface.end());

        break;

      case GeoQuadricNDConstants.QUADRIC_CONE:
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        if (quadric instanceof GeoQuadric3DPart) { // simple cone
          double height =
              ((GeoQuadric3DPart) quadric).getBottomParameter()
                  - ((GeoQuadric3DPart) quadric).getTopParameter();
          Coords top = quadric.getMidpoint3D();
          ev1 = quadric.getEigenvec3D(0);
          ev2 = quadric.getEigenvec3D(1);
          radius = quadric.getHalfAxis(0);
          double radius2 = quadric.getHalfAxis(1);
          Coords bottomCenter =
              surface.cone(
                  top,
                  ev1,
                  ev2,
                  quadric.getEigenvec3D(2),
                  radius,
                  radius2,
                  0,
                  2 * Math.PI,
                  height,
                  1f);

          boundsMin.setValues(top, 3);
          boundsMax.setValues(top, 3);
          radius *= height;
          enlargeBoundsToDiagonal(boundsMin, boundsMax, bottomCenter, ev1, ev2, radius, radius2);

        } else { // infinite cone
          if (vMinMax == null) {
            vMinMax = new double[2];
          }
          vMinMax[0] = Double.POSITIVE_INFINITY;
          vMinMax[1] = Double.NEGATIVE_INFINITY;
          getMinMax(vMinMax);
          min = vMinMax[0];
          max = vMinMax[1];
          // min -= delta;
          // max += delta;
          // App.debug(min+","+max);
          center = quadric.getMidpoint3D();
          ev1 = quadric.getEigenvec3D(0);
          ev2 = quadric.getEigenvec3D(1);
          Coords ev3 = quadric.getEigenvec3D(2);
          r1 = quadric.getHalfAxis(0);
          r2 = quadric.getHalfAxis(1);

          if (min * max < 0) {
            if (getView3D().useClippingCube()) {
              surface.cone(center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, min, 1f);
              surface.cone(center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, max, 1f);
            } else {
              surface.cone(
                  center,
                  ev1,
                  ev2,
                  ev3,
                  r1,
                  r2,
                  0,
                  2 * Math.PI,
                  min,
                  (float) ((-9 * min - max) / (min - max)));
              surface.cone(
                  center,
                  ev1,
                  ev2,
                  ev3,
                  r1,
                  r2,
                  0,
                  2 * Math.PI,
                  max,
                  (float) ((-9 * max - min) / (max - min)));
            }
          } else {
            if (getView3D().useClippingCube()) {
              surface.cone(center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, min, max, false, false);
            } else {
              double delta = (max - min) / 10;
              surface.cone(
                  center,
                  ev1,
                  ev2,
                  ev3,
                  r1,
                  r2,
                  0,
                  2 * Math.PI,
                  min + delta,
                  max - delta,
                  false,
                  false);
              surface.cone(
                  center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, min, min + delta, true, false);
              surface.cone(
                  center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, max - delta, max, false, true);
            }
          }
        }

        setSurfaceIndex(surface.end());
        break;

      case GeoQuadricNDConstants.QUADRIC_CYLINDER:
        center = quadric.getMidpoint3D();
        ev1 = quadric.getEigenvec3D(0);
        ev2 = quadric.getEigenvec3D(1);
        Coords ev3 = quadric.getEigenvec3D(2);

        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());

        if (quadric instanceof GeoQuadric3DPart) { // simple cylinder
          radius = quadric.getHalfAxis(0);
          double radius2 = quadric.getHalfAxis(1);
          longitude = renderer.getGeometryManager().getLongitude(radius, getView3D().getScale());
          Coords bottomCenter =
              surface.cylinder(
                  center,
                  ev1,
                  ev2,
                  ev3,
                  radius,
                  radius2,
                  0,
                  2 * Math.PI,
                  quadric.getMinParameter(1),
                  quadric.getMaxParameter(1),
                  false,
                  false,
                  longitude);

          boundsMin.set(Double.POSITIVE_INFINITY);
          boundsMax.set(Double.NEGATIVE_INFINITY);
          enlargeBoundsToDiagonal(boundsMin, boundsMax, center, ev1, ev2, radius, radius);
          enlargeBoundsToDiagonal(boundsMin, boundsMax, bottomCenter, ev1, ev2, radius, radius);

        } else {
          if (vMinMax == null) {
            vMinMax = new double[2];
          }
          vMinMax[0] = Double.POSITIVE_INFINITY;
          vMinMax[1] = Double.NEGATIVE_INFINITY;
          getMinMax(vMinMax);
          min = vMinMax[0];
          max = vMinMax[1];
          r1 = quadric.getHalfAxis(0);
          r2 = quadric.getHalfAxis(1);
          radius = Math.max(r1, r2);

          longitude = renderer.getGeometryManager().getLongitude(radius, getView3D().getScale());
          if (getView3D().useClippingCube()) {
            surface.cylinder(
                center, ev1, ev2, ev3, r1, r2, 0, 2 * Math.PI, min, max, false, false, longitude);
          } else {
            double delta = (max - min) / 10;
            surface.cylinder(
                center,
                ev1,
                ev2,
                ev3,
                r1,
                r2,
                0,
                2 * Math.PI,
                min + delta,
                max - delta,
                false,
                false,
                longitude);
            surface.cylinder(
                center,
                ev1,
                ev2,
                ev3,
                r1,
                r2,
                0,
                2 * Math.PI,
                min,
                min + delta,
                true,
                false,
                longitude);
            surface.cylinder(
                center,
                ev1,
                ev2,
                ev3,
                r1,
                r2,
                0,
                2 * Math.PI,
                max - delta,
                max,
                false,
                true,
                longitude);
          }
        }

        setSurfaceIndex(surface.end());

        break;

      case GeoQuadricNDConstants.QUADRIC_SINGLE_POINT:
        surface = renderer.getGeometryManager().getSurface();
        surface.start(getReusableSurfaceIndex());
        Coords m = quadric.getMidpoint3D();
        double thickness =
            quadric.getLineThickness() / getView3D().getScale() * DrawPoint3D.DRAW_POINT_FACTOR;
        surface.drawSphere(quadric.getLineThickness(), m, thickness);
        setSurfaceIndex(surface.end());

        boundsMin.setValues(m, 3);
        boundsMax.setValues(m, 3);
        boundsMin.addInside(-thickness);
        boundsMax.addInside(thickness);
        break;

      case GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES:
      case GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES:
        initDrawPlanes(quadric);
        drawPlanes[0].updateForItSelf();
        drawPlanes[1].updateForItSelf();
        break;

      case GeoQuadricNDConstants.QUADRIC_PLANE:
        initDrawPlanes(quadric);
        drawPlanes[0].updateForItSelf();
        break;

      case GeoQuadricNDConstants.QUADRIC_LINE:
        initDrawLine(quadric);
        drawLine.updateForItSelf();
        break;

      default:
        setSurfaceIndex(-1);
    }

    return true;
  }