long double BaseOfPerpendicularIsInsideSegment(Pnt p, Pnt a, Pnt b) { Pnt normal = Pnt((b - a).y, - (b - a).x); normal = normal * (1 / normal.len()); long double l = distanceFromPointToLine(p, a, b); return pointIsOnSegment(p + normal * l, a, b) || pointIsOnSegment(p - normal * l, a, b); }
//Dini's Surface void dini(GLVApp& app, bool reset = false){ static Dll dll = DLN(0,1,0); static Frame frame(PT(0,2,0), Rot(1,0,0,0)); TOUCH(frame); static Pnt p = Ro::null(1,0,0); static float period, pitch, amt, nm, lz; SET Gui& gui = app.gui; gui(period,"period",-10,10)(pitch,"pitch",-10,10)(amt,"amt",-10,10)(nm,"num",10,100); gui(lz, "light_src",-100,100); amt = -2; period = 1; pitch = 0; lz = .35; END if (reset) bSet = false; GL::lightPos(0, lz, lz); DRAW(frame);//.draw(); Twist tw; tw.along(dll, PI*period, pitch); Par par = frame.ty(frame.scale() * amt); int num = nm; UVMesh uvmesh(num+1,num+1); ITJi(i,num) Pnt tp = p.sp( tw.mot(-t) ); ITJi(j, num) Par npar = par.trs(0,tp[1],0); Bst pp = Gen::bst(npar*t);//Gen::trv(1,npar * t); Pnt np = Ro::loc( tp.sp( pp ) ); uvmesh.add(np); END END //DRAW uvmesh.draw(1,0,0); uvmesh.drawTri(1,1,0,.5); app.text("Negatively Curved Surfaces: The Psuedosphere and Dini's Surface"); }
void Immediate (const Sph& s){ VT ta = Ro::size( s, false ); //Draw as dual Sphere (if |radius^2| > 0.000001); if ( fabs(ta) > FPERROR ) { // printf("spehere!!!!!!!!!!!!!!!!!!!!\n"); bool real = ta > 0 ? 1 : 0; Pnt p = Ro::cen( s ); VT t = sqrt ( fabs ( ta ) ); gfx::GL::translate ( p.begin() ); (real) ? gfx::Glyph::SolidSphere(t, 5+ floor(t*30), 5+floor(t*30)) : Glyph::Sphere(t); } else { // printf("NOOOOOO\n"); gfx::Glyph::Point(s); } }
//Time that will take the point with a given speed to hit a circle arrow::Vct::Mod tth (const Pnt &p, const arrow::Vct &pv, const Crl &c) { //If they are alredy at contact, the tth is 0 if (p.contact(c)) return 0; else if(!(pv))//If they are not at contact and the speed is null, they will never meet return -1; //Get the distance and the componets of the speed arrow::Vct d(p.get_center()-c.get_center()); arrow::Vct::Mod dx(d.mod_tan_part(pv)); //Get the a, b and c coefficientes of the second degree ecuation double ac=pv.sq_mod(), bc=2*dx*pv.mod(), cc=d.sq_mod()-c.get_size()*c.get_size(); //Get the value of the discriminant double disc=bc*bc-4*ac*cc; //Check that the 2nd degree equation has solution if (disc<0)//No solution return -1;//No contact else//Has solution { //Find the two solutions double sol1=(-bc-std::sqrt(disc))/(2*ac), sol2=(-bc+std::sqrt(disc))/(2*ac); double sol=std::min(sol1,sol2);//Find the final solution if (sol<0) return -1;//No contact return value return sol; } }
void hopf(al::VsrApp& app){ HopfFiber hf; static int time = 0; time++; double tphase = PI * time/180.0; //GUI Controlled Parameters static int num = 2; static int res = 3; static bool handed, bDrawCir, bDrawPnt,bReset; static double phase,amt,minDistance; //SET UP Gui static bool bSet = 0; if (!bSet) { bSet = 1; app.glv.gui(num,"num",0,1000)(res,"res",0,1000)(phase,"phase",-100,100)(amt,"amt",0,10)(minDistance,"minDistance",0,1000); app.glv.gui(handed)(bDrawCir, "drawcir")(bDrawPnt,"drawpnt")(bReset,"reset"); } vector<Pnt> vp; for (int i = 0; i < num; ++i){ double u = 1.0 * i/num; for (int j = 0; j < res; ++j){ double v = 1.0 * j/res; Cir tc = hf.fiber(-1.0 + 2*u, -.5 + v); Pnt tp = Ro::pnt_cir( tc, tphase * Ro::cur(tc) * phase); if(bDrawPnt)DRAW3(tp,u,v,1-u); if(bDrawCir)DRAW3(tc,v,u,1-u); vp.push_back( Ro::pnt_cir( tc, v * u * PI ) ); } } static Dll dll = DLN(0,1,0); app.interface.touch(dll); DRAW(dll); static Point point = PT(2,0,0); app.interface.touch(point); DRAW3(point,1,0,0); for (int i = 0; i <= 1; ++i){ double t = i/1.0; Dll tdll = dll.sp( Gen::rot(Biv::xy * t*PIOVERTWO) ); Pnt pa = Ro::split( ( tdll ^ Ro::sur(hf.cir) ).dual(), true); Pnt pb = Ro::split( ( tdll ^ Ro::sur(hf.cir) ).dual(), false); DRAW3(pa,1,1,0); DRAW3(pb,1,1,0); Coord::Sph spha = Coord::vec2sph( Vector(pa).unit() ); Coord::Sph sphb = Coord::vec2sph( Vector(pb).unit() ); Cir cca = hf.fiber( spha.theta / PI, spha.phi / PI ); Cir ccb = hf.fiber( sphb.theta / PI, sphb.phi / PI ); Bst bst = Gen::bst( (cca.dual() * PI/3.0 + ccb.dual() * PI/2.0 )* amt ); DRAW3(cca,0,1,0); DRAW3(ccb,0,0,1); vector<Pnt> pp; Pnt tp = point;//.trs(-t,0,0); for (int i = 0; i<1000; ++i){ tp = Ro::loc( tp.sp( bst ) ); pp.push_back(tp); } glColor3f(1,0,0); glBegin(GL_LINE_STRIP); for (int i = 0; i<pp.size(); ++i ){ GL::vertex( pp[i].w() ); } glEnd(); } int tnum = 10; // for (int j = 0; j < tnum; ++j){ // // double t = 1.0 * j/tnum; // // Bst bst2 = hf.mtt( ); // // for (int i = 0; i<pp.size(); ++i ){ // for(int k = 0; k < 10; ++k){ // // } // } // // } }
//Contact between a point and a circle bool collide (const Crl &c, const Pnt &p) { return (c.get_center()-p.get_center()).sq_mod()<=c.get_size()*c.get_size(); }
virtual void onDraw(){ getMouse(); static Dls dls = Ro::dls(5.0, 0,-5,0); Touch(interface,dls); static Dlp dlp = Vec(0,1,1).unit() + Inf(0); Touch(interface,dlp); Draw(dlp,0,1,0); //some lines int iter = 50; float spacing = 10; vector<Lin> lines(iter); int it = 0; for ( auto &i : lines ){ it += 1; float t = -spacing/2.0 + spacing * (float) it / iter; //Top curvature Par tp = Par( Tnv(0,0,amtA) ).trs(0,3,0); auto bstA = Gen::bst( tp ); Pnt tpnt = Ro::point( t, 3, 0 ); Dll dll = (tpnt ^ Vec::y ^ Inf(1) ).dual(); Pnt pa = Ro::loc( tpnt.spin( bstA ) ); //Bottom Curvature Par bp = Par( Tnv(0,0,amtB) ).trs(0,-3,0); auto bstB = Gen::bst( bp ); Pnt bpnt = Ro::point( t, -3, 0 ); Pnt pb = Ro::loc( bpnt.spin( bstB ) ); i = pa ^ pb ^ Inf(1); i = i.runit(); Draw(i); Pnt rp = ( i.dual() ^ dlp ).dual().unit().null(); Draw(rp,1,0,1); Draw(pa,1,0,0); Draw(tpnt,0,1,0); Draw(pb,1,0,0); // Par itp = Par( Tnv(0,0,amtA) ).trs ( Fl::loc( LN(0,1,0), rp, false ) ); // auto ibst = Gen::bst(itp); // VT dist = Ro::dist( pa, rp ); Pnt rpp = Ro::loc( Ro::split( ( Ro::dls( tpnt, dist ) ^ dll ).dual(), false )) ; VT dist2 = Ro::dist( tpnt, rpp ); // cout << dist << " " << dist2 << endl; // Pnt rpp = Ro::loc( rp.spin( !ibst ) ); //inverse operation Draw( rpp, 1,1, 0); auto ri = i.reflect(dlp); Draw(ri,0,0,1); } // Draw(dls,0,1,1,.2); }
/*! * \brief hyperbolic spin transformation from pa to pb by amt (0,1) */ Point hspin(const Pnt& pa, const Pnt& pb, double amt){ return Round::loc( pa.boost( hgen(pa,pb,amt) ) ); //versor * dist * amt * .5) ); }