class Tetrahedron{ //Four corner points Vec3D p1; Vec3D p2; Vec3D p3; Vec3D p4; //Values at the four corner points float v1, v2,v3,v4; //Interpolated position of the threshold on the six edges float f12, f13, f14, f23, f24, f34; float threshold; int type; Tetrahedron(){ } Tetrahedron(Vec3D p1, Vec3D p2,Vec3D p3,Vec3D p4, float v1, float v2, float v3, float v4,float t){ set(p1,p2,p3,p4,v1,v2,v3,v4,t); } void set(Vec3D p1, Vec3D p2,Vec3D p3,Vec3D p4, float v1, float v2, float v3, float v4,float t){ this.p1=p1.copy(); this.p2=p2.copy(); this.p3=p3.copy(); this.p4=p4.copy(); this.v1=v1; this.v2=v2; this.v3=v3; this.v4=v4; threshold =t; type= determineType(); determineFactors(); } void determineFactors(){ f12 = determineFactor(v1,v2,threshold); f13 = determineFactor(v1,v3,threshold); f14 = determineFactor(v1,v4,threshold); f23 = determineFactor(v2,v3,threshold); f24 = determineFactor(v2,v4,threshold); f34 = determineFactor(v3,v4,threshold); } float determineFactor(float ll, float ul, float t){ if(abs(ul-ll)<0.001f) return 0.5f; return constrain((t-ll)/(ul-ll),0f,1f); } int determineType(){ int result=0; if(v1>threshold) result+=1; if(v2>threshold) result+=2; if(v3>threshold) result+=4; if(v4>threshold) result+=8; return result; } void draw(){ drawFaces(type); } void drawFaces(int type){ Vec3D tmp; switch(type) { case 0: case 15: break; case 1: case 14: tmp =p1.add(p3.sub(p1).scale(f13)); vertex(tmp.x,tmp.y,tmp.z); tmp =p1.add(p2.sub(p1).scale(f12)); vertex(tmp.x,tmp.y,tmp.z); tmp =p1.add(p4.sub(p1).scale(f14)); vertex(tmp.x,tmp.y,tmp.z); break; case 2: case 13: tmp =p1.add(p2.sub(p1).scale(f12)); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p3.sub(p2).scale(f23)); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p4.sub(p2).scale(f24)); vertex(tmp.x,tmp.y,tmp.z); break; case 3: case 12: tmp =p1.add(p4.sub(p1).scale(f14)); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p4.sub(p2).scale(f24)); vertex(tmp.x,tmp.y,tmp.z); tmp =p1.add(p3.sub(p1).scale(f13)); vertex(tmp.x,tmp.y,tmp.z); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p4.sub(p2).scale(f24)); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p3.sub(p2).scale(f23)); vertex(tmp.x,tmp.y,tmp.z); break; case 4: case 11: tmp =p1.add(p3.sub(p1).scale(f13)); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p3.sub(p2).scale(f23)); vertex(tmp.x,tmp.y,tmp.z); tmp =p3.add(p4.sub(p3).scale(f34)); vertex(tmp.x,tmp.y,tmp.z); break; case 5: case 10: tmp =p1.add(p2.sub(p1).scale(f12)); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p3.sub(p2).scale(f23)); vertex(tmp.x,tmp.y,tmp.z); tmp =p1.add(p4.sub(p1).scale(f14)); vertex(tmp.x,tmp.y,tmp.z); vertex(tmp.x,tmp.y,tmp.z); tmp =p3.add(p4.sub(p3).scale(f34)); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p3.sub(p2).scale(f23)); vertex(tmp.x,tmp.y,tmp.z); break; case 6: case 9: tmp =p1.add(p2.sub(p1).scale(f12)); vertex(tmp.x,tmp.y,tmp.z); tmp =p1.add(p3.sub(p1).scale(f13)); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p4.sub(p2).scale(f24)); vertex(tmp.x,tmp.y,tmp.z); vertex(tmp.x,tmp.y,tmp.z); tmp =p3.add(p4.sub(p3).scale(f34)); vertex(tmp.x,tmp.y,tmp.z); tmp =p1.add(p3.sub(p1).scale(f13)); vertex(tmp.x,tmp.y,tmp.z); break; case 7: case 8: tmp =p1.add(p4.sub(p1).scale(f14)); vertex(tmp.x,tmp.y,tmp.z); tmp =p2.add(p4.sub(p2).scale(f24)); vertex(tmp.x,tmp.y,tmp.z); tmp =p3.add(p4.sub(p3).scale(f34)); vertex(tmp.x,tmp.y,tmp.z); break; default: break; } } }