package fiberedKnot; import java.awt.Color; import jv.number.PdColor; import jv.number.PuDouble; import jv.number.PuInteger; import jv.object.PsDebug; import jv.project.PjProject; import jv.vecmath.PdVector; import jv.anim.PsAnimation; import jv.anim.PsTimeEvent; import jv.geom.PgPolygon; import jv.geom.PgElementSet; import jv.vecmath.PiVector; import jv.viewer.PvLight; /** * Project for demonstrating that torus knots are fibered, inside the JavaView viewer. * * @author Robert BL * skeleton by Matthew Song */ public class PjFiberedKnot extends PjProject { protected double deft = 0.; // Default time parameter protected double defw = 0.4; protected PuDouble m_time; protected PuDouble m_halfwidth; protected PuInteger m_knotvertices; protected PuInteger m_insideVisible, m_outsideVisible; //protected PvLight m_light; //protected PgElementSet m_torus; protected PgElementSet m_surf; protected PgPolygon m_knot; protected double s2=0.7548776662; protected double s1=Math.sqrt(1-s2*s2); public PjFiberedKnot() { super("FiberedKnot"); PsAnimation anim = new PsAnimation(); anim.setName("Time"); anim.addTimeListener(this); anim.setRepeat(PsAnimation.LOOP); m_knotvertices = new PuInteger("Knot length", this); m_insideVisible = new PuInteger("Green width", this); m_outsideVisible = new PuInteger("Blue width", this); m_time = new PuDouble("Time", this); m_knot = new PgPolygon(3); m_surf = new PgElementSet(3); // m_torus = new PgElementSet(3); if (getClass() == PjFiberedKnot.class) init(); } void toS3(PdVector v, Complex z, Complex w) { if (Math.abs(z.norm()+w.norm()-1)>1e-5) System.out.println("Point not in S3: " + (z.norm()+w.norm())); double a = z.re-1; if (Math.abs(a) < 1e-15) a=((a>=0)?1e-15:-1e-15); // System.out.println(v + " " + w.re/a + " " + w.im/a + " " + z.im/a); v.set(w.re/a, w.im/a, z.im/a); } public void init() { super.init(); m_time.setDefBounds(0, Math.PI*2, Math.PI / 200.0, Math.PI / 8.0); m_time.setDefValue(0); m_time.init(); m_insideVisible.setDefBounds(0,8,1,1); m_insideVisible.setDefValue(8); m_insideVisible.init(); m_outsideVisible.setDefBounds(0,21,3,1); m_outsideVisible.setDefValue(4); m_outsideVisible.init(); m_knotvertices.setDefBounds(2,512,1,6); m_knotvertices.setDefValue(256); m_knotvertices.init(); m_knot.showVertices(false); m_knot.setGlobalEdgeColor(Color.WHITE); m_knot.setGlobalEdgeSize(3); m_surf.showElementColors(true); m_surf.showEdges(false); m_surf.showSmoothElementColors(true); /* m_torus.showElementColors(true); m_torus.setGlobalElementColor(Color.YELLOW); m_torus.computeTorus(25,36,s2/(1-s1*s1),s2*s1/(1-s1*s1)); m_torus.showTransparency(true); m_torus.setTransparency(.9); m_torus.showEdges(false); */ drawKnot(); drawSurf(); } void drawKnot() { int maxi = m_knotvertices.getValue()-1; m_knot.setNumVertices(maxi+1); for (int i=0; i<=maxi; i++) toS3(m_knot.getVertex(i), Complex.polar(s1, i*3./maxi*Math.PI*2), Complex.polar(-s2, i*2./maxi*Math.PI*2)); } void drawSurf() { int wraps[] = new int[2]; wraps[0]=3; wraps[1]=2; int max_visible[] = new int[2]; int visible[] = new int[2]; max_visible[0]=9; max_visible[1]=22; visible[0]=1+m_insideVisible.getValue(); visible[1]=1+m_outsideVisible.getValue(); for (int i=0; i<2; i++) { if (visible[i]<1) visible[i]=1; if (visible[i]>max_visible[i]) visible[i]=max_visible[i]; } int max_theta=21; m_surf.setNumVertices(wraps[0]*wraps[1]*max_theta*(visible[0]+visible[1])); m_surf.assureVertexColors(); int cnt=0; for (int side=0; side < 2; side++) { double dr=(side>0?s2:s1)/(max_visible[side]-.9999999); double rmin=dr*(max_visible[side]-visible[side]); double dth=2*Math.PI/(max_theta-1e-8)/wraps[1-side]; for (int branch=0; branch0?s2:s1); r+=dr) { for (double th=0; th<2*Math.PI; th+=dth) { Complex z = Complex.polar(r,th); Complex z_2=z.pow(wraps[1-side]); double r2_3=Math.pow(1-r*r,wraps[side]*.5); double w_3r_2= Math.pow(r2_3,2) - Math.pow(z_2.im,2); if (w_3r_2<1e-5) w_3r_2 = 0; Complex w_3 = new Complex(Math.sqrt(w_3r_2), -z_2.im ); Complex w = Complex.polar(1.,branch*2*Math.PI/wraps[side]).multiply(w_3.pow(1./wraps[side])); if (side>0) {Complex t=z; z=w; w=t; } z = z.multiply(Complex.polar(1., m_time.getValue()/2.)); w = w.multiply(Complex.polar(1., m_time.getValue()/3.)); toS3(m_surf.getVertex(cnt), z,w); if (side>0) m_surf.setVertexColor(cnt++, new Color((float)r,(float)r,(float)1.)); else m_surf.setVertexColor(cnt++, new java.awt.Color((float)r,(float)1.,(float)r)); } } } } m_surf.setNumElements(wraps[0]*wraps[1]*max_theta*(visible[0]+visible[1]-2)); m_surf.assureElementColors(); m_surf.setDimOfElements(4); int ecnt=0; for (int side=0; side<2; side++) { int maxj=max_theta*wraps[1-side]; for (int branch=0; branch