/* -*-flix-*- */ /* * Animation depicting the local isometric deformation of a * catenoid to a helicoid through minimal immersions */ #include "epix.h" using namespace ePiX; // number of meridians and latitudes int N1(72); int N2(24); P VIEWPT(4, 3, 4); // locations of "lights"; see mesh::draw() below for implementation P LIGHT_R(10,0,10); P LIGHT_G(0,10,10); P LIGHT_B(0,-10,10); // internal constants double r_0(1.0); double EPS(0.0); // fact shrink factor double du(2.0/N1), dv(4.0/N2); // parametrized surfaces P helicoid(double u, double v) { return P(sinh(v)*Cos(M_PI*u), sinh(v)*Sin(M_PI*u), 2*M_PI*u); } P catenoid(double u, double v) { return P(cosh(v)*Sin(M_PI*u), -cosh(v)*Cos(M_PI*u), -v); } P morph(double u, double v) { return Cos(2*M_PI*tix())*helicoid(u,v) + Sin(2*M_PI*tix())*catenoid(u,v); } // facet-like class with spot reflection class element { private: P pt1; P pt2; P pt3; P pt4; double distance; public: element(P f(double u, double v), double u0, double v0) : pt1(f(u0+EPS,v0+EPS)), pt2(f(u0+du-EPS,v0+EPS)), pt3(f(u0+du-EPS,v0+dv-EPS)), pt4(f(u0+EPS,v0+dv-EPS)) { P center(0.25*(pt1 + (pt2 + (pt3 + pt4)))); P temp(camera.viewpt()); distance = norm(center-temp); } double how_far() const { return distance; } void draw() { P normal((pt2 - pt1)*(pt4 - pt1)); normal *= 1/norm(normal); double dens_r(0.75*(pow(normal|LIGHT_R, 2)/(LIGHT_R|LIGHT_R))); double dens_g(0.75*(pow(normal|LIGHT_G, 2)/(LIGHT_G|LIGHT_G))); double dens_b(0.75*(pow(normal|LIGHT_B, 2)/(LIGHT_B|LIGHT_B))); fill(RGB(dens_r, dens_g, dens_b)); ePiX::quad(pt1, pt2, pt3, pt4); } }; class By_distance { public: bool operator() (const element& arg1, const element& arg2) { return arg1.how_far() > arg2.how_far(); } }; int main(int argc, char* argv[]) { if (argc == 3) { char* arg; double temp1, temp2; temp1=strtod(argv[1], &arg); temp2=strtod(argv[2], &arg); tix()=temp1/temp2; } double MAX(8); picture(P(-MAX,-MAX),P(MAX,MAX), "5x5in"); begin(); pen(Neutral(), 0); // no grid lines // draw bounding square for uniform frame size backing(Black()); viewpoint(VIEWPT); /* rotating lights LIGHT_R=cis(2*M_PI*tix()); LIGHT_G=cis(2*M_PI*(tix()+0.25)); LIGHT_B=P(-2,-2,6); */ camera.range(20); // build surface std::vector mesh; for (int i=0; i