public void drawSphere( Coords center, double radius, int longitude, double longitudeStart, int longitudeLength, double frustumRadius) { manager.startGeometry(Manager.Type.TRIANGLES); // set texture to (0,0) manager.setDummyTexture(); int latitude = longitude / 4; // check which parts are visible (latitudes) Coords o = manager.getView3D().getCenter(); double z = center.getZ(); double zMin = o.getZ() - frustumRadius; double zMax = o.getZ() + frustumRadius; int latitudeMaxTop = 0; latitudeMaxTop = latitude; if (Kernel.isGreater(z + radius, zMax)) { double angle = Math.asin((zMax - z) / radius); latitudeMaxTop = (int) (latitude * 2 * angle / Math.PI) + 2; } int latitudeMaxBottom = 0; latitudeMaxBottom = latitude; if (Kernel.isGreater(zMin, z - radius)) { double angle = Math.asin((z - zMin) / radius); latitudeMaxBottom = (int) (latitude * 2 * angle / Math.PI) + 2; } // Log.debug(latitudeMaxBottom+","+latitudeMaxTop); int latitudeMax = Math.max(latitudeMaxTop, latitudeMaxBottom); int latitudeMin = 0; // start on equator if (latitudeMaxTop < 0) { // start below equator latitudeMin = -latitudeMaxTop; } else if (latitudeMaxBottom < 0) { // start above equator latitudeMin = -latitudeMaxBottom; } // check which parts are visible (longitudes) // start drawing if (coordsArray.length <= longitudeLength) { coordsArray = new Coords[longitudeLength + 1]; for (int ui = 0; ui <= longitudeLength; ui++) { coordsArray[ui] = new Coords(4); } } Coords norm1 = new Coords(4), norm2 = new Coords(4), n1b = new Coords(4), n2b = new Coords(4); double[] cosSinV = new double[2]; // equator // cosSinV[0] = 1; // cos(0) // cosSinV[1] = 0; // sin(0) cosSin(latitudeMin, latitude, cosSinV); double lastCos = 1; for (int ui = 0; ui <= longitudeLength; ui++) { sphericalCoords(ui, longitude, longitudeStart, cosSinV, coordsArray[ui]); } // shift for longitude int shift = 1; boolean jumpNeeded = false; for (int vi = latitudeMin + 1; vi < latitudeMax; vi++) { cosSin(vi, latitude, cosSinV); // check if parallel is small enough to make jumps if (2 * cosSinV[0] < lastCos) { lastCos = lastCos / 2; jumpNeeded = true; } else { jumpNeeded = false; } // first values norm2.set(coordsArray[0]); sphericalCoords(0, longitude, longitudeStart, cosSinV, n2b); // first : no jump boolean jump = jumpNeeded; for (int ui = shift; ui <= longitudeLength; ui += shift) { // last latitude values norm1.set(norm2); norm2.set(coordsArray[ui]); // new latitude values and draw triangles n1b.set(n2b); if (jumpNeeded) { if (jump) { // draw edge triangle and center triangle sphericalCoords(ui + shift, longitude, longitudeStart, cosSinV, n2b); if (vi < latitudeMaxTop) { // top triangles drawNCr(norm1, center, radius); drawNCr(norm2, center, radius); drawNCr(n1b, center, radius); drawNCr(n1b, center, radius); drawNCr(norm2, center, radius); drawNCr(n2b, center, radius); } if (vi < latitudeMaxBottom) { // bottom triangles drawNCrm(norm1, center, radius); drawNCrm(n1b, center, radius); drawNCrm(norm2, center, radius); drawNCrm(n1b, center, radius); drawNCrm(n2b, center, radius); drawNCrm(norm2, center, radius); } } else { // draw edge triangle sphericalCoords(ui, longitude, longitudeStart, cosSinV, n2b); if (vi < latitudeMaxTop) { // top triangles drawNCr(norm1, center, radius); drawNCr(norm2, center, radius); drawNCr(n1b, center, radius); } if (vi < latitudeMaxBottom) { // bottom triangles drawNCrm(norm1, center, radius); drawNCrm(n1b, center, radius); drawNCrm(norm2, center, radius); } } } else { // no jump : draw two triangles sphericalCoords(ui, longitude, longitudeStart, cosSinV, n2b); if (vi < latitudeMaxTop) { // top triangles drawNCr(norm1, center, radius); drawNCr(norm2, center, radius); drawNCr(n1b, center, radius); drawNCr(norm2, center, radius); drawNCr(n2b, center, radius); drawNCr(n1b, center, radius); } if (vi < latitudeMaxBottom) { // bottom triangles drawNCrm(norm1, center, radius); drawNCrm(n1b, center, radius); drawNCrm(norm2, center, radius); drawNCrm(norm2, center, radius); drawNCrm(n1b, center, radius); drawNCrm(n2b, center, radius); } } coordsArray[ui].set(n2b); if (jumpNeeded) { jump = !jump; } } // if just jumps done, next shift is twice if (jumpNeeded) { shift = shift * 2; } sphericalCoords(0, longitude, longitudeStart, cosSinV, coordsArray[0]); } if (latitudeMax == latitude) { // pole norm2.set(coordsArray[0]); for (int ui = shift; ui <= longitudeLength; ui += shift) { norm1.set(norm2); norm2.set(coordsArray[ui]); if (latitudeMaxTop == latitude) { // top triangles drawNCr(norm1, center, radius); drawNCr(norm2, center, radius); drawNCr(Coords.VZ, center, radius); } if (latitudeMaxBottom == latitude) { // bottom triangles drawNCrm(norm1, center, radius); drawNCrm(Coords.VZ, center, radius); drawNCrm(norm2, center, radius); } } } manager.endGeometry(); }
/** * draws normal and point at center - normal * radius * * @param normal * @param center * @param radius */ protected void drawNCrm(Coords normal, Coords center, double radius) { normal2.setX(normal.getX()); normal2.setY(normal.getY()); normal2.setZ(-normal.getZ()); drawNCr(normal2, center, radius); }