@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; } }
/** * 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; }
@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; }