Exemplo n.º 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);
   }
 }
Exemplo n.º 2
0
 /**
  * draw a sphere with center and radius. view scaling is used to know how many triangles are
  * needed
  *
  * @param center center of the sphere
  * @param radius radius of the sphere
  * @param longitude longitude length for rendering, corresponding to 2*PI (must be power of 2)
  * @param longitudeStart for sphere parts, first longitude to draw
  * @param longitudeLength for sphere parts, longitude width (must be power of 2)
  */
 public void drawSphere(
     Coords center, double radius, int longitude, double longitudeStart, int longitudeLength) {
   drawSphere(
       center,
       radius,
       longitude,
       longitudeStart,
       longitudeLength,
       manager.getView3D().getFrustumRadius());
 }
Exemplo n.º 3
0
  public void drawSphere(int size, Coords center, double radius) {

    int longitude = 8;
    size += 3;
    while (longitude * 6 <= size * size) { // find the correct longitude size
      // (size=3 <-> longitude=12 and
      // size=9 <-> longitude=48)
      longitude *= 2;
    }

    drawSphere(center, radius, longitude, 0, longitude, Double.POSITIVE_INFINITY);
  }
Exemplo n.º 4
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;
  }
Exemplo n.º 5
0
  /**
   * draw a sphere with center and radius. view scaling is used to know how many triangles are
   * needed
   *
   * @param center center of the sphere
   * @param radius radius of the sphere
   * @param longitude longitude length for rendering
   */
  public void drawSphere(Coords center, double radius, int longitude) {

    drawSphere(center, radius, longitude, 0, longitude);
  }