class Superellipsoid extends Biparam /*Sphere*/ implements java.io.Serializable { static final long serialVersionUID = -251688182693574378L; Superellipsoid() { super(); // false); inPnt = new cVector(); du = new cVector(); dv = new cVector(); name = "Superellipsoid"; east = 2; north = 2; //uDivs = vDivs = 32; uDivs = 36; vDivs = 34; minUDivs = 3; minVDivs = 2; retile(); recalculate(); } Object3D deepCopy() { Superellipsoid s = new Superellipsoid(); deepCopySelf(s); return s; } protected void deepCopyNode(Object3D other) { super.deepCopyNode(other); Superellipsoid s = (Superellipsoid)other; s.east = east; s.north = north; } void createEditWindow(GroupEditor callee, boolean newWindow) { //editWindow = new SuperEditor(this, deepCopy(), callee); if (newWindow) objectUI = new SuperEditor(this, deepCopy(), callee); else objectUI = new SuperEditor(this, callee); editWindow = objectUI.GetEditor(); } double signPower(double base, double pow) { //if (base == 0) // base = 0.0000001; if (base == 0 && pow == 0 || base == 1) return 1; if (base == 0) return 0; if (base == -1) return -1; if (base >= 0) return (double)Mathpow(base, pow); else return -(double)Mathpow(-base, pow); } static int tablelength = 257; static double power1 = -1; static double[] powtable1 = new double[tablelength]; static double power2 = -1; static double[] powtable2 = new double[tablelength]; double Mathpow(double base, double pow) { int basei = (int) (base * (tablelength - 1)); double[] table = null; if (pow == power1) { table = powtable1; } else if (pow == power2) { table = powtable2; } else { if (power2 == -1) { power2 = pow; table = powtable2 = new double[tablelength]; } else { power1 = pow; table = powtable1 = new double[tablelength]; power2 = -1; } } if (basei != 0 && table[basei] == 0) { table[basei] = Math.pow(basei/(tablelength - 1.0), pow); //if (table[basei] == 0) // System.out.println("POW == 0 : " + basei); } if (table[basei+1] == 0) { table[basei+1] = Math.pow((basei+1.0)/(tablelength - 1.0), pow); //if (table[basei+1] == 0) // System.out.println("POW == 0"); } double offset = base * (tablelength - 1) - basei; //System.out.println("offset = " + offset); return table[basei] * (1 - offset) + table[basei+1] * offset; } double DsignPower(double base, double pow) { if (base == 0) base = 0.0000000001; if (base == 1 || base == -1) return pow; if (base > 0) return pow * (double)(Mathpow(base, pow) / base); // - 1); else // if (base < 0) return pow * (double)(Mathpow(-base, pow) / -base); // - 1); //else //{ // if (pow == 1) // return 1; // else // return 0; //} } cVector du; // = new cVector(); cVector dv; // = new cVector(); double uStretch() { return 2; } double vFlip(double v) { return 1-v; } Vertex biparamFunction(double u, double v) { //System.out.println("U = " + u + "; V = " + v); double uAng = LA.toRadians(u * 360); double vAng = LA.toRadians(v * 180 - 90); double mcu = Math.cos(uAng); double msu = Math.sin(uAng); double mcv = Math.cos(vAng); double msv = Math.sin(vAng); if (u == 1) { mcu = 1; msu = 0; } if (v == 1) { mcv = 0; msv = 1; } if (v == 0) { mcv = 0; msv = -1; } double cu = signPower(mcu, north); double su = signPower(msu, north); double cv = signPower(mcv, east); double sv = signPower(msv, east); double z = radius * cv * cu; double x = radius * cv * su; double y = radius * sv + radius; double dcu = DsignPower(mcu, north) * -msu; double dsu = DsignPower(msu, north) * mcu; double dcv = DsignPower(mcv, east) * -msv; double dsv = DsignPower(msv, east) * mcv; du.z = cv * dcu; du.x = cv * dsu; du.y = 0; dv.z = dcv * cu; dv.x = dcv * su; dv.y = dsv; //if (du.length() == 0) // System.out.println("DU is null"); //if (dv.length() == 0) // System.out.println("DV is null"); LA.vecNormalize(du); LA.vecNormalize(dv); Vertex temp = new Vertex(); temp.norm = LA.newVector(x, y, z); LA.vecCross(du,dv, temp.norm); if (temp.norm.length() == 0) temp.norm.y = 2*v - 1; else LA.vecNormalize(temp.norm); temp./*pos.*/x = x; // = LA.newVector(x, y, z); temp./*pos.*/y = y; temp./*pos.*/z = z; //if (temp.norm.dot(temp/*.pos*/) < 0) //temp.norm.mul(-1); //LA.vecAdd(temp/*.pos*/, center, temp/*.pos*/); return temp; } boolean inside(double x, double y, double z, boolean xform) { if (xform) untransform(x, y, z, inPnt); else LA.setVector(inPnt, x, y, z); //LA.vecSub(inPnt, center, inPnt); LA.vecScale(inPnt, 1 / radius); // Math.abs(radius)); for (int i=0; i < 3; i++) if (inPnt.get(i) < 0) inPnt.set(i, -inPnt.get(i)); boolean inside = true; for (int i=0; i < 3; i++) if (inPnt.get(i) >= 1) { //Simplex.atom = this; //height = 1; //depth = 0; //return false; inside = false; break; } double f = 1; if (inside) { double e2 = 2 / north; double e1 = 2 / east; f = (double)(Mathpow(inPnt.x, e2) + Mathpow(inPnt.z, e2)); f = (double)Math.pow(f, e1/e2); // east/north); // e2 / e1); f += (double)Mathpow(inPnt.y, e1); f -= 1; } //double f = (double)(signPower(inPnt.x, e2) + signPower(inPnt.z, e2)); //f = (double)signPower(f, e2 / e1); //f += (double)signPower(inPnt.y, e1); //System.out.println("INSIDE(" + x + ", " + y + ", " + z + ") = " + f); inside = f <= 0; if (depth != -1 && (height <= 0 ^ inside)) { Simplex.atom = this; } height = f; depth = 0; return radius<0?!inside:inside; } void getBounds(cVector minima, cVector maxima, boolean xform) { super.getBounds(minima, maxima, xform); // july 2014 //for (int i=0; i < 3; i++) // { // double r = Math.abs(radius); // minima.x = -r; // minima.y = -r; // minima.z = -r; // //maxima[i] = center[i] + radius; // maxima.x = r; // maxima.y = r; // maxima.z = r; // } // // if (xform) // transformBounds(minima, maxima); } void generatePOV(StringBuffer buffer) { generateNameComment(buffer); generateIndent(buffer); buffer.append("superellipsoid { < "); buffer.append(north); buffer.append(","); buffer.append(east); buffer.append(">\n"); generateIndent(buffer); buffer.append(" scale "); buffer.append(radius); buffer.append("\n"); //generateIndent(buffer); //buffer.append(" translate "); //LA.toPOVRay(center, buffer); //buffer.append("\n"); generateTransform(buffer); generateIndent(buffer); buffer.append("}\n"); } double east; double north; double radius = 0.5; private cVector inPnt; }