void EventLoop(CCam & Camera1) { bool quitit=false; SDL_Event event; SDL_MouseMotionEvent event2; SDL_keysym *whatkey; bool mousedown=false; // Go to while(!quitit) to see what happens once data set up // Go to Render Scene for graphics bit bool exitnow=false; double xunit,yunit,zunit; xunit=1.0;yunit=1.0;zunit=1.0; // if_stream opens for input // of_stream opens for output // f_stream opens for both // string filename ="Sphere4.dat"; ifstream file_in; file_in.open(filename.c_str()); file_in >> n_nodes >> ntri; cout << n_nodes << " number of nodes" << endl; cout << ntri<< " number of triangles" << endl; cout << "read next line\n"; cout << "start read loop\n"; Triangles=(Triangle*)calloc(ntri, sizeof(Triangle)); NodeV=(D3Dvec*)calloc(n_nodes, sizeof(D3Dvec)); //initiales char quad, otherquad; int id,l,m,n; double x,y,z; for(int i=0; i<ntri;i++){ file_in >>l; file_in >>m; file_in >>n; file_in >>quad; // same resuly of file_in >> l >>m >>n; Triangles[i]=Triangle(); //initialise Triangles[i].SetTri(l,m,n); Triangles[i].SetQuad(quad); } for(int i=0; i<ntri;i++){ file_in >> l >> m >> n; Triangles[i].SetNeighb(l,m,n); } for(int i=0; i < n_nodes; i++){ NodeV[i]=D3Dvec(); file_in >> x >> y >> z; NodeV[i].SetVec(x,y,z); } istart=0; istop=ntri; /********************************************************************************** Calculate Metric Tensor **********************************************************************************/ double **Gmetric; Gmetric =(double**)calloc( ntri, sizeof( double[3] ) ); if(!Gmetric){ cout << "Memory Failed for Gmetric " << endl; exit(0);} // 2D vectors in each triangle double **avec, **bvec; avec=(double**)calloc( ntri, sizeof(double[2]) ); if(!avec){ cout << "Memory Failed for avec" << endl; exit(0);} bvec=(double**)calloc( ntri, sizeof(double[2]) ); if(!bvec){ cout << "Memory Failed for bvec" << endl; exit(0);} double avecdash[2], bvecdash[2]; double avecdash_new[2], bvecdash_new[2]; D3Dvec Ve1,Ve2,VOrig; //origin and edge vectors Ve1=D3Dvec(); Ve2=D3Dvec(); VOrig=D3Dvec(); //Initialise D3Dvec Unit_i, Unit_j, Unit_k; Unit_i=D3Dvec(); Unit_j=D3Dvec(); Unit_k=D3Dvec(); int i1,i2,i3; double rad=-1; for(int i=0; i<ntri; i++){ Gmetric[i]=new double[3]; //initialise i1=Triangles[i].Get1(); i2=Triangles[i].Get2(); i3=Triangles[i].Get3(); x=NodeV[i1].GetX(); y=NodeV[i1].GetY(); z=NodeV[i1].GetZ(); VOrig.SetVec(x,y,z); x=NodeV[i2].GetX()-VOrig.GetX(); y=NodeV[i2].GetY()-VOrig.GetY(); z=NodeV[i2].GetZ()-VOrig.GetZ(); Ve1.SetVec(x,y,z); x=NodeV[i3].GetX()-VOrig.GetX(); y=NodeV[i3].GetY()-VOrig.GetY(); z=NodeV[i3].GetZ()-VOrig.GetZ(); Ve2.SetVec(x,y,z); Gmetric[i][0]=Ve1.Dot(Ve1); Gmetric[i][1]=Ve1.Dot(Ve2); Gmetric[i][2]=Ve2.Dot(Ve2); rad=Gmetric[i][0]; rad=sqrt(rad)*6370.; // local cartesians Unit_i=Ve1; Normalise(Unit_i); Unit_k=Ve1*Ve2; Normalise(Unit_k); Unit_j=Unit_k*Unit_i; avec[i]=new double[2]; bvec[i]=new double[2]; avec[i][0]=Unit_i.Dot(Ve1); avec[i][1]=0.0; bvec[i][0]=Unit_i.Dot(Ve2); bvec[i][1]=Unit_j.Dot(Ve2); } /********************************************************************************** GEODESIC- start point **********************************************************************************/ // Now for a geodesic ! // int Tstart0=56; int Tstart, TNext; double xO,yO,zO; double x1,y1,z1; double x2,y2,z2; double x3,y3,z3; char qStart,qNext; double d1, d2, lambda; double d1dash,d2dash; double ds_total, ds_squared; double alpha_start, beta_start; double alphaTstart, betaTstart; //values of lambda to hit the line alpha=0, beta=0, alpha+beta=1 double Tol1=0.000001; // if fabs(d) less than this it lands on edge miles // away or never at all double Tol2=1e-8; //possibility that we land on a corner double alpha_e1, beta_e1; double alpha_e2, beta_e2; double alpha_e3, beta_e3; bool land_e1, land_e2, land_e3; double lambda_edge1, lambda_edge2, lambda_edge3; int Node1, Node2, Node3; double alphaNext,betaNext; double alpha_p, beta_p, alpha_q, beta_q; double alpha_p_dash, beta_p_dash, alpha_q_dash, beta_q_dash; double CosTheta,SinTheta,Theta,Phi; double adot_adash, adot_bdash, bdot_adash, bdot_bdash; double W1,W2,X1,X2,Y1,Y2,Z1,Z2,Det; double ex1,why1,ex2,why3; unsigned int ndim; int kount=0; Tstart=Tstart0; alpha_start=0.25, beta_start=0.25; d1=.25; d2=0.19; bool start_e1, start_e2, start_e3; start_e1=false; //assume that for first triangle start_e2=false; //we don't start off on an edge start_e3=false; //change for instance, if we have alpha_start=0 /********************************************************************************** GEODESIC- Propagate **********************************************************************************/ while(ds_total < 6.3 && kount < GeoPos){ if(kount==GeoPos-1){ cout <<"Last One! " << endl; } Node1=Triangles[Tstart].Get1(); Node2=Triangles[Tstart].Get2(); Node3=Triangles[Tstart].Get3(); D3Dvec Rnode1,Rnode2; Rnode1=D3Dvec(); Rnode2=D3Dvec(); xO=NodeV[Node1].GetX(); yO=NodeV[Node1].GetY(); zO=NodeV[Node1].GetZ(); VOrig.SetVec(xO,yO,zO); x1=NodeV[Node2].GetX(); y1=NodeV[Node2].GetY(); z1=NodeV[Node2].GetZ(); Rnode1.SetVec(x1,y1,z1); x2=NodeV[Node3].GetX(); y2=NodeV[Node3].GetY(); z2=NodeV[Node3].GetZ(); Rnode2.SetVec(x2,y2,z2); Ve1=Rnode1-VOrig; Ve2=Rnode2-VOrig; x3=VOrig.GetX()+alpha_start*Ve1.GetX()+beta_start*Ve2.GetX(); y3=VOrig.GetY()+alpha_start*Ve1.GetY()+beta_start*Ve2.GetY(); z3=VOrig.GetZ()+alpha_start*Ve1.GetZ()+beta_start*Ve2.GetZ(); Geodesy[kount]=new D3Dvec(); Geodesy[kount].SetX(x3); Geodesy[kount].SetY(y3); Geodesy[kount].SetZ(z3); cout << Geodesy[kount].GetX() << " " << Geodesy[kount].GetY() << " " << Geodesy[kount].GetZ() << " kount=" << kount << " Tstart=" << Tstart << endl; kount++; land_e1=false; land_e2=false; land_e3=false; //alpha_start + d1 lambda=0 lands on edge2; //beta_start+ d2 lambda=0 lands on edge1; if( fabs(d1) > Tol1){lambda_edge1=-beta_start/d2; land_e1=true;} if( fabs(d2) > Tol1){lambda_edge2=-alpha_start/d1; land_e2=true;} if( fabs(d2+d2) > Tol1) {lambda_edge3=(1.0-alpha_start-beta_start)/(d1+d2); land_e3=true;} cout << "d1=" << d1 << endl; cout << "d2=" << d2 << endl; cout << "alpha_s=" << alpha_start << endl; cout << "beta_s=" << beta_start << endl; alpha_e1=alpha_start+lambda_edge1*d1; beta_e1=beta_start+lambda_edge1*d2; alpha_e2=alpha_start+lambda_edge2*d1; beta_e2=beta_start+lambda_edge2*d2; alpha_e3=alpha_start+lambda_edge3*d1; beta_e3=beta_start+lambda_edge3*d2; ndim=2; Dmatrix Mat(ndim,ndim); //creates 4 by 3 on the heap. Dvector RHS(ndim); Dvector LHS(ndim); if( (fabs(alpha_e1) < Tol2) && (fabs(beta_e1) <Tol2) ){ // set it safely on edge 1 alpha_e1=2.*Tol2; beta_e1=0.0; } if( (fabs(1.0-alpha_e1) < Tol2) && (fabs(beta_e1) <Tol2) ){ // set it safely on edge 1 alpha_e1=1.0-2.0*Tol2; beta_e1=0.0; } if( (fabs(alpha_e2) < Tol2) && (fabs(beta_e2) <Tol2) ){ // set it safely on edge 2 alpha_e2=0.0; beta_e2=2.0*Tol2; } if( (fabs(1.0-beta_e2) < Tol2) && (fabs(alpha_e2) <Tol2) ){ // set it safely on edge 2 alpha_e2=0.0; beta_e2=1.0-2.0*Tol2; } if( (fabs(1.0-alpha_e3-beta_e3) < Tol2) ){ if(fabs(alpha_e3) < Tol2){ // set it safely on edge 3 alpha_e3=2.0*Tol2; beta_e3=1.0-alpha_e3; } if(fabs(beta_e3) < Tol2){ // set it safely on edge 3 beta_e3=2.0*Tol2; alpha_e3=1.0-beta_e3; } } /* cout << "e1 " << alpha_e1 << " L e1=" << lambda_edge1 << endl; cout << "e2 " << beta_e2 << " L_e2=" << lambda_edge2 << endl; cout << "a e3 " << alpha_e3 << " L_e3=" << lambda_edge3 << endl; cout << "b e3 " << beta_e3 << endl; */ if(lambda_edge1 <0.0 || alpha_e1 < 0.0 || alpha_e1 > 1.0)land_e1=false; if(lambda_edge2 <0.0 || beta_e2 < 0.0 || beta_e2 > 1.0)land_e2=false; if(lambda_edge3 <0.0 || alpha_e3 < 0.0 || alpha_e3 > 1.0)land_e3=false; if(lambda_edge3 <0.0 || beta_e3 < 0.0 || beta_e3 > 1.0)land_e3=false; cout << land_e1 << land_e2 << land_e3 << " edges 1 2 and 3" << endl; // Normally we land on two edges! // We start it some point in the start triangle // proceed to the edge, but now we start at an edge // if(start_e1)land_e1=false; if(start_e2)land_e2=false; if(start_e3)land_e3=false; start_e1=false; start_e2=false; start_e3=false; if(land_e1){ //beta_e1=0 ds_squared= Gmetric[Tstart][0]*(alpha_e1-alpha_start)*(alpha_e1-alpha_start) -2.0*Gmetric[Tstart][1]*(alpha_e1-alpha_start)*beta_start +Gmetric[Tstart][2]*beta_start*beta_start; ds_total=ds_total+sqrt(ds_squared); } if(land_e2){ //alpha_e1=0 ds_squared= Gmetric[Tstart][0]*alpha_start*alpha_start -2.0*Gmetric[Tstart][1]*alpha_start*(beta_e2-beta_start) +Gmetric[Tstart][2]*(beta_e2-beta_start)*(beta_e2-beta_start); ds_total=ds_total+sqrt(ds_squared); } if(land_e3){ ds_squared= Gmetric[Tstart][0]*(alpha_e3-alpha_start)*(alpha_e3-alpha_start) +2.0*Gmetric[Tstart][1]*(alpha_e3-alpha_start)*(beta_e3-beta_start) +Gmetric[Tstart][2]*(beta_e3-beta_start)*(beta_e3-beta_start); ds_total=ds_total+sqrt(ds_squared); } if( land_e1 )TNext=Triangles[Tstart].GetN1(); if( land_e2 )TNext=Triangles[Tstart].GetN2(); if( land_e3 )TNext=Triangles[Tstart].GetN3(); avecdash[0]=avec[TNext][0]; avecdash[1]=avec[TNext][1]; bvecdash[0]=bvec[TNext][0]; bvecdash[1]=bvec[TNext][1]; qStart=Triangles[Tstart].GetQuad(); qNext=Triangles[TNext].GetQuad(); // edge 1 always crosses into an edge 1 in the opposite sense if(land_e1){ alphaNext=1.0-alpha_e1; betaNext=0.0; start_e1=true; alpha_p=0.0; //edge 1 beta_p=0.0; alpha_q=1.0; beta_q=0.0; alpha_p_dash=alpha_q; // same edge, opposite sense beta_p_dash=beta_q; alpha_q_dash=alpha_p; beta_q_dash=beta_p; } // If the neighbour on edge 2 is in a different quad // it lands on edge 3, otherwise minus edge 2 if(land_e2){ alpha_p=0.0; beta_p=0.0; alpha_q=0.0; beta_q=1.0; if(qNext==qStart){ //crosses to edge 2 of neighbour- opposite sense betaNext=1.0-beta_e2; alphaNext=0.0; start_e2=true; alpha_p_dash=alpha_q; beta_p_dash=beta_q; alpha_q_dash=alpha_p; beta_q_dash=beta_p; } else { //crosses to edge 3 of neighbour- same sense. alphaNext=1.0-beta_e2; betaNext=beta_e2; start_e3=true; alpha_p_dash=1.0; beta_p_dash=0.0; alpha_q_dash=0.0; beta_q_dash=1.0; } } if(land_e3){ alpha_p=1.0; beta_p=0.0; alpha_q=0.0; beta_q=1.0; if(qNext==qStart){ //crosses to edge 3 of neighbour- opposite sense. alphaNext=1.0-alpha_e3; betaNext=alpha_e3; alpha_p_dash=alpha_q; beta_p_dash=beta_q; alpha_q_dash=alpha_p; beta_q_dash=beta_p; start_e3=true; } else { //crosses to edge 2 of neighbour -- has same sense alphaNext=0; betaNext=beta_e3; alpha_p_dash=0.0; beta_p_dash=0.0; alpha_q_dash=0.0; beta_q_dash=1.0; start_e2=true; } } cout << "ds_total=" << ds_total << endl; X1=alpha_p_dash*avecdash[0]+beta_p_dash*bvecdash[0]; X2=alpha_p_dash*avecdash[1]+beta_p_dash*bvecdash[1]; Y1=alpha_p*avec[Tstart][0]+beta_p*bvec[Tstart][0]; Y2=alpha_p*avec[Tstart][1]+beta_p*bvec[Tstart][1]; W1=alpha_q_dash*avecdash[0]+beta_q_dash*bvecdash[0]; W2=alpha_q_dash*avecdash[1]+beta_q_dash*bvecdash[1]; Z1=alpha_q*avec[Tstart][0]+beta_q*bvec[Tstart][0]; Z2=alpha_q*avec[Tstart][1]+beta_q*bvec[Tstart][1]; Det=(W2-X2)*(W2-X2)+(W1-X1)*(W1-X1); unsigned int ir,ic,ir1,ir2; ir=0; ic=0; Mat(ir,ic)=W1-X1; ir=0; ic=1; Mat(ir,ic)=W2-X2; ir=1; ic=0; Mat(ir,ic)=-(W2-X2); ir=1; ic=1; Mat(ir,ic)=W1-X1; Mat=Mat/Det; ir=0; RHS(ir)=Z1-Y1; ir=1; RHS(ir)=Z2-Y2; LHS=Mat*RHS; ir=0; CosTheta=LHS(ir); ir=1; SinTheta=LHS(ir); // cout << "cos and sin "<< CosTheta << " " << SinTheta << endl; // cout << "cossq+sinsq=" << CosTheta*CosTheta+SinTheta*SinTheta << endl; avecdash_new[0]= avecdash[0]*CosTheta-avecdash[1]*SinTheta; avecdash_new[1]= avecdash[0]*SinTheta+avecdash[1]*CosTheta; bvecdash_new[0]= bvecdash[0]*CosTheta-bvecdash[1]*SinTheta; bvecdash_new[1]= bvecdash[0]*SinTheta+bvecdash[1]*CosTheta; adot_adash=avec[Tstart][0]*avecdash_new[0] +avec[Tstart][1]*avecdash_new[1]; adot_bdash=avec[Tstart][0]*bvecdash_new[0] +avec[Tstart][1]*bvecdash_new[1]; bdot_adash=bvec[Tstart][0]*avecdash_new[0] +bvec[Tstart][1]*avecdash_new[1]; bdot_bdash=bvec[Tstart][0]*bvecdash_new[0] +bvec[Tstart][1]*bvecdash_new[1]; /* cout << adot_adash << " a dot adash " << avec[Tstart][0]*avecdash_new[0]+ avec[Tstart][1]*avecdash_new[1] << endl; cout << adot_bdash << " a dot bdash " << avec[Tstart][0]*bvecdash_new[0]+ avec[Tstart][1]*bvecdash_new[1] << endl; cout << bdot_adash << " b dot adash " << bvec[Tstart][0]*avecdash_new[0]+ bvec[Tstart][1]*avecdash_new[1] << endl; cout << bdot_bdash << " b dot bdash " << bvec[Tstart][0]*bvecdash_new[0]+ bvec[Tstart][1]*bvecdash_new[1] << endl; */ // The next couts all check out /* cout << " a dot a " << avec[Tstart][0]*avec[Tstart][0]+ avec[Tstart][1]*avec[Tstart][1] << endl; cout << " b dot b " << bvec[Tstart][0]*bvec[Tstart][0]+ bvec[Tstart][1]*bvec[Tstart][1] << endl; cout << " a dot a in Next " << avec[TNext][0]*avec[TNext][0]+ avec[TNext][1]*avec[TNext][1] << endl; cout << bdot_bdash << " b dot b in Next " << bvec[TNext][0]*bvec[TNext][0]+ bvec[TNext][1]*bvec[TNext][1] << endl; cout << "a " << avec[Tstart][0] << " " << avec[Tstart][1] << endl; cout << "b " << bvec[Tstart][0] << " " << bvec[Tstart][1] << endl; */ /* cout << "a dash " << avecdash[0] << " " << avecdash[1] << endl; cout << "b dash " << bvecdash[0] << " " << bvecdash[1] << endl; */ /* cout << "a dash rotate " << avecdash_new[0] << " " << avecdash_new[1] << endl; cout << "b dash rotate " << bvecdash_new[0] << " " << bvecdash_new[1] << endl; */ ir=0;ic=0; Mat(ir,ic)=Gmetric[Tstart][2]; ir=0;ic=1; Mat(ir,ic)=-Gmetric[Tstart][1]; ir=1;ic=0; Mat(ir,ic)=-Gmetric[Tstart][1]; ir=1;ic=1; Mat(ir,ic)=Gmetric[Tstart][0]; Det=Gmetric[Tstart][0]*Gmetric[Tstart][2] -Gmetric[Tstart][1]*Gmetric[Tstart][1]; Mat=Mat/Det; ir=0; RHS(ir)=adot_adash; ir=1; RHS(ir)=bdot_adash; LHS=Mat*RHS; ir=0; x1=LHS(ir); ir=1; y1=LHS(ir); ir=0; RHS(ir)=adot_bdash; ir=1; RHS(ir)=bdot_bdash; LHS=Mat*RHS; ir=0; x2=LHS(ir); ir=1; y2=LHS(ir); //check adash=x1 a + y1 b, bdash=x2 a+ y2 b cout << x1*avec[Tstart][0]+y1*bvec[Tstart][0] << " " << avecdash_new[0] << endl; cout << x1*avec[Tstart][1]+y1*bvec[Tstart][1] << " " << avecdash_new[1] << endl; cout << x2*avec[Tstart][0]+y2*bvec[Tstart][0] << " " << bvecdash_new[0] << endl; cout << x2*avec[Tstart][1]+y2*bvec[Tstart][1] << " " << bvecdash_new[1] << endl; ir=0;ic=0; Mat(ir,ic)=y2; ir=0;ic=1; Mat(ir,ic)=-x2; ir=1;ic=0; Mat(ir,ic)=-y1; ir=1;ic=1; Mat(ir,ic)=x1; Det=x1*y2-x2*y1; Mat=Mat/Det; cout << "M11=" << y2/Det << " M12=" << -x2/Det << endl; cout << "M21=" << -y1/Det << " M12=" << x1/Det << endl; ir=0; RHS(ir)=d1; ir=1; RHS(ir)=d2; LHS=Mat*RHS; ir=0; d1dash=LHS(ir); ir=1; d2dash=LHS(ir); // We have finally arrived in TNext, which will be the new Tstart; Tstart=TNext; alpha_start=alphaNext; beta_start=betaNext; d1=d1dash; d2=d2dash; } //end while ds_total Geokount=kount; cout << "Geokount=" << Geokount << endl; while(!quitit){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: quitit=true; break; case SDL_MOUSEBUTTONDOWN: mousedown=true; break; case SDL_MOUSEBUTTONUP: mousedown=false; break; case SDL_MOUSEMOTION: if(mousedown){ if(MouseOn)Camera1.MouseView();} else{ if(MouseOn)Camera1.MouseLookAt(); } break; case SDL_KEYDOWN: whatkey=&event.key.keysym; HandleKeyPress(whatkey); break; case SDL_KEYUP: whatkey=&event.key.keysym; HandleKeyRelease(whatkey); default: break; } // end of case } //end of inner loop CheckMove(Camera1); RenderScene(Camera1); } //end of outer loop }
void EventLoop(CCam & Camera1) { bool quitit=false; SDL_Event event; SDL_MouseMotionEvent event2; SDL_keysym *whatkey; bool mousedown=false; int n_nodes; bool old1,old2,old3; bool case0, case1, case2, case3, case4, case5, case6, case7; // Go to while(!quitit) to see what happens once data set up // Go to Render Scene for graphics bit // bool exitnow=false; extern double X,Y,Z; X=-1e32;Y=-1e-32;Z=-1e32; xmax=X; ymax=Y, zmax=Z; xmin=-X; ymin=-Y, zmin=-Z; double xunit,yunit,zunit; xunit=1.0;yunit=1.0;zunit=1.0; // (On ,my machine) very slow ndiv>9, pages memory // On Earth, ndiv=6 is the last stage where unsigned shorts // could be used for triangle and node numbers, and the length scale is ~200km. int ndiv=4; int Ttotal,Ntotal; Ttotal=8*(int)(pow(4,ndiv+1)-1)/3; Ntotal=4*(int)(pow(4,ndiv)-1)+6; int trinumbers[ndiv+1]; int nodenumbers[ndiv+1]; cout << "There will be " << endl; cout << Ttotal << " Triangles in total " << endl; cout << 3*pow(4,ndiv) << " new nodes in last subdivision " << endl; cout << Ntotal << " Nodes in total " << endl; trinumbers[0]=8; //initial octahedron nodenumbers[0]=6; int trinum=8; Triangles=(Triangle*) calloc( Ttotal ,sizeof(Triangle)); NodeV=(D3Dvec*)calloc( Ntotal, sizeof(D3Dvec)); for(int i=0; i<Ntotal; i++){ NodeV[i]=D3Dvec(); } //initialise or bust! for(int i=0; i<Ttotal; i++){ Triangles[i]=Triangle(); } //initialise cout << " Starting Subdivision " << endl; // if_stream opens for input // of_stream opens for output // f_stream opens for both // double x,y,z; // position vectors for basic octahedron x=0.0; y=-1.0; z=0.0; NodeV[0].SetVec(x,y,z); x=1.0; y=0.0; z=0.0; NodeV[1].SetVec(x,y,z); x=0.0; y=1.0; z=0.0; NodeV[2].SetVec(x,y,z); x=-1.0; y=0.0; z=0.0; NodeV[3].SetVec(x,y,z); x=0.0; y=0.0; z=1.0; NodeV[4].SetVec(x,y,z); x=0.0; y=0.0; z=-1.0; NodeV[5].SetVec(x,y,z); int in,jn,kn; char quad, otherquad; //node numbers for basic octahedron quad=1; in=1-1;jn=2-1;kn=5-1; Triangles[0].SetTri(in, jn, kn); Triangles[0].SetQuad(quad); quad=2; in=2-1;jn=3-1;kn=5-1; Triangles[1].SetTri(in, jn, kn); Triangles[1].SetQuad(quad); quad=3; in=3-1;jn=4-1;kn=5-1; Triangles[2].SetTri(in, jn, kn); Triangles[2].SetQuad(quad); quad=4; in=4-1;jn=1-1;kn=5-1; Triangles[3].SetTri(in, jn, kn); Triangles[3].SetQuad(quad); quad=1; in=2-1;jn=1-1;kn=6-1; Triangles[4].SetTri(in, jn, kn); Triangles[4].SetQuad(quad); quad=2; in=3-1;jn=2-1;kn=6-1; Triangles[5].SetTri(in, jn, kn); Triangles[5].SetQuad(quad); quad=3; in=4-1;jn=3-1;kn=6-1; Triangles[6].SetTri(in, jn, kn); Triangles[6].SetQuad(quad); quad=4; in=1-1;jn=4-1;kn=6-1; Triangles[7].SetTri(in, jn, kn); Triangles[7].SetQuad(quad); //Neighbours for each edge of each triangle //Triangle edges in triangle are the edge number //of the edge in the NEIGHBOUR // //For instance Edge 1 of first triangle //is edge 1 of triangle 5, but in opposite direction in=5-1;jn=4-1;kn=2-1; Triangles[0].SetNeighb(in, jn, kn); in=6-1;jn=1-1;kn=3-1; Triangles[1].SetNeighb(in, jn, kn); in=7-1;jn=2-1;kn=4-1; Triangles[2].SetNeighb(in, jn, kn); in=8-1;jn=3-1;kn=1-1; Triangles[3].SetNeighb(in, jn, kn); // ********************************************* in=1-1;jn=6-1;kn=8-1; Triangles[4].SetNeighb(in, jn, kn); in=2-1;jn=7-1;kn=5-1; Triangles[5].SetNeighb(in, jn, kn); in=3-1;jn=8-1;kn=6-1; Triangles[6].SetNeighb(in, jn, kn); in=4-1;jn=5-1;kn=7-1; Triangles[7].SetNeighb(in, jn, kn); ntri=8; n_nodes=6; ntrinew=0; //we have 8 triangles and 6 nodes n_nodes=n_nodes-1; // 6 nodes 0-5 int *pSplit0,*pSplit1,*pSplit2,*pSplit3; bool split_this; int in1,in2,in3; int is1,is2; int nn1,nn2,nn3; int inode1,inode2,inode3; int new0,new1,new2,new3; //serves for new node or triangle numbers int new1N,new2N,new3N; istart=0; istop=8; // split all triangles at this level if the neighbours // are on the same level. Then every split triangle // has an unsplit neighbour and vice versa // //recursive subdivision // for(int idiv=0; idiv <ndiv; idiv++){ ntrinew=0; nnodenew=0; for(int itri=istart;itri<istop;itri++){ if( Triangles[itri].GetN() ){ in1=Triangles[itri].GetN1(); in2=Triangles[itri].GetN2(); in3=Triangles[itri].GetN3(); } else { cout <<" No Neighbours " << endl; exit(0); } pSplit0=Triangles[itri].GetS(); pSplit1=Triangles[in1].GetS(); pSplit2=Triangles[in2].GetS(); pSplit3=Triangles[in3].GetS(); if(!pSplit0){split_this=true;} else {split_this=false;} if(split_this){ // Split This Triangle into 4 with three new nodes bool NodeExists1=false; bool NodeExists2=false; bool NodeExists3=false; if(pSplit3)NodeExists1=true; if(pSplit2)NodeExists2=true; if(pSplit1)NodeExists3=true; int oldnode1=-1,oldnode2=-1,oldnode3=-1; old1=false; old2=false; old3=false; // nodes of internal triangle to current replacement // in current leve; if(NodeExists1){ // split exists on edge 3 of current T quad=Triangles[itri].GetQuad(); otherquad=Triangles[in3].GetQuad(); if(quad != otherquad){ oldnode1= Triangles[Triangles[in3].GetS2()].Get3();} else { oldnode1= Triangles[Triangles[in3].GetS3()].Get3();} old1=true; } if(NodeExists2){ // split exists on edge 2 of current T // quad=Triangles[itri].GetQuad(); otherquad=Triangles[in2].GetQuad(); if(quad != otherquad){ oldnode2= Triangles[Triangles[in2].GetS3()].Get3(); } else { oldnode2= Triangles[Triangles[in2].GetS2()].Get3(); } old2=true; } if(NodeExists3){ // edge 1 always matches edge1 oldnode3= Triangles[Triangles[in1].GetS2()].Get2(); old3=true; } if(oldnode1 < 0){ n_nodes++; nnodenew++; NodeV[n_nodes].SetX( NodeV[ Triangles[itri].Get2() ].GetX() +( NodeV[ Triangles[itri].Get3() ].GetX() -NodeV[ Triangles[itri].Get2() ].GetX() )/2.0 ); NodeV[n_nodes].SetY( NodeV[ Triangles[itri].Get2() ].GetY() +( NodeV[ Triangles[itri].Get3() ].GetY() -NodeV[ Triangles[itri].Get2() ].GetY() )/2.0 ); NodeV[n_nodes].SetZ( NodeV[ Triangles[itri].Get2() ].GetZ() +( NodeV[ Triangles[itri].Get3() ].GetZ() -NodeV[ Triangles[itri].Get2() ].GetZ() )/2.0 ); // Normalise(NodeV[n_nodes]); } if(oldnode2 < 0){ n_nodes++; nnodenew++; NodeV[n_nodes].SetX( NodeV[ Triangles[itri].Get1() ].GetX() +( NodeV[ Triangles[itri].Get3() ].GetX() -NodeV[ Triangles[itri].Get1() ].GetX() )/2.0 ); NodeV[n_nodes].SetY( NodeV[ Triangles[itri].Get1() ].GetY() +( NodeV[ Triangles[itri].Get3() ].GetY() -NodeV[ Triangles[itri].Get1() ].GetY() )/2.0 ); NodeV[n_nodes].SetZ( NodeV[ Triangles[itri].Get1() ].GetZ() +( NodeV[ Triangles[itri].Get3() ].GetZ() -NodeV[ Triangles[itri].Get1() ].GetZ() )/2.0 ); // Normalise(NodeV[n_nodes]); } if(oldnode3 < 0){ n_nodes++; nnodenew++; NodeV[n_nodes].SetX( NodeV[ Triangles[itri].Get1() ].GetX() +( NodeV[ Triangles[itri].Get2() ].GetX() -NodeV[ Triangles[itri].Get1() ].GetX() )/2.0 ); NodeV[n_nodes].SetY( NodeV[ Triangles[itri].Get1() ].GetY() +( NodeV[ Triangles[itri].Get2() ].GetY() -NodeV[ Triangles[itri].Get1() ].GetY() )/2.0 ); NodeV[n_nodes].SetZ( NodeV[ Triangles[itri].Get1() ].GetZ() +( NodeV[ Triangles[itri].Get2() ].GetZ() -NodeV[ Triangles[itri].Get1() ].GetZ() )/2.0 ); // Normalise(NodeV[n_nodes]); } isplit=istop+ntrinew; new0=isplit; new1=isplit+1; new2=isplit+2; new3=isplit+3; Triangles[itri].SetSplit( new0, new1, new2, new3); if(old1)inode1=oldnode1; if(old2)inode2=oldnode2; if(old3)inode3=oldnode3; case0=false; case1=false; case2=false; case3=false; case4=false; case5=false; case6=false; case7=false; if( !old1 && !old2 && !old3)case0=true; if( old1 && old2 && old3)case7=true; if(case0 ){ inode1=n_nodes-2; inode2=n_nodes-1; inode3=n_nodes-0; } if(case7){ inode1=oldnode1; inode2=oldnode2; inode3=oldnode3; } if(!case0 && !case7) { if(old1){ if(old2 || old3){ if(old2){ case4=true; // nodes 1 and 2 exist inode1=oldnode1; inode2=oldnode2; inode3=n_nodes-0; } else { case6=true; // nodes 1 and 3 exist inode1=oldnode1; inode2=n_nodes-0; inode3=oldnode3; } } else { case1=true; //only node 1 exists inode1=oldnode1; inode2=n_nodes-1; inode3=n_nodes-0; } }//endif old1 if(old2){ if(!old1){ // case 4 done above if(old3){ case5=true; //nodes 2 and 3 exist inode1=n_nodes-0; inode2=oldnode2; inode3=oldnode3; } else { case2=true; //only node 2 exists inode1=n_nodes-1; inode2=oldnode2; inode3=n_nodes-0; } } } //endif old2 if(old3){ if( !old1 && !old2){ // 1 and 3 and 2 and 3 done already case3=true; inode1=n_nodes-1; inode2=n_nodes-0; inode3=oldnode3; } } } //endif (NOT case 0) AND (NOT case 7) quad=Triangles[itri].GetQuad(); Triangles[new0].SetTri(inode1, inode2, inode3); //Centre T Triangles[new0].SetQuad(quad); Triangles[new1].SetTri(Triangles[itri].Get1(), inode3, inode2); Triangles[new1].SetQuad(quad); Triangles[new2].SetTri(inode3, Triangles[itri].Get2(), inode1); Triangles[new2].SetQuad(quad); Triangles[new3].SetTri(inode2, inode1, Triangles[itri].Get3()); Triangles[new3].SetQuad(quad); //Set Neighbours for centre Triangle; new1N=new3; new2N=new2; new3N=new1; Triangles[new0].SetNeighb(new1N,new2N,new3N); Triangles[new1].SetN3(new0); Triangles[new2].SetN2(new0); Triangles[new3].SetN1(new0); if(pSplit1){ // have split neighbours on edge 1 // These are is1=Triangles[in1].GetS3(); is2=Triangles[in1].GetS2(); Triangles[new1].SetN1(is1); Triangles[new2].SetN1(is2); Triangles[is1].SetN1(new1); Triangles[is2].SetN1(new2); //independent of quadrant } if(pSplit2){ // have split neighbours on edge 2 // These are quad=Triangles[itri].GetQuad(); otherquad=Triangles[in2].GetQuad(); if(quad != otherquad){ is1=Triangles[in2].GetS3(); is2=Triangles[in2].GetS4(); } else { is1=Triangles[in2].GetS4(); is2=Triangles[in2].GetS2(); } if(quad != otherquad){ Triangles[is1].SetN3(new1); Triangles[is2].SetN3(new3); } else { Triangles[is1].SetN2(new1); Triangles[is2].SetN2(new3); } Triangles[new1].SetN2(is1); Triangles[new3].SetN2(is2); } if(pSplit3){ // have split neighbours on edge 3 // These are quad=Triangles[itri].GetQuad(); otherquad=Triangles[in3].GetQuad(); if(quad != otherquad){ is1=Triangles[in3].GetS2(); is2=Triangles[in3].GetS4(); } else { is1=Triangles[in3].GetS4(); is2=Triangles[in3].GetS3(); } if(quad != otherquad){ Triangles[is1].SetN2(new2); Triangles[is2].SetN2(new3); } else { Triangles[is1].SetN3(new2); Triangles[is2].SetN3(new3); } Triangles[new2].SetN3(is1); Triangles[new3].SetN3(is2); } ntrinew=ntrinew+4; } //endif neighbours unsplit } //end loop over tranche of triangles istart=istop; istop=istop+ntrinew; // cout << " new istart=" << istart << endl; // cout << "new istop=" << istop << endl; trinumbers[idiv+1]=ntrinew; nodenumbers[idiv+1]=n_nodes; trinum=trinum+ntrinew; cout << " There are " << ntrinew << " new Triangles in this subdivision"<<endl; cout << " There are " << trinum << " Triangles in total "<<endl; cout << " There are " << nnodenew << " new nodes in this subdivision "<< endl; cout << " There are " << n_nodes+1 << " Nodes in total "<<endl; cout << "idiv=" << idiv << endl; int ie1, ie2, ie3, ie4; //check connections! cout << "ISTART ISTOP " << istart << " " << istop << endl; for(int i=0; i< n_nodes; i++) Normalise(NodeV[i]); } // only cehck if we suspect something wrong! /* for(int itri=istart; itri < istop; itri++){ // cout << "Checking T" << itri << endl; in1=Triangles[itri].GetN1(); in2=Triangles[itri].GetN2(); in3=Triangles[itri].GetN3(); ie1=Triangles[itri].Get1(); //across edge 1 ie2=Triangles[itri].Get2(); ie3=Triangles[in1].Get1(); // Allways Opposite ie4=Triangles[in1].Get2(); if( ie1 != ie4)cout << " edge mismatch 1 " << "Ts " << itri << " " << in1 << " " << ie1 << " " << ie2 << " in " << itri << " and " << ie3 << " " << ie4 << endl; ie1=Triangles[itri].Get1(); // across edge 2 ie2=Triangles[itri].Get3(); quad=Triangles[itri].GetQuad(); otherquad=Triangles[in2].GetQuad(); if(quad != otherquad){ ie3=Triangles[in2].Get3(); ie4=Triangles[in2].Get2();} // Same directions else { ie3=Triangles[in2].Get1(); ie4=Triangles[in2].Get3(); //Opposite directions } if( ie1 != ie4)cout << " edge mismatch 2 " << "Ts " << itri << " " << in1 << " " << ie1 << " " << ie2 << " in " << itri << " and " << ie3 << " " << ie4 << " " << in2 << " quads are " << (int)quad << " " << (int)otherquad <<endl; ie1=Triangles[itri].Get2(); //across edge 3 ie2=Triangles[itri].Get3(); quad=Triangles[itri].GetQuad(); otherquad=Triangles[in3].GetQuad(); if(quad != otherquad){ ie3=Triangles[in3].Get3(); // Same directions ie4=Triangles[in3].Get1(); } else { ie3=Triangles[in3].Get2(); ie4=Triangles[in3].Get3(); // Opposite directions } if( ie1 != ie4)cout << " edge mismatch 3 " << "Ts " << itri << " " << in1 << " " << ie1 << " " << ie2 << " in " << itri << " and " << ie3 << " " << ie4 << " " << in2 << " quads are " << (int)quad << " " << (int)otherquad <<endl; } */ /* for(int i=0; i<idiv+1; i++){ cout << " Node Numbers and Tri Numbers" << endl; cout << nodenumbers[i] << " " << trinumbers[i] << endl; } */ /* cout << " nodes and triangles " << n_nodes << " " << trinum << endl; cout << 4*(pow(4,ndiv)-1)+6 << " nodes in total " << n_nodes << endl; cout << ntrinew << " new Triangles in last division" << endl; cout << Ttotal << " Total number of triangles at all levels" << endl; } */ cout << " calculate metric" << endl; double **Gmetric; Gmetric =(double**)calloc( Ttotal, sizeof( double[3] ) ); if(!Gmetric){ cout << "Memory Failed for Gmetric " << endl; exit(0);} // double Gmetric[Ttotal][3]; D3Dvec Va1,Vb1,VOrig; D3Dvec Va2,Vb2; //used later but declare and initialise here Va1=D3Dvec(); Vb1=D3Dvec(); Va2=D3Dvec(); Vb2=D3Dvec(); VOrig=D3Dvec(); double ex,why,zed; int i1,i2,i3; double rad=-1; for(int i=Ttotal-ntrinew; i<Ttotal; i++){ Gmetric[i]=new double[3]; i1=Triangles[i].Get1(); i2=Triangles[i].Get2(); i3=Triangles[i].Get3(); x=NodeV[i1].GetX(); y=NodeV[i1].GetY(); z=NodeV[i1].GetZ(); VOrig.SetVec(x,y,z); x=NodeV[i2].GetX()-VOrig.GetX(); y=NodeV[i2].GetY()-VOrig.GetY(); z=NodeV[i2].GetZ()-VOrig.GetZ(); Va1.SetVec(x,y,z); x=NodeV[i3].GetX()-VOrig.GetX(); y=NodeV[i3].GetY()-VOrig.GetY(); z=NodeV[i3].GetZ()-VOrig.GetZ(); Vb1.SetVec(x,y,z); Gmetric[i][0]=Va1.Dot(Va1); Gmetric[i][1]=Va1.Dot(Vb1); Gmetric[i][2]=Va1.Dot(Vb1); rad=Gmetric[i][0]; rad=sqrt(rad)*6370.; } // NodeV[0], NodeV[1], .... NodeV[n_nodes] is n_nodes+1 nodes n_nodes=n_nodes+1; cout << "There were " << ntrinew << " new triangles in last subdivision" << endl; cout << "There should be " << endl; cout << Ttotal << " Triangles in total, there are " << istop << endl; cout << 3*(int)pow(4,ndiv) << " new nodes in last subdivision " << endl; cout << Ntotal << " Nodes in total, there are " << n_nodes << endl; cout << ntrinew << " triangles, length scales of order " << rad << " km for Earth" << endl; cout << "They are Triangles T[" << Ttotal-ntrinew <<"] " << " to Triangles T[" << Ttotal <<"] " << endl; // Now for a geodesic ! // // In this specific example we expect ndiv=4 if(ndiv==4){ int Tlow=680; //triangle number range for ndiv=4 int Thigh=2728; int Tstart0=1222; int Tstart, NextT; double xO,yO,zO; double x1,y1,z1; double x2,y2,z2; char qStart,qNext; double d1, d2, lambda; double ds_total, ds_squared; bool escape; double alpha_exit, beta_exit; double alpha_start, beta_start; double alphaTstart, betaTstart; // values of lambda to hit the line alpha=0, beta=0, alpha+beta=1. double Tol1=0.000001; // if fabs(d) less than this it lands on edge miles away or never at all double Tol2=1e-8; //possibility that we land on a corner double alpha_e1, beta_e1; double alpha_e2, beta_e2; double alpha_e3, beta_e3; bool land_e1, land_e2, land_e3; double lambda_edge1, lambda_edge2, lambda_edge3; int Node1, Node2, Node3; Tstart=Tstart0; Node1=Triangles[Tstart].Get1(); Node2=Triangles[Tstart].Get2(); Node3=Triangles[Tstart].Get2(); D3Dvec Rnode1,Rnode2,Rnode3; Rnode1=D3Dvec(); Rnode2=D3Dvec(); Rnode3=D3Dvec(); xO=NodeV[Node1].GetX(); yO=NodeV[Node1].GetY(); zO=NodeV[Node1].GetZ(); VOrig.SetVec(xO,yO,zO); x1=NodeV[Node2].GetX(); y1=NodeV[Node2].GetY(); z1=NodeV[Node2].GetZ(); Rnode1.SetVec(x1,y1,z1); x2=NodeV[Node3].GetX(); y2=NodeV[Node3].GetY(); z2=NodeV[Node3].GetZ(); Rnode2.SetVec(x2,y2,z2); Va1=Rnode2-Rnode1; Vb1=Rnode3-Rnode1; alpha_start=0.25, beta_start=0.25; d1=.5; d2=0.25; land_e1=false; land_e2=false; land_e3=false; //alpha_start + d1 lambda=0 lands on edge2; //beta_start+ d2 lambda=0 lands on edge1; if( fabs(d1) > Tol1){lambda_edge1=-beta_start/d2; land_e1=true;} if( fabs(d2) > Tol1){lambda_edge2=-alpha_start/d1; land_e2=true;} if( fabs(d2+d2) > Tol1) {lambda_edge3=(1.0-alpha_start-beta_start)/(d1+d2); land_e3=true;} cout << "d1=" << d1 << endl; cout << "d2=" << d2 << endl; cout << "alpha_s=" << alpha_start << endl; cout << "beta_s=" << beta_start << endl; alpha_e1=alpha_start+lambda_edge1*d1; beta_e1=beta_start+lambda_edge1*d2; alpha_e2=alpha_start+lambda_edge2*d1; beta_e2=beta_start+lambda_edge2*d2; alpha_e3=alpha_start+lambda_edge3*d1; beta_e3=beta_start+lambda_edge3*d2; if( (fabs(alpha_e1) < Tol2) && (fabs(beta_e1) <Tol2) ){ // set it safely on edge 1 alpha_e1=2.*Tol2; beta_e1=0.0; } if( (fabs(1.0-alpha_e1) < Tol2) && (fabs(beta_e1) <Tol2) ){ // set it safely on edge 1 alpha_e1=1.0-2.0*Tol2; beta_e1=0.0; } if( (fabs(alpha_e2) < Tol2) && (fabs(beta_e2) <Tol2) ){ // set it safely on edge 2 alpha_e2=0.0; beta_e2=2.0*Tol2; } if( (fabs(1.0-beta_e2) < Tol2) && (fabs(alpha_e2) <Tol2) ){ // set it safely on edge 2 alpha_e2=0.0; beta_e2=1.0-2.0*Tol2; } if( (fabs(1.0-alpha_e3-beta_e3) < Tol2) ){ if(fabs(alpha_e3) < Tol2){ // set it safely on edge 3 alpha_e3=2.0*Tol2; beta_e3=1.0-alpha_e3; } if(fabs(beta_e3) < Tol2){ // set it safely on edge 3 beta_e3=2.0*Tol2; alpha_e3=1.0-beta_e3; } } /* cout << "e1 " << alpha_e1 << " L e1=" << lambda_edge1 << endl; cout << "e2 " << beta_e2 << " L_e2=" << lambda_edge2 << endl; cout << "a e3 " << alpha_e3 << " L_e3=" << lambda_edge3 << endl; cout << "b e3 " << beta_e3 << endl; */ if(lambda_edge1 <0.0 || alpha_e1 < 0.0 || alpha_e1 > 1.0)land_e1=false; if(lambda_edge2 <0.0 || beta_e2 < 0.0 || beta_e2 > 1.0)land_e2=false; if(lambda_edge3 <0.0 || alpha_e3 < 0.0 || alpha_e3 > 1.0)land_e3=false; if(lambda_edge3 <0.0 || beta_e3 < 0.0 || beta_e3 > 1.0)land_e3=false; cout << land_e1 << land_e2 << land_e3 << endl; escape=false; if(land_e1){ //beta_e1=0 ds_squared= Gmetric[Tstart][0]*(alpha_e1-alpha_start)*(alpha_e1-alpha_start) -2.0*Gmetric[Tstart][1]*(alpha_e1-alpha_start)*beta_start +Gmetric[Tstart][2]*beta_start*beta_start; ds_total=ds_total+sqrt(ds_squared); escape=true; alpha_exit=alpha_e1; beta_exit=0.0; } if(land_e2){ //alpha_e1=0 ds_squared= Gmetric[Tstart][0]*alpha_start*alpha_start -2.0*Gmetric[Tstart][1]*alpha_start*(beta_e2-beta_start) +Gmetric[Tstart][2]*(beta_e2-beta_start)*(beta_e2-beta_start); ds_total=ds_total+sqrt(ds_squared); escape=true; beta_exit=beta_e2; alpha_exit=0; } if(land_e3){ ds_squared= Gmetric[Tstart][0]*(alpha_e3-alpha_start)*(alpha_e3-alpha_start) +2.0*Gmetric[Tstart][1]*(alpha_e3-alpha_start)*(beta_e3-beta_start) +Gmetric[Tstart][2]*(beta_e3-beta_start)*(beta_e3-beta_start); ds_total=ds_total+sqrt(ds_squared); escape=true; beta_exit=beta_e3; alpha_exit=alpha_e3; } if( land_e1 )NextT=Triangles[Tstart].Get1(); if( land_e2 )NextT=Triangles[Tstart].Get2(); if( land_e3 )NextT=Triangles[Tstart].Get3(); qStart=Triangles[Tstart].GetQuad(); qNext=Triangles[Tstart].GetQuad(); // edge 1 always crosses into an edge 1 in the opposite sense /* if(land_e1){ alphaNext=1.0-alpha_e1; betaNext=0.0; */ /* * alpha_a=0.0; beta_a=0.0; alpha_b=1.0; beta_b=0.0; alpha_a_dash=alpha_b beta_a_dash=beta_b; } /* if(land_e2){ if(qNext==qStart){ betaNext=1.0-beta_e2; alphaNext=0.0; } else { //crosses to edge 3 of neighbour alphaNext=1.0-alpha_e2; betaNext=alpha_e2 } } if(land_e3){ if(qNext==qStart){ alphaNext=1.0-alpha_e3; betaNext=alphaa_e2; } else { //crosses to edge 3 of neighbour -- has same sense alphaNext=alpha_e3; betaNext=beta_e3 } } */ } else { cout << "This code only propagates a geodesic if ndiv=4" << endl; } while(!quitit){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: quitit=true; break; case SDL_MOUSEBUTTONDOWN: mousedown=true; break; case SDL_MOUSEBUTTONUP: mousedown=false; break; case SDL_MOUSEMOTION: if(mousedown){ if(MouseOn)Camera1.MouseView();} else{ if(MouseOn)Camera1.MouseLookAt(); } break; case SDL_KEYDOWN: whatkey=&event.key.keysym; HandleKeyPress(whatkey); break; case SDL_KEYUP: whatkey=&event.key.keysym; HandleKeyRelease(whatkey); default: break; } // end of case } //end of inner loop CheckMove(Camera1); RenderScene(Camera1); } //end of outer loop }
void EventLoop(CCam & Camera1) { bool quitit=false; SDL_Event event; SDL_MouseMotionEvent event2; SDL_keysym *whatkey; bool mousedown=false; int n_nodes; bool old1,old2,old3; bool case0, case1, case2, case3, case4, case5, case6, case7; // Go to while(!quitit) to see what happens once data set up // Go to Render Scene for graphics bit bool exitnow=false; extern double X,Y,Z; X=-1e32;Y=-1e-32;Z=-1e32; xmax=X; ymax=Y, zmax=Z; xmin=-X; ymin=-Y, zmin=-Z; double xunit,yunit,zunit; xunit=1.0;yunit=1.0;zunit=1.0; fstream infile1,infile2; infile1.open("Node.dat", ios::in); infile2.open("Tri.dat", ios::in); double lati, longi; double x,y,z; int Ttotal, Ntotal, ndiv; ndiv=4; Ttotal=20*(int)(pow(4,ndiv+1)-1); Ntotal=(int)(pow(2,2*ndiv)); Ntotal=10*Ntotal+2; Triangles=(Triangle*)calloc(Ttotal, sizeof(Triangle)); NodeV=(D3Dvec*)calloc(Ntotal, sizeof(D3Dvec)); //INITIALISE USING CONSTRUCTOR for(int i=0; i< Ttotal; i++){ Triangles[i]=Triangle(); } for(int i=0; i< Ntotal; i++){ NodeV[i]=D3Dvec(); } // position vectors for basic icosahedron for(int i=0; i< 12; i++){ infile1 >> lati >> longi; x=cos(lati)*cos(longi); y=cos(lati)*sin(longi); z=sin(lati); NodeV[i].SetVec(x,y,z); } int in,jn,kn; char quad, otherquad; for(int i=0; i< 20; i++){ infile2 >> in >> jn >> kn; in=in-1; jn=jn-1; kn=kn-1; Triangles[i].SetTri(in, jn, kn); quad=i; Triangles[i].SetQuad(quad); } //Neighbours for each edge of each triangle //Triangle edges in triangle are the edge number //of the edge in the NEIGHBOUR // //For instance Edge 1 of first triangle //is edge 1 of triangle 5, but in opposite direction // ********************************************* in=6-1;jn=2-1;kn=5-1; Triangles[0].SetNeighb(in, jn, kn); in=7-1;jn=3-1;kn=1-1; Triangles[1].SetNeighb(in, jn, kn); in=8-1;jn=4-1;kn=2-1; Triangles[2].SetNeighb(in, jn, kn); in=9-1;jn=5-1;kn=3-1; Triangles[3].SetNeighb(in, jn, kn); in=10-1;jn=1-1;kn=4-1; Triangles[4].SetNeighb(in, jn, kn); // ********************************************* in=1-1;jn=11-1;kn=12-1; Triangles[5].SetNeighb(in, jn, kn); in=2-1;jn=12-1;kn=13-1; Triangles[6].SetNeighb(in, jn, kn); in=3-1;jn=13-1;kn=14-1; Triangles[7].SetNeighb(in, jn, kn); in=4-1;jn=14-1;kn=15-1; Triangles[8].SetNeighb(in, jn, kn); in=5-1;jn=15-1;kn=11-1; Triangles[9].SetNeighb(in, jn, kn); // ********************************************* in=18-1;jn=6-1;kn=10-1; Triangles[10].SetNeighb(in, jn, kn); in=19-1;jn=7-1;kn=6-1; Triangles[11].SetNeighb(in, jn, kn); in=20-1;jn=8-1;kn=7-1; Triangles[12].SetNeighb(in, jn, kn); in=16-1;jn=9-1;kn=8-1; Triangles[13].SetNeighb(in, jn, kn); in=17-1;jn=10-1;kn=9-1; Triangles[14].SetNeighb(in, jn, kn); // ********************************************* in=14-1;jn=20-1;kn=17-1; Triangles[15].SetNeighb(in, jn, kn); in=15-1;jn=16-1;kn=18-1; Triangles[16].SetNeighb(in, jn, kn); in=11-1;jn=17-1;kn=19-1; Triangles[17].SetNeighb(in, jn, kn); in=12-1;jn=18-1;kn=20-1; Triangles[18].SetNeighb(in, jn, kn); in=13-1;jn=19-1;kn=16-1; Triangles[19].SetNeighb(in, jn, kn); // ********************************************* ntri=20; n_nodes=12; ntrinew=0; //we have 8 triangles and 6 nodes ofstream file_out; file_out.open("Sphere0.dat", ios::out); //can habe ios::app for appending file_out << n_nodes <<" "<< ntri << " number of nodes, number of triangles" << endl; //output triangle number, 3 node numbers, and quadrant id for(int i=0; i<ntri; i++){ file_out << i <<" "<< Triangles[i].Get1() <<" "<< Triangles[i].Get2() <<" "<< Triangles[i].Get3() <<" "<< Triangles[i].GetQuad() <<" "<< endl; } //output triangle neighbours on edges 1 2 and 3. for(int i=0; i<ntri; i++){ file_out << Triangles[i].GetN1()-istop <<" "<< Triangles[i].GetN2()-istop <<" "<< Triangles[i].GetN3()-istop << endl; } //output x,y,z coordinates of nodes. for(int i=0; i< n_nodes; i++){ file_out << i <<" "<< NodeV[i].GetX() <<" "<< NodeV[i].GetY() <<" "<< NodeV[i].GetZ() << endl; } file_out.close(); n_nodes=n_nodes-1; // 12 nodes 0-11 int *pSplit0,*pSplit1,*pSplit2,*pSplit3; bool split_this; int in1,in2,in3; int is1,is2; int nn1,nn2,nn3; int inode1,inode2,inode3; int new0,new1,new2,new3; //serves for new node or triangle numbers int new1N,new2N,new3N; istart=0; istop=20; // split all triangles at this level if the neighbours // are on the same level. Then every split triangle // has an unsplit neighbour and vice versa // //recursive subdivision // char* filename[5]; for(int idiv=0; idiv < ndiv; idiv++){ ntrinew=0; for(int itri=istart;itri<istop;itri++){ if( Triangles[itri].GetN() ){ in1=Triangles[itri].GetN1(); in2=Triangles[itri].GetN2(); in3=Triangles[itri].GetN3(); } else { cout <<" No Neighbours " << endl; exit(0); } pSplit0=Triangles[itri].GetS(); pSplit1=Triangles[in1].GetS(); pSplit2=Triangles[in2].GetS(); pSplit3=Triangles[in3].GetS(); if(!pSplit0){split_this=true;} else {split_this=false;} if(split_this){ // Split This Triangle into 4 with three new nodes bool NodeExists1=false; bool NodeExists2=false; bool NodeExists3=false; if(pSplit3)NodeExists1=true; if(pSplit2)NodeExists2=true; if(pSplit1)NodeExists3=true; int oldnode1=-1,oldnode2=-1,oldnode3=-1; old1=false; old2=false; old3=false; // nodes of internal triangle to current replacement // in current leve; if(NodeExists1){ // split exists on edge 3 of current T quad=Triangles[itri].GetQuad(); otherquad=Triangles[in3].GetQuad(); iquad=(int)quad; if(iquad > 4 && iquad <15)otherquad=quad; if(quad != otherquad){ oldnode1= Triangles[Triangles[in3].GetS2()].Get3();} else { oldnode1= Triangles[Triangles[in3].GetS3()].Get3();} old1=true; } if(NodeExists2){ // split exists on edge 2 of current T // quad=Triangles[itri].GetQuad(); otherquad=Triangles[in2].GetQuad(); iquad=(int)quad; if(iquad > 4 && iquad <15)otherquad=quad; if(quad != otherquad){ oldnode2= Triangles[Triangles[in2].GetS3()].Get3(); } else { oldnode2= Triangles[Triangles[in2].GetS2()].Get3(); } old2=true; } if(NodeExists3){ // edge 1 always matches edge1 oldnode3= Triangles[Triangles[in1].GetS2()].Get2(); old3=true; } if(oldnode1 < 0){ n_nodes++; NodeV[n_nodes].SetX( NodeV[ Triangles[itri].Get2() ].GetX() +( NodeV[ Triangles[itri].Get3() ].GetX() -NodeV[ Triangles[itri].Get2() ].GetX() )/2.0 ); NodeV[n_nodes].SetY( NodeV[ Triangles[itri].Get2() ].GetY() +( NodeV[ Triangles[itri].Get3() ].GetY() -NodeV[ Triangles[itri].Get2() ].GetY() )/2.0 ); NodeV[n_nodes].SetZ( NodeV[ Triangles[itri].Get2() ].GetZ() +( NodeV[ Triangles[itri].Get3() ].GetZ() -NodeV[ Triangles[itri].Get2() ].GetZ() )/2.0 ); } if(oldnode2 < 0){ n_nodes++; NodeV[n_nodes].SetX( NodeV[ Triangles[itri].Get1() ].GetX() +( NodeV[ Triangles[itri].Get3() ].GetX() -NodeV[ Triangles[itri].Get1() ].GetX() )/2.0 ); NodeV[n_nodes].SetY( NodeV[ Triangles[itri].Get1() ].GetY() +( NodeV[ Triangles[itri].Get3() ].GetY() -NodeV[ Triangles[itri].Get1() ].GetY() )/2.0 ); NodeV[n_nodes].SetZ( NodeV[ Triangles[itri].Get1() ].GetZ() +( NodeV[ Triangles[itri].Get3() ].GetZ() -NodeV[ Triangles[itri].Get1() ].GetZ() )/2.0 ); } if(oldnode3 < 0){ n_nodes++; NodeV[n_nodes].SetX( NodeV[ Triangles[itri].Get1() ].GetX() +( NodeV[ Triangles[itri].Get2() ].GetX() -NodeV[ Triangles[itri].Get1() ].GetX() )/2.0 ); NodeV[n_nodes].SetY( NodeV[ Triangles[itri].Get1() ].GetY() +( NodeV[ Triangles[itri].Get2() ].GetY() -NodeV[ Triangles[itri].Get1() ].GetY() )/2.0 ); NodeV[n_nodes].SetZ( NodeV[ Triangles[itri].Get1() ].GetZ() +( NodeV[ Triangles[itri].Get2() ].GetZ() -NodeV[ Triangles[itri].Get1() ].GetZ() )/2.0 ); } isplit=istop+ntrinew; new0=isplit; new1=isplit+1; new2=isplit+2; new3=isplit+3; Triangles[itri].SetSplit( new0, new1, new2, new3); if(old1)inode1=oldnode1; if(old2)inode2=oldnode2; if(old3)inode3=oldnode3; case0=false; case1=false; case2=false; case3=false; case4=false; case5=false; case6=false; case7=false; if( !old1 && !old2 && !old3)case0=true; if( old1 && old2 && old3)case7=true; if(case0 ){ inode1=n_nodes-2; inode2=n_nodes-1; inode3=n_nodes-0; } if(case7){ inode1=oldnode1; inode2=oldnode2; inode3=oldnode3; } if(!case0 && !case7) { if(old1){ if(old2 || old3){ if(old2){ case4=true; // nodes 1 and 2 exist inode1=oldnode1; inode2=oldnode2; inode3=n_nodes-0; } else { case6=true; // nodes 1 and 3 exist inode1=oldnode1; inode2=n_nodes-0; inode3=oldnode3; } } else { case1=true; //only node 1 exists inode1=oldnode1; inode2=n_nodes-1; inode3=n_nodes-0; } }//endif old1 if(old2){ if(!old1){ // case 4 done above if(old3){ case5=true; //nodes 2 and 3 exist inode1=n_nodes-0; inode2=oldnode2; inode3=oldnode3; } else { case2=true; //only node 2 exists inode1=n_nodes-1; inode2=oldnode2; inode3=n_nodes-0; } } } //endif old2 if(old3){ if( !old1 && !old2){ // 1 and 3 and 2 and 3 done already case3=true; inode1=n_nodes-1; inode2=n_nodes-0; inode3=oldnode3; } } } //endif (NOT case 0) AND (NOT case 7) quad=Triangles[itri].GetQuad(); Triangles[new0].SetTri(inode1, inode2, inode3); //Centre T Triangles[new0].SetQuad(quad); Triangles[new1].SetTri(Triangles[itri].Get1(), inode3, inode2); Triangles[new1].SetQuad(quad); Triangles[new2].SetTri(inode3, Triangles[itri].Get2(), inode1); Triangles[new2].SetQuad(quad); Triangles[new3].SetTri(inode2, inode1, Triangles[itri].Get3()); Triangles[new3].SetQuad(quad); //Set Neighbours for centre Triangle; new1N=new3; new2N=new2; new3N=new1; Triangles[new0].SetNeighb(new1N,new2N,new3N); Triangles[new1].SetN3(new0); Triangles[new2].SetN2(new0); Triangles[new3].SetN1(new0); if(pSplit1){ // have split neighbours on edge 1 // These are is1=Triangles[in1].GetS3(); is2=Triangles[in1].GetS2(); Triangles[new1].SetN1(is1); Triangles[new2].SetN1(is2); Triangles[is1].SetN1(new1); Triangles[is2].SetN1(new2); //independent of quadrant } if(pSplit2){ // have split neighbours on edge 2 // These are quad=Triangles[itri].GetQuad(); otherquad=Triangles[in2].GetQuad(); iquad=(int)quad; if(iquad > 4 && iquad <15)otherquad=quad; if(quad != otherquad){ is1=Triangles[in2].GetS3(); is2=Triangles[in2].GetS4(); } else { is1=Triangles[in2].GetS4(); is2=Triangles[in2].GetS2(); } if(quad != otherquad){ Triangles[is1].SetN3(new1); Triangles[is2].SetN3(new3); } else { Triangles[is1].SetN2(new1); Triangles[is2].SetN2(new3); } Triangles[new1].SetN2(is1); Triangles[new3].SetN2(is2); } if(pSplit3){ // have split neighbours on edge 3 // These are quad=Triangles[itri].GetQuad(); otherquad=Triangles[in3].GetQuad(); iquad=(int)quad; if(iquad > 4 && iquad <15)otherquad=quad; if(quad != otherquad){ is1=Triangles[in3].GetS2(); is2=Triangles[in3].GetS4(); } else { is1=Triangles[in3].GetS4(); is2=Triangles[in3].GetS3(); } if(quad != otherquad){ Triangles[is1].SetN2(new2); Triangles[is2].SetN2(new3); } else { Triangles[is1].SetN3(new2); Triangles[is2].SetN3(new3); } Triangles[new2].SetN3(is1); Triangles[new3].SetN3(is2); } ntrinew=ntrinew+4; } //endif neighbours unsplit } //end loop over tranche of triangles if(idiv==0)*filename="Sphere1.dat"; if(idiv==1)*filename="Sphere2.dat"; if(idiv==2)*filename="Sphere3.dat"; if(idiv==3)*filename="Sphere4.dat"; if(idiv==4)*filename="Sphere5.dat"; file_out.open(*filename, ios::out); //can habe ios::app for appending file_out << n_nodes+1 <<" "<< ntrinew << endl; //output triangle number, 3 node numbers, and quadrant id for(int i=istop; i< istop+ntrinew; i++){ file_out << Triangles[i].Get1() <<" "<< Triangles[i].Get2() <<" "<< Triangles[i].Get3() <<" "<< Triangles[i].GetQuad() << endl; } //output triangle neighbours on edges 1 2 and 3. for(int i=istop; i < istop+ntrinew; i++){ file_out <<" " << Triangles[i].GetN1()-istop <<" "<< Triangles[i].GetN2()-istop <<" "<< Triangles[i].GetN3()-istop << endl; } // n_nodes runs from 0 to n_nodes, so there are actually n_nodes+1 nodes! for(int i=0; i<n_nodes+1;i++){ // cout << "Normalising i=" << i << endl; Normalise(NodeV[i]); } //output x,y,z coordinates of nodes. for(int i=0; i< n_nodes+1; i++){ file_out << NodeV[i].GetX() <<" "<< NodeV[i].GetY() <<" "<< NodeV[i].GetZ() << endl; } file_out.close(); istart=istop; istop=istop+ntrinew; cout << " new istart=" << istart << endl; cout << "new istop=" << istop << endl; int ie1, ie2, ie3, ie4; //check connections! cout << "ISTART ISTOP " << istart << " " << istop << endl; for(int itri=istart; itri < istop; itri++){ // cout << "Checking T" << itri << endl; in1=Triangles[itri].GetN1(); in2=Triangles[itri].GetN2(); in3=Triangles[itri].GetN3(); ie1=Triangles[itri].Get1(); //across edge 1 ie2=Triangles[itri].Get2(); ie3=Triangles[in1].Get1(); // Allways Opposite ie4=Triangles[in1].Get2(); if( ie1 != ie4)cout << " edge mismatch 1 " << "Ts " << itri << " " << in1 << " " << ie1 << " " << ie2 << " in " << itri << " and " << ie3 << " " << ie4 << endl; ie1=Triangles[itri].Get1(); // across edge 2 ie2=Triangles[itri].Get3(); quad=Triangles[itri].GetQuad(); otherquad=Triangles[in2].GetQuad(); iquad=(int)quad; if(iquad > 4 && iquad <15)otherquad=quad; if(quad != otherquad){ ie3=Triangles[in2].Get3(); ie4=Triangles[in2].Get2();} // Same directions else { ie3=Triangles[in2].Get1(); ie4=Triangles[in2].Get3(); //Opposite directions } if( ie1 != ie4)cout << " edge mismatch 2 " << "Ts " << itri << " " << in1 << " " << ie1 << " " << ie2 << " in " << itri << " and " << ie3 << " " << ie4 << " " << in2 << " quads are " << (int)quad << " " << (int)otherquad <<endl; ie1=Triangles[itri].Get2(); //across edge 3 ie2=Triangles[itri].Get3(); quad=Triangles[itri].GetQuad(); otherquad=Triangles[in3].GetQuad(); iquad=(int)quad; if(iquad > 4 && iquad <15)otherquad=quad; if(quad != otherquad){ ie3=Triangles[in3].Get3(); // Same directions ie4=Triangles[in3].Get1(); } else { ie3=Triangles[in3].Get2(); ie4=Triangles[in3].Get3(); // Opposite directions } if( ie1 != ie4)cout << " edge mismatch 3 " << "Ts " << itri << " " << in1 << " " << ie1 << " " << ie2 << " in " << itri << " and " << ie3 << " " << ie4 << " " << in2 << " quads are " << (int)quad << " " << (int)otherquad <<endl; } } cout <<"Number of nodes is " << n_nodes+1 << endl; //exit(0); while(!quitit){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: quitit=true; break; case SDL_MOUSEBUTTONDOWN: mousedown=true; break; case SDL_MOUSEBUTTONUP: mousedown=false; break; case SDL_MOUSEMOTION: if(mousedown){ if(MouseOn)Camera1.MouseView();} else{ if(MouseOn)Camera1.MouseLookAt(); } break; case SDL_KEYDOWN: whatkey=&event.key.keysym; HandleKeyPress(whatkey); break; case SDL_KEYUP: whatkey=&event.key.keysym; HandleKeyRelease(whatkey); default: break; } // end of case } //end of inner loop CheckMove(Camera1); RenderScene(Camera1); } //end of outer loop }