#include "gwin.user.h" #include double myatan2(); float t0[3],t1[3],t2[3],ti0[3],ti1[3],ti2[3]; double pi,pi1, pi2, pi3; float xmerc(); float lats[500],longs[500]; int ortho; int merc; int setmercator(),setortho(),plot_grid(),interrupt_display(); int new_center(),redisplay(),setortho2(); float x,y; int event; char key; int interrupt = 0; int display_underway = 0; float lat_cen,long_cen; int ortho2; main() { float xlat,xlong; char line[30]; pi1 = 3.1415926535897943/180.; pi2 = 180./3.1415926535897943; pi3 = 3.1415926535897943/2.0; ortho = 1; ortho2 = 0; merc = 0; printf("\n\nEnter lat_cen, long_cen: "); scanf("%f %f",&lat_cen,&long_cen); ustart("high2",0.,640.,0.,400.); if(merc ) uwindo(-180.,180.,-180.,180.); if(ortho || ortho2) uwindo(-250.,250.,-160.,160.); setup_menus(); make_rotation_matrices(lat_cen,long_cen); make_geo_grid(); plot_grid(); while(1 == 1) { ugrina(&x,&y,&event,&key); latlong(x,y,&xlat,&xlong); sprintf(line,"%6.2f %6.2f",xlat,xlong); if (ortho || ortho2){ uprint(100.,150.,line); }else{ uprint(100.,170.,line); } } } latlong(x1,y1,xlat,xlong) float x1,y1,*xlat,*xlong; { float xxx,yyy,zzz; double xtemp,ytemp,ztemp; float temp1,temp2; float ph1,th1; char line[30]; if(ortho || ortho2){ yyy = x1/150.; zzz = y1/150.; temp1 = yyy*yyy; temp2 = zzz*zzz; if(temp1 + temp2 > 1.0)return(1); xxx = sqrt((double)(1 - temp1 - temp2)); xtemp = (double)(ti0[0] * xxx + ti0[1] * yyy + ti0[2] * zzz); ytemp = (double)(ti1[0] * xxx + ti1[1] * yyy + ti1[2] * zzz); ztemp = (double)(ti2[0] * xxx + ti2[1] * yyy + ti2[2] * zzz); if(fabs(xtemp) < 1e-15) xtemp = 1e-15; *xlong = pi2*myatan2(ytemp,xtemp); if(ztemp > 1.0) ztemp = 1.0; if(ztemp < -1.0) ztemp = -1.0; *xlat = pi2*(pi3 - acos(ztemp)); } if(merc){ ph1 = pi1 * y1; ph1 = 2.0 * atan(exp(ph1)) - pi3; ph1 = pi3 - ph1; th1 = pi1 * x1; xxx = sin((double)ph1) * cos((double)th1); yyy = sin((double)ph1) * sin((double)th1); zzz = cos((double)ph1); xtemp = (double)(ti0[0] * xxx + ti0[1] * yyy + ti0[2] * zzz); ytemp = (double)(ti1[0] * xxx + ti1[1] * yyy + ti1[2] * zzz); ztemp = (double)(ti2[0] * xxx + ti2[1] * yyy + ti2[2] * zzz); if(fabs(xtemp) < 1e-15) xtemp = 1e-15; *xlong = pi2*myatan2(ytemp,xtemp); if(ztemp > 1.0) ztemp = 1.0; if(ztemp < -1.0) ztemp = -1.0; *xlat = pi2*(pi3 - acos(ztemp)); } } make_rotation_matrices(lat_cen,long_cen) float lat_cen,long_cen; { /* Rotation matrices to rotate lat/long to new lat/long */ /* so that (lat_cen,long_cen) becomes (0,0) */ float sin_theta, cos_theta, theta_rot, sin_phi, cos_phi, phi_rot; theta_rot = long_cen * pi1; phi_rot = lat_cen * pi1; sin_theta = sin(theta_rot); cos_theta = cos(theta_rot); sin_phi = sin(phi_rot); cos_phi = cos(phi_rot); t0[0] = cos_theta * cos_phi; t0[1] = sin_theta * cos_phi; t0[2] = sin_phi; t1[0] = -sin_theta; t1[1] = cos_theta; t1[2] = 0.0; t2[0] = -cos_theta * sin_phi; t2[1] = -sin_theta * sin_phi; t2[2] = cos_phi; ti0[0] = cos_theta * cos_phi; ti0[1] = -sin_theta; ti0[2] = -cos_theta * sin_phi; ti1[0] = sin_theta * cos_phi; ti1[1] = cos_theta; ti1[2] = -sin_theta * sin_phi; ti2[0] = sin_phi; ti2[1] = 0.0; ti2[2] = cos_phi; } mercator(long_in,lat_in,x_out,y_out) float lat_in,long_in,*y_out,*x_out; { float xla,xlo,x[3],xr[3],sth,cth,sph,cph; double th1,ph1; xla = lat_in; xlo = long_in; th1 = pi1 * xlo; ph1 = pi3 - xla * pi1; sth = sin(th1); cth = cos(th1); sph = sin(ph1); cph = cos(ph1); x[0] = sph * cth; x[1] = sph * sth; x[2] = cph; xr[0] = t0[0] * x[0] + t0[1] * x[1] + t0[2] * x[2]; xr[1] = t1[0] * x[0] + t1[1] * x[1] + t1[2] * x[2]; xr[2] = t2[0] * x[0] + t2[1] * x[1] + t2[2] * x[2]; *y_out = xmerc( pi2 * asin(xr[2])); *x_out = pi2 * myatan2(xr[1],xr[0]); } float xmerc(xlat) float(xlat); { double a1; if (fabs(xlat) < 89.9999){ if(xlat >= 0.0){ a1 = pi1 * (45.0 + .5 * xlat); return((float) pi2 * log(tan(a1))); } else { a1 = -pi1 * (-45.0 + .5 * xlat); return((float) -pi2 * log(tan(a1))); } } else { if(xlat < 0) return(-750.); return(750.); } } orthographic(long_in,lat_in,x_out,y_out,frontside) float lat_in,long_in,*y_out,*x_out; int *frontside; { float xla,xlo,x[3],xr[3],sth,cth,sph,cph; double th1,ph1; xla = lat_in; xlo = long_in; th1 = pi1 * xlo; ph1 = pi3 - xla * pi1; sth = sin(th1); cth = cos(th1); sph = sin(ph1); cph = cos(ph1); x[0] = sph * cth; x[1] = sph * sth; x[2] = cph; xr[0] = t0[0] * x[0] + t0[1] * x[1] + t0[2] * x[2]; xr[1] = t1[0] * x[0] + t1[1] * x[1] + t1[2] * x[2]; xr[2] = t2[0] * x[0] + t2[1] * x[1] + t2[2] * x[2]; *y_out = 150.0 * xr[2]; *x_out = 150.0 * xr[1]; *frontside = 0; if(xr[0]>0.0)*frontside = 1; } make_geo_grid() { int i; float x; i = 0; for(x = -90.0;x < 91.0 ;x += 10.0){ lats[i++] = x; } lats[0] = -89.999; lats[i-1] = 89.999; i = 0; for(x = -180.0; x < 181.0; x += 10.0){ longs[i++] = x; } longs[0] = -179.999; longs[i-1] = 179.999; } plot_grid() { if(merc){ mercplot(); return(0); } if(ortho){ orthoplot(); return(0); } if(ortho2){ ortho2plot(); return(0); } } mercplot() { int i,j; float x,y,xold; int event,key; display_underway = 1; interrupt = 0; uerase(); upset("colo",1.0); for(i=0;i<19;i++){ mercator(longs[0],lats[i],&x,&y); umove(x,y); xold = x; for(j=1;j<37;j++){ ugrina(&x,&y,&event,&key); if(interrupt) goto interrupted; mercator(longs[j],lats[i],&x,&y); if(fabs(xold-x) < 100.0)udraw(x,y); umove(x,y); xold = x; } } for(j=0;j<37;j++){ mercator(longs[j],lats[0],&x,&y); umove(x,y); xold = x; for(i=1;i<19;i++){ ugrina(&x,&y,&event,&key); if(interrupt) goto interrupted; mercator(longs[j],lats[i],&x,&y); if(fabs(xold-x) < 100.0)udraw(x,y); umove(x,y); xold = x; } } interrupted: interrupt = 0; display_underway = 0; } orthoplot() { int i,j; float x,y,xold,yold; int event,key; int frontside; display_underway = 1; interrupt = 0; uerase(); upset("colo",1.0); for(i=0;i<19;i++){ orthographic(longs[0],lats[i],&x,&y,&frontside); umove(x,y); xold = x; yold = y; for(j=1;j<37;j++){ ugrina(&x,&y,&event,&key); if(interrupt) goto interrupted; orthographic(longs[j],lats[i],&x,&y,&frontside); if(fabs(xold-x) < 100.0 && frontside){ umove(xold,yold); udraw(x,y); }else{ umove(x,y); } xold = x; yold = y; } } for(j=0;j<37;j++){ orthographic(longs[j],lats[0],&x,&y,&frontside); umove(x,y); xold = x; yold = y; for(i=1;i<19;i++){ ugrina(&x,&y,&event,&key); if(interrupt) goto interrupted; orthographic(longs[j],lats[i],&x,&y,&frontside); if(fabs(xold-x) < 100.0 && frontside){ umove(xold,yold); udraw(x,y); }else{ umove(x,y); } xold = x; yold = y; } } interrupted: interrupt = 0; display_underway = 0; } ortho2plot() { int i,j; float x,y,xold,yold; int event,key; int frontside; frontside = 1; display_underway = 1; interrupt = 0; uerase(); /* plot backsides first */ upset("colo",10.0); for(i=0;i<19;i++){ orthographic(longs[0],lats[i],&x,&y,&frontside); umove(x,y); xold = x; yold = y; for(j=1;j<37;j++){ ugrina(&x,&y,&event,&key); if(interrupt) goto interrupted; orthographic(longs[j],lats[i],&x,&y,&frontside); if(fabs(xold-x) < 100.0 && !frontside){ umove(xold,yold); udraw(x,y); }else{ umove(x,y); } xold = x; yold = y; } } for(j=0;j<37;j++){ orthographic(longs[j],lats[0],&x,&y,&frontside); umove(x,y); xold = x; yold = y; for(i=1;i<19;i++){ ugrina(&x,&y,&event,&key); if(interrupt) goto interrupted; orthographic(longs[j],lats[i],&x,&y,&frontside); if(fabs(xold-x) < 100.0 && !frontside){ umove(xold,yold); udraw(x,y); }else{ umove(x,y); } xold = x; yold = y; } } /* now plot front sides */ upset("colo",1.0); for(i=0;i<19;i++){ orthographic(longs[0],lats[i],&x,&y,&frontside); umove(x,y); xold = x; yold = y; for(j=1;j<37;j++){ ugrina(&x,&y,&event,&key); if(interrupt) goto interrupted; orthographic(longs[j],lats[i],&x,&y,&frontside); if(fabs(xold-x) < 100.0 && frontside){ umove(xold,yold); udraw(x,y); }else{ umove(x,y); } xold = x; yold = y; } } for(j=0;j<37;j++){ orthographic(longs[j],lats[0],&x,&y,&frontside); umove(x,y); xold = x; yold = y; for(i=1;i<19;i++){ ugrina(&x,&y,&event,&key); if(interrupt) goto interrupted; orthographic(longs[j],lats[i],&x,&y,&frontside); if(fabs(xold-x) < 100.0 && frontside){ umove(xold,yold); udraw(x,y); }else{ umove(x,y); } xold = x; yold = y; } } interrupted: interrupt = 0; display_underway = 0; } setup_menus() { uamenu(1,0,0,"PROJECTION ",' ',0,(USHORT)MIDRAWN|MENUENABLED,7); uamenu(1,1,0," ORTHOGRAPHIC ",'O',6,(USHORT)MIDRAWN|ITEMTEXT|HIGHCOMP |COMMSEQ|ITEMENABLED|CHECKIT,setortho); uamenu(1,2,0," MERCATOR ",'M',5,(USHORT)MIDRAWN|ITEMTEXT|HIGHCOMP |COMMSEQ|ITEMENABLED,setmercator); uamenu(1,3,0," ORTHO2 ",'2',3,(USHORT)MIDRAWN|ITEMTEXT|HIGHCOMP |COMMSEQ|ITEMENABLED,setortho2); uamenu(2,0,0,"DISPLAY ",' ',0,(USHORT)MIDRAWN|MENUENABLED,7); uamenu(2,1,0,"REDISPLAY ",'R',0,(USHORT)MIDRAWN|ITEMTEXT|HIGHCOMP |COMMSEQ|ITEMENABLED,redisplay); uamenu(2,2,0,"INTERRUPT ",'I',0,(USHORT)MIDRAWN|ITEMTEXT|HIGHCOMP |COMMSEQ|ITEMENABLED,interrupt_display); uamenu(2,3,0,"NEW CENTER ",'C',0,(USHORT)MIDRAWN|ITEMTEXT|HIGHCOMP |COMMSEQ|ITEMENABLED,new_center); } redisplay() { plot_grid(); interrupt=1; /* cancel previous invocation if any */ } setortho() { uwindo(-250.,250.,-160.,160.); ortho = 1; merc = 0; ortho2 = 0; uamenu(1,1,0," ORTHOGRAPHIC ",'O',6,(USHORT)MIDRAWN|ITEMTEXT|HIGHCOMP |COMMSEQ|ITEMENABLED|CHECKIT|CHECKED,setortho); redisplay(); } setmercator() { uwindo(-180.,180.,-180.,180.); merc = 1; ortho = 0; ortho2 = 0; uamenu(1,2,0," MERCATOR ",'M',5,(USHORT)MIDRAWN|ITEMTEXT|HIGHCOMP |COMMSEQ|ITEMENABLED|CHECKIT|CHECKED,setmercator); redisplay(); } setortho2() { uwindo(-250.,250.,-160.,160.); ortho2 = 1; ortho = 0; merc = 0; uamenu(1,3,0," ORTHO2 ",'2',3,(USHORT)MIDRAWN|ITEMTEXT|HIGHCOMP |COMMSEQ|ITEMENABLED|CHECKIT|CHECKED,setortho2); redisplay(); } interrupt_display() { interrupt = 1; } new_center() { char coords[255]; uerase(); uwindo(0.,100.,0.,100.); ugetstring(10.,75.,70.,"Enter latitude and longitude: ",coords); while (sscanf(coords,"%f %f",&lat_cen,&long_cen) < 2){ ugetstring(10.,75.,70., "Error, try again. Enter latitude and longitude: ",coords); } make_rotation_matrices(lat_cen,long_cen); if(merc)setmercator(); if(ortho)setortho(); if(ortho2)setortho2(); } double myatan2(y,x) double x,y; { double temp; double pi = 3.1415926535897943; double piov2 = 0.5 * 3.1415926535897943; if(fabs(x) > 0.0){ temp = atan((double)y/x); }else{ if(y < 0.0){ temp = -piov2; }else{ temp = piov2; if(fabs(x) < 1e-15 && fabs(y) <1e-15) temp = 0.0; } } if(x < 0.0 ){ if(y >= 0.0) { temp = pi + temp; }else{ temp = -pi + temp; } } return(temp); }