class Klein extends Biparam implements java.io.Serializable { // void DrawNode(CameraPane display, Object3D /*Composite*/ root, boolean selected) {} static final long serialVersionUID = 0; double radius = 4; Klein() { this(true); } Klein(Klein s) { s.deepCopySelf(this); } public Klein(boolean recalc) { toParent = LA.newMatrix(); fromParent = LA.newMatrix(); name = "Klein"; //uDivs = vDivs = 16; uDivs = 32; vDivs = 32; minUDivs = 3; minVDivs = 2; //center = new cVector(); if (recalc) { retile(); recalculate(); } } void refreshCenter(cVector c) { /**/ toParent[3][0] = c.x; // - center.x; toParent[3][1] = c.y; // - center.y; toParent[3][2] = c.z; // - center.z; fromParent[3][0] = -c.x; // + center.x; fromParent[3][1] = -c.y; // + center.y; fromParent[3][2] = -c.z; // + center.z; /**/ //center.set(0,0,0); } cVector getCenter() { //assert(center.x == 0); //assert(center.y == 0); //assert(center.z == 0); // if (center == null) // center = new cVector(); cVector c = new cVector(center); for (int i=GetTransformCount(); --i>=0;) LA.xformPos(c, toParent, c); return c; } Object3D deepCopy() { Sphere e = new Sphere(); deepCopySelf(e); return e; } protected void deepCopyNode(Object3D other) { super.deepCopyNode(other); Klein e = (Klein) other; if (center != null) { e.center = new cVector(center); //LA.vecCopy(center, e.center); } e.radius = radius; } void generatePOV(StringBuffer buffer) { generateNameComment(buffer); generateIndent(buffer); buffer.append("sphere { "); // LA.toPOVRay(center, buffer); buffer.append(", "); // buffer.append(radius); buffer.append("\n"); generateTransform(buffer); generateIndent(buffer); buffer.append("}\n"); } Vertex biparamFunction(double u, double v) { // KLEIN #! /* double uAng = LA.toRadians(-180*(1-u) + 180*u); double vAng = LA.toRadians(-180*(1-v) + 180*v); // x = cos(u) (a + sin(v) cos(u/2) - sin(2v) sin(u/2)/2) // y = sin(u) (a + sin(v) cos(u/2) - sin(2v) sin(u/2)/2) // z = sin(u/2) sin(v) + cos(u/2) sin(2v)/2 //where // -pi <= u <= pi //and // -pi <= v <= pi double cosu = Math.cos(uAng); double sinu = Math.sin(uAng); double cosu2 = Math.cos(uAng/2); double sinu2 = Math.sin(uAng/2); double sinv = Math.sin(vAng); double sin2v = Math.sin(vAng/2); double x = cosu * (handle + sinv * cosu2 - sin2v * sinu2 / 2); double y = sinu * (handle + sinv * cosu2 - sin2v * sinu2 / 2); double z = sinu2 * sinv + cosu2 * sin2v / 2; */ double uAng = LA.toRadians(u*360); double vAng = LA.toRadians(v*360); double cosu = Math.cos(uAng); double sinu = Math.sin(uAng); double cosv = Math.cos(vAng); double sinv = Math.sin(vAng); double r = radius * (1 - cosu / 2); double x = 6 * cosu * (1 + sinu); double y = 16 * sinu; double z = r * sinv; if (u < 0.5) { x += r * cosu * cosv; y += r * sinu * cosv; } else { x += r * Math.cos(vAng + Math.PI); } // y = -16 .. 20 r = radius * (20 - y)/36 * (1 - cosu / 2); x = 6 * cosu * (1 + sinu); y = 16 * sinu; z = r * sinv; if (u < 0.5) { x += r * cosu * cosv; y += r * sinu * cosv; } else { x += r * Math.cos(vAng + Math.PI); } Vertex temp = new Vertex(); temp.norm = LA.newVector(x, y, z); //temp.pos = new cVector(); if (center != null) LA.vecAdd(temp.norm, center, temp/*.pos*/); else LA.vecCopy(temp.norm, temp/*.pos*/); LA.vecNormalize(temp.norm); return temp; } void createEditWindow(GroupEditor callee, boolean newWindow) { //editWindow = (new SphereEditor(this, deepCopy(), callee)).GetEditor(); if (newWindow) { objectUI = new KleinEditor(this, deepCopy(), callee); } else { objectUI = new KleinEditor(this, callee); } editWindow = objectUI.GetEditor(); } boolean inside(double x, double y, double z, boolean xform) { return false; } }