import java.awt.*; class Torus extends Biparam implements java.io.Serializable { static final long serialVersionUID = -7637054329820073252L; // Old Torus() { inPnt = new cVector(); name = "Torus"; uDivs = 35; // 64; vDivs = 19; // 24; minUDivs = 3; minVDivs = 3; retile(); major = 1; minor = 0.2; recalculate(); } Object3D deepCopy() { Torus t = new Torus(); deepCopySelf(t); return t; } protected void deepCopySelf(Object3D other) { super.deepCopySelf(other); Torus t = (Torus)other; t.major = major; t.minor = minor; } void createEditWindow(GroupEditor callee, boolean newWindow) { if (newWindow) objectUI = new TorusEditor(this, deepCopy(), callee); else objectUI = new TorusEditor(this, callee); editWindow = objectUI.GetEditor(); } void generatePOV(StringBuffer buffer) { generateNameComment(buffer); generateIndent(buffer); buffer.append("torus { "); buffer.append(major); buffer.append(", "); buffer.append(minor); buffer.append("\n"); generateTransform(buffer); generateIndent(buffer); buffer.append("}\n"); } double uStretch() { return 6; // Actually 6.28 (I think) } Vertex biparamFunction(double u, double v) { if (u == 1) u = 0; if (v == 1) v = 0; double uAng = u * 2 * Math.PI; double vAng = -v * 2 * Math.PI; double cosua = Math.cos(uAng); double sinua = Math.sin(uAng); double cosva = Math.cos(vAng); double sinva = Math.sin(vAng); double radius = (major + cosva * minor); double x = cosua * radius; double y = sinva * minor; if (Math.abs(y) < 1E-10) y = 0; // hashtable issue double z = sinua * radius; cVector tPos = LA.newVector(x, y, z); double xx = cosua * cosva * minor; double zz = sinua * cosva * minor; cVector tNorm = LA.newVector(xx, y, zz); Vertex temp = new Vertex(tPos); //temp.pos = tPos; // useless new temp.norm = tNorm; LA.vecNormalize(temp.norm); temp.y += minor; return temp; } void getBounds(cVector minima, cVector maxima, boolean xform) { super.getBounds(minima, maxima, xform); // july 2014 minima.x = minima.z = -(major + minor); // maxima.x = maxima.z = major + minor; // minima.y = -minor; // maxima.y = minor; // if (xform) // transformBounds(minima, maxima); } boolean inside(double x, double y, double z, boolean xform) { if (xform) untransform(x, y, z, inPnt); else LA.setVector(inPnt, x, y, z); double rad1 = inPnt.x * inPnt.x + inPnt.z * inPnt.z; rad1 = (double)Math.sqrt(rad1); double d = major / rad1; double xx = d * inPnt.x; double zz = d * inPnt.z; inPnt.x -= xx; inPnt.z -= zz; double rad2 = inPnt.x * inPnt.x + inPnt.y * inPnt.y + inPnt.z * inPnt.z; return rad2 <= minor * minor; } void drawEditHandles(//ClickInfo info, int level) { if (level == 0) { return; } else { super.drawEditHandles(//info, level); cVector temp = LA.newVector(0, 0, minor); LA.xformPos(temp, toParent, temp); Rectangle majorSpot = calcHotSpot(temp); //, info); majorSpot.translate(4, 4); temp.x = major; temp.y = temp.z = 0; LA.xformPos(temp, toParent, temp); Rectangle minorSpot = calcHotSpot(temp); //, info); minorSpot.translate(4, 4); clickInfo.g.setColor(Color.green); clickInfo.g.fillRect(majorSpot.x, majorSpot.y, majorSpot.width, majorSpot.height); clickInfo.g.fillRect(minorSpot.x, minorSpot.y, minorSpot.width, minorSpot.height); return; } } boolean doEditClick(//ClickInfo info, int level) { if (level == 0) return false; hitSomething = 0; if (super.doEditClick(//info, level)) { hitSomething = 1; return true; } cVector temp = LA.newVector(0, 0, minor); LA.xformPos(temp, toParent, temp); Rectangle majorSpot = calcHotSpot(temp); //, info); majorSpot.translate(4, 4); temp.x = major; temp.y = temp.z = 0; LA.xformPos(temp, toParent, temp); Rectangle minorSpot = calcHotSpot(temp); //, info); minorSpot.translate(4, 4); if (majorSpot.contains(clickInfo.x, clickInfo.y)) { hitSomething = 2; startRad = major; } else if (minorSpot.contains(clickInfo.x, clickInfo.y)) { hitSomething = 3; startRad = minor; } else { return false; } startX = clickInfo.x; return true; } void doEditDrag(//ClickInfo info, boolean opposite) { if (hitSomething == 0) return; if (hitSomething == 1) { super.doEditDrag(//info, opposite); return; } double deltaR = clickInfo.x - startX; //cVector delta = LA.newVector(info.x - startX, 0, 0); //LA.xformDir(delta, info.camera.fromScreen, delta); deltaR /= 100 * clickInfo.camera.SCALE / clickInfo.camera.Distance(); double newRad = startRad + deltaR; if (newRad < 0) newRad = 0; if (hitSomething == 2) major = newRad; else minor = newRad; recalculate(); clickInfo.pane.repaint(); } double major; double minor; protected cVector inPnt; private static final int hitStandard = 1; private static final int hitMajor = 2; private static final int hitMinor = 3; private static int hitSomething; private static int startX; private static double startRad; }