void init_sphere_2D() /* initialisation of window */ { glLineWidth(3); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glOrtho(0.0, NX, DPOLE, NY-DPOLE, -1.0, 1.0); } void draw_vertex_sphere(double xyz[3]) { double xy_screen[2]; xyz_to_xy(xyz[0], xyz[1], xyz[2], xy_screen); glVertex2d(xy_screen[0], xy_screen[1]); } void init_wave_sphere(t_wave_sphere wsphere[NX*NY]) /* initialize sphere data */ { int i, j; double dphi, dtheta, theta0, xy[2], phishift; printf("Initializing wsphere\n"); dphi = DPI/(double)NX; // dtheta = PI/(double)NY; dtheta = PI/(double)(NY-2*(DPOLE)); theta0 = (double)(DPOLE)*dtheta; phishift = PHISHIFT*(XMAX-XMIN)/360.0; #pragma omp parallel for private(i,j) for (i=0; i XMAX) xy[0] += XMIN - XMAX; xy[1] *= (double)NY/(double)(NY-2*DPOLE); wsphere[i*NY+j].x2d = xy[0]; wsphere[i*NY+j].y2d = xy[1]; } /* cotangent, taking care of not dividing by zero */ for (j=1; j nmaxpixels) { printf("Image too large, increase nmaxpixels in choose_colors()\n"); exit(0); } /* shift due to min/max latitudes of image */ sshift = 0 + DPOLE; nshift = 0 + DPOLE; /* read rgb values */ for (j=0; j nx-1) ii -= nx; // jj = (int)(-ry*(double)j + cy); // jj = (int)(ry*(double)(NY-nshift - j)) + sshift; jj = (int)(ry*(double)(NY-nshift - j)); if (jj > ny-1) jj = ny-1; if (jj < 0) jj = 0; wsphere[i*NY+j].r = (double)rgb_values[3*(jj*nx+ii)]*cratio; wsphere[i*NY+j].g = (double)rgb_values[3*(jj*nx+ii)+1]*cratio; wsphere[i*NY+j].b = (double)rgb_values[3*(jj*nx+ii)+2]*cratio; /* decide which points are in the Sea */ diff = iabs(rgb_values[3*(jj*nx+ii)] - 10); diff += iabs(rgb_values[3*(jj*nx+ii)+1] - 10); diff += iabs(rgb_values[3*(jj*nx+ii)+2] - 51); wsphere[i*NY+j].indomain = (diff < 10); } free(rgb_values); fclose(image_file); } int ij_to_sphere(int i, int j, double r, t_wave_sphere wsphere[NX*NY], double xyz[3]) /* convert spherical to rectangular coordinates */ { double pscal, newr; static double norm_observer; static int first = 1; if (first) { norm_observer = sqrt(observer[0]*observer[0] + observer[1]*observer[1] + observer[2]*observer[2]); first = 0; } newr = wsphere[i*NY+j].radius; xyz[0] = wsphere[i*NY+j].x; xyz[1] = wsphere[i*NY+j].y; xyz[2] = wsphere[i*NY+j].z; pscal = xyz[0]*observer[0] + xyz[1]*observer[1] + xyz[2]*observer[2]; xyz[0] *= newr; xyz[1] *= newr; xyz[2] *= newr; return(pscal/norm_observer > COS_VISIBLE); } int init_circle_sphere(t_circles_sphere *circles, int circle_pattern) /* initialise circles on sphere */ /* for billiard shape D_SPHERE_CIRCLES */ { int ncircles, k; double alpha, beta, gamma; switch (circle_pattern) { case (C_SPH_DODECA): { alpha = acos(sqrt(5.0)/3.0); beta = acos(1.0/3.0); gamma = asin(sqrt(3.0/8.0)); circles[0].theta = 0.0; circles[0].phi = 0.0; for (k=0; k<3; k++) { circles[1+k].theta = alpha; circles[1+k].phi = (double)k*DPI/3.0; } for (k=0; k<3; k++) { circles[4+k].theta = beta; circles[4+k].phi = (double)k*DPI/3.0 + gamma; circles[7+k].theta = beta; circles[7+k].phi = (double)k*DPI/3.0 - gamma; } for (k=0; k<3; k++) { circles[10+k].theta = PI - beta; circles[10+k].phi = (double)k*DPI/3.0 + PI/3.0 + gamma; circles[13+k].theta = PI - beta; circles[13+k].phi = (double)k*DPI/3.0 + PI/3.0 - gamma; } for (k=0; k<3; k++) { circles[16+k].theta = PI - alpha; circles[16+k].phi = (double)k*DPI/3.0 + PI/3.0; } circles[19].theta = PI; circles[19].phi = 0.0; for (k=0; k<20; k++) { circles[k].radius = MU; circles[k].x = sin(circles[k].theta)*cos(circles[k].phi); circles[k].y = sin(circles[k].theta)*sin(circles[k].phi); circles[k].z = cos(circles[k].theta); } ncircles = 20; break; } case (C_SPH_ICOSA): { alpha = acos(1.0/sqrt(5.0)); circles[0].theta = 0.0; circles[0].phi = 0.0; for (k=0; k<5; k++) { circles[1+k].theta = alpha; circles[1+k].phi = (double)k*DPI/5.0; } for (k=0; k<5; k++) { circles[6+k].theta = PI - alpha; circles[6+k].phi = (double)k*DPI/5.0 + PI/5.0; } circles[11].theta = PI; circles[11].phi = 0.0; for (k=0; k<12; k++) { circles[k].radius = MU; circles[k].x = sin(circles[k].theta)*cos(circles[k].phi); circles[k].y = sin(circles[k].theta)*sin(circles[k].phi); circles[k].z = cos(circles[k].theta); } ncircles = 12; break; } case (C_SPH_OCTA): { circles[0].theta = 0.0; circles[0].phi = 0.0; for (k=0; k<4; k++) { circles[1+k].theta = PID; circles[1+k].phi = (double)k*PID; } circles[5].theta = PI; circles[5].phi = 0.0; for (k=0; k<6; k++) { circles[k].radius = MU; circles[k].x = sin(circles[k].theta)*cos(circles[k].phi); circles[k].y = sin(circles[k].theta)*sin(circles[k].phi); circles[k].z = cos(circles[k].theta); } ncircles = 6; break; } case (C_SPH_CUBE): { alpha = acos(1.0/3.0); circles[0].theta = 0.0; circles[0].phi = 0.0; for (k=0; k<3; k++) { circles[1+k].theta = alpha; circles[1+k].phi = (double)k*DPI/3.0; circles[4+k].theta = PI - alpha; circles[4+k].phi = (double)k*DPI/3.0 + PI/3.0; } circles[7].theta = PI; circles[7].phi = 0.0; for (k=0; k<8; k++) { circles[k].radius = MU; circles[k].x = sin(circles[k].theta)*cos(circles[k].phi); circles[k].y = sin(circles[k].theta)*sin(circles[k].phi); circles[k].z = cos(circles[k].theta); } ncircles = 8; break; } default: { printf("Function init_circle_sphere not defined for this pattern \n"); } } return(ncircles); } int xy_in_billiard_sphere(int i, int j, t_wave_sphere wsphere[NX*NY]) /* returns 1 if (x,y) represents a point in the billiard */ { int k; double pscal, dist, r, u, v, u1, v1; static double cos_rot, sin_rot; static int first = 1; if (first) { if (B_DOMAIN == D_SPHERE_EARTH) init_earth_map(wsphere); else if ((B_DOMAIN == D_SPHERE_JULIA)||(B_DOMAIN == D_SPHERE_JULIA_INV)) { cos_rot = cos(JULIA_ROT*DPI/360.0); sin_rot = sin(JULIA_ROT*DPI/360.0); } first = 0; } switch (B_DOMAIN) { case (D_NOTHING): { return(1); } case (D_LATITUDE): { return(vabs(wsphere[i*NY+j].theta - PID) < LAMBDA*PID); } case (D_SPHERE_CIRCLES): { for (k=0; k RMAX) r = RMAX; wsphere[i*NY+j].radius = r; } if (SHADE_WAVE) { #pragma omp parallel for private(i,j,norm,pscal,deltar,deltai,deltaj,n) for (i=0; i NX) ii -= NX; glVertex2i(ii, j); glVertex2i(ii+1, j); glVertex2i(ii+1, j+1); glVertex2i(ii, j+1); } glEnd (); } void draw_wave_sphere_ij(int i, int iplus, int j, int jplus, int jcolor, int movie, double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], t_wave wave[NX*NY], t_wave_sphere wsphere[NX*NY], int zplot, int cplot, int palette, int fade, double fade_value) /* draw wave at simulation grid point (i,j) */ { int k, l; double xyz[3], ca; if ((TWOSPEEDS)||(xy_in[i*NY+j])) glColor3f(wave[i*NY+jcolor].rgb[0], wave[i*NY+jcolor].rgb[1], wave[i*NY+jcolor].rgb[2]); else { ca = wave[i*NY+j].cos_angle; ca = (ca + 1.0)*0.4 + 0.2; if (fade) ca *= fade_value; if (B_DOMAIN == D_SPHERE_EARTH) glColor3f(wsphere[i*NY+j].r*ca, wsphere[i*NY+j].g*ca, wsphere[i*NY+j].b*ca); else glColor3f(COLOR_OUT_R*ca, COLOR_OUT_G*ca, COLOR_OUT_B*ca); } glBegin(GL_TRIANGLE_FAN); if (ij_to_sphere(i, j, *wave[i*NY+j].p_zfield[movie], wsphere, xyz)) draw_vertex_sphere(xyz); if (ij_to_sphere(iplus, j, *wave[iplus*NY+j].p_zfield[movie], wsphere, xyz)) draw_vertex_sphere(xyz); if (ij_to_sphere(iplus, jplus, *wave[iplus*NY+j+1].p_zfield[movie], wsphere, xyz)) draw_vertex_sphere(xyz); if (ij_to_sphere(i, jplus, *wave[i*NY+j+1].p_zfield[movie], wsphere, xyz)) draw_vertex_sphere(xyz); glEnd (); } void draw_wave_sphere_3D(int movie, double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], t_wave wave[NX*NY], t_wave_sphere wsphere[NX*NY], int zplot, int cplot, int palette, int fade, double fade_value, int refresh) { int i, j, imax, imin; double observer_angle, angle2; blank(); if (refresh) { compute_wave_fields(phi, psi, xy_in, zplot, cplot, wave); if (SHADE_3D) compute_light_angle_sphere(xy_in, wave, wsphere, movie); else if (SHADE_2D) compute_light_angle_sphere_2d(xy_in, wave, movie); compute_cfield_sphere(xy_in, cplot, palette, wave, fade, fade_value, movie); } observer_angle = argument(observer[0], observer[1]); if (observer_angle < 0.0) observer_angle += DPI; angle2 = observer_angle + PI; if (angle2 > DPI) angle2 -= DPI; imin = (int)(observer_angle*(double)NX/DPI); imax = (int)(angle2*(double)NX/DPI); if (imin >= NX-1) imin = NX-2; if (imax >= NX-1) imax = NX-2; // printf("Angle = %.5lg, angle2 = %.5lg, imin = %i, imax = %i\n", observer_angle, angle2, imin, imax); if (observer[2] > 0.0) { if (imin < imax) { for (i=imax; i>imin; i--) for (j=0; j=0; i--) for (j=0; j=imin; i--) for (j=0; jimin; i--) for (j=NY-3; j>=0; j--) draw_wave_sphere_ij(i, i+1, j, j+1, j+1, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); for (i=imax+1; i=0; j--) draw_wave_sphere_ij(i, i+1, j, j+1, j+1, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); for (j=NY-3; j>=0; j--) draw_wave_sphere_ij(NX-1, 0, j, j+1, j+1, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); for (i=0; i<=imin; i++) for (j=NY-3; j>=0; j--) draw_wave_sphere_ij(i, i+1, j, j+1, j+1, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); } else { for (i=imax; i=0; j--) draw_wave_sphere_ij(i, i+1, j, j+1, j+1, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); for (i=imax-1; i>=0; i--) for (j=NY-3; j>=0; j--) draw_wave_sphere_ij(i, i+1, j, j+1, j+1, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); for (j=NY-3; j>=0; j--) draw_wave_sphere_ij(NX-1, 0, j, j+1, j+1, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); for (i=NX-2; i>=imin; i--) for (j=NY-3; j>=0; j--) draw_wave_sphere_ij(i, i+1, j, j+1, j+1, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); } /* South pole */ for (i=0; i0; j--) draw_wave_sphere_ij(i, i+1, j-1, j, j, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); for (j=2; j>0; j--) draw_wave_sphere_ij(NX-1, 0, j-1, j, DPOLE, movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade, fade_value); } } void draw_wave_sphere(int movie, double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], t_wave wave[NX*NY], t_wave_sphere wsphere[NX*NY], int zplot, int cplot, int palette, int fade, double fade_value, int refresh) { if (PLOT_2D) draw_wave_sphere_2D(movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade,fade_value, refresh); else draw_wave_sphere_3D(movie, phi, psi, xy_in, wave, wsphere, zplot, cplot, palette, fade,fade_value, refresh); }