2747 lines
92 KiB
C
2747 lines
92 KiB
C
/*********************/
|
|
/* Graphics routines */
|
|
/*********************/
|
|
|
|
#include "colors_waves.c"
|
|
|
|
|
|
int writetiff(char *filename, char *description, int x, int y, int width, int height, int compression)
|
|
{
|
|
TIFF *file;
|
|
GLubyte *image, *p;
|
|
int i;
|
|
|
|
file = TIFFOpen(filename, "w");
|
|
if (file == NULL)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
image = (GLubyte *) malloc(width * height * sizeof(GLubyte) * 3);
|
|
|
|
/* OpenGL's default 4 byte pack alignment would leave extra bytes at the
|
|
end of each image row so that each full row contained a number of bytes
|
|
divisible by 4. Ie, an RGB row with 3 pixels and 8-bit componets would
|
|
be laid out like "RGBRGBRGBxxx" where the last three "xxx" bytes exist
|
|
just to pad the row out to 12 bytes (12 is divisible by 4). To make sure
|
|
the rows are packed as tight as possible (no row padding), set the pack
|
|
alignment to 1. */
|
|
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
|
|
|
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
|
|
TIFFSetField(file, TIFFTAG_IMAGEWIDTH, (uint32) width);
|
|
TIFFSetField(file, TIFFTAG_IMAGELENGTH, (uint32) height);
|
|
TIFFSetField(file, TIFFTAG_BITSPERSAMPLE, 8);
|
|
TIFFSetField(file, TIFFTAG_COMPRESSION, compression);
|
|
TIFFSetField(file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
|
TIFFSetField(file, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
|
|
TIFFSetField(file, TIFFTAG_SAMPLESPERPIXEL, 3);
|
|
TIFFSetField(file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
|
TIFFSetField(file, TIFFTAG_ROWSPERSTRIP, 1);
|
|
TIFFSetField(file, TIFFTAG_IMAGEDESCRIPTION, description);
|
|
p = image;
|
|
for (i = height - 1; i >= 0; i--)
|
|
{
|
|
// if (TIFFWriteScanline(file, p, height - i - 1, 0) < 0)
|
|
if (TIFFWriteScanline(file, p, i, 0) < 0)
|
|
{
|
|
free(image);
|
|
TIFFClose(file);
|
|
return 1;
|
|
}
|
|
p += width * sizeof(GLubyte) * 3;
|
|
}
|
|
TIFFClose(file);
|
|
return 0;
|
|
}
|
|
|
|
|
|
void init() /* initialisation of window */
|
|
{
|
|
glLineWidth(3);
|
|
|
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
// glOrtho(XMIN, XMAX, YMIN, YMAX , -1.0, 1.0);
|
|
glOrtho(0.0, NX, 0.0, NY, -1.0, 1.0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void blank()
|
|
{
|
|
if (BLACK) glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
else glClearColor(1.0, 1.0, 1.0, 1.0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
}
|
|
|
|
|
|
|
|
void save_frame()
|
|
{
|
|
static int counter = 0;
|
|
char *name="wave.", n2[100];
|
|
char format[6]=".%05i";
|
|
|
|
counter++;
|
|
// printf (" p2 counter = %d \n",counter);
|
|
strcpy(n2, name);
|
|
sprintf(strstr(n2,"."), format, counter);
|
|
strcat(n2, ".tif");
|
|
printf(" saving frame %s \n",n2);
|
|
writetiff(n2, "Wave equation in a planar domain", 0, 0,
|
|
WINWIDTH, WINHEIGHT, COMPRESSION_LZW);
|
|
|
|
}
|
|
|
|
void save_frame_counter(int counter)
|
|
/* same as save_frame, but with imposed image number (for option DOUBLE_MOVIE) */
|
|
{
|
|
char *name="wave.", n2[100];
|
|
char format[6]=".%05i";
|
|
|
|
strcpy(n2, name);
|
|
sprintf(strstr(n2,"."), format, counter);
|
|
strcat(n2, ".tif");
|
|
printf(" saving frame %s \n",n2);
|
|
writetiff(n2, "Wave equation in a planar domain", 0, 0,
|
|
WINWIDTH, WINHEIGHT, COMPRESSION_LZW);
|
|
|
|
}
|
|
|
|
void write_text_fixedwidth( double x, double y, char *st)
|
|
{
|
|
int l, i;
|
|
|
|
l=strlen( st ); // see how many characters are in text string.
|
|
glRasterPos2d( x, y); // location to start printing text
|
|
for( i=0; i < l; i++) // loop until i is greater then l
|
|
{
|
|
// glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
|
|
// glutBitmapCharacter(GLUT_BITMAP_8_BY_13, st[i]); // Print a character on the screen
|
|
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, st[i]); // Print a character on the screen
|
|
}
|
|
}
|
|
|
|
|
|
void write_text( double x, double y, char *st)
|
|
{
|
|
int l,i;
|
|
|
|
l=strlen( st ); // see how many characters are in text string.
|
|
glRasterPos2d( x, y); // location to start printing text
|
|
for( i=0; i < l; i++) // loop until i is greater then l
|
|
{
|
|
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
|
|
// glutBitmapCharacter(GLUT_BITMAP_8_BY_13, st[i]); // Print a character on the screen
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************/
|
|
/* some basic math */
|
|
/*********************/
|
|
|
|
double vabs(double x) /* absolute value */
|
|
{
|
|
double res;
|
|
|
|
if (x<0.0) res = -x;
|
|
else res = x;
|
|
return(res);
|
|
}
|
|
|
|
double module2(double x, double y) /* Euclidean norm */
|
|
{
|
|
double m;
|
|
|
|
m = sqrt(x*x + y*y);
|
|
return(m);
|
|
}
|
|
|
|
double argument(double x, double y)
|
|
{
|
|
double alph;
|
|
|
|
if (x!=0.0)
|
|
{
|
|
alph = atan(y/x);
|
|
if (x<0.0)
|
|
alph += PI;
|
|
}
|
|
else
|
|
{
|
|
alph = PID;
|
|
if (y<0.0)
|
|
alph = PI*1.5;
|
|
}
|
|
return(alph);
|
|
}
|
|
|
|
|
|
// int in_polygon(double x, double y, double r, int npoly, double apoly)
|
|
// /* test whether (x,y) is in regular polygon of npoly sides inscribed in circle of radious r, turned by apoly Pi/2 */
|
|
// {
|
|
// int condition = 1, k;
|
|
// double omega, cw, angle;
|
|
//
|
|
// omega = DPI/((double)npoly);
|
|
// cw = cos(omega*0.5);
|
|
// for (k=0; k<npoly; k++)
|
|
// {
|
|
// angle = apoly*PID + ((double)k+0.5)*omega;
|
|
// condition = condition*(x*cos(angle) + y*sin(angle) < r*cw);
|
|
// }
|
|
// return(condition);
|
|
// }
|
|
|
|
|
|
|
|
int in_tpolygon(double x, double y, t_polygon polygon)
|
|
/* test whether (x,y) is in polygon */
|
|
{
|
|
int condition = 1, k;
|
|
double omega, cw, angle, x1, y1;
|
|
|
|
x1 = (x-polygon.xc)/polygon.radius;
|
|
y1 = (y-polygon.yc)/polygon.radius;
|
|
|
|
/* first test whether point is in circumcircle */
|
|
if (x1*x1 + y1*y1 >= 1.0) return(0);
|
|
|
|
omega = DPI/((double)polygon.nsides);
|
|
cw = cos(omega*0.5);
|
|
for (k=0; k<polygon.nsides; k++)
|
|
{
|
|
angle = polygon.angle*PID + ((double)k+0.5)*omega;
|
|
condition = condition*(x1*cos(angle) + y1*sin(angle) < cw);
|
|
}
|
|
return(condition);
|
|
}
|
|
|
|
/*********************/
|
|
/* drawing routines */
|
|
/*********************/
|
|
|
|
/* The billiard boundary is drawn in (x,y) coordinates */
|
|
/* However for the grid points, we use integer coordinates (i,j) */
|
|
/* GL would allow to always work in (x,y) coordinates but using both */
|
|
/* sets of coordinates decreases number of double computations when */
|
|
/* drawing the field */
|
|
|
|
void xy_to_ij(double x, double y, int ij[2])
|
|
/* convert (x,y) position to (i,j) in table representing wave */
|
|
{
|
|
double x1, y1;
|
|
|
|
x1 = (x - XMIN)/(XMAX - XMIN);
|
|
y1 = (y - YMIN)/(YMAX - YMIN);
|
|
|
|
ij[0] = (int)(x1 * (double)NX);
|
|
ij[1] = (int)(y1 * (double)NY);
|
|
}
|
|
|
|
|
|
void xy_to_pos(double x, double y, double pos[2])
|
|
/* convert (x,y) position to double-valued position in table representing wave */
|
|
{
|
|
double x1, y1;
|
|
|
|
x1 = (x - XMIN)/(XMAX - XMIN);
|
|
y1 = (y - YMIN)/(YMAX - YMIN);
|
|
|
|
pos[0] = x1 * (double)NX;
|
|
pos[1] = y1 * (double)NY;
|
|
}
|
|
|
|
|
|
void ij_to_xy(int i, int j, double xy[2])
|
|
/* convert (i,j) position in table representing wave to (x,y) */
|
|
{
|
|
double x1, y1;
|
|
|
|
xy[0] = XMIN + ((double)i)*(XMAX-XMIN)/((double)NX);
|
|
xy[1] = YMIN + ((double)j)*(YMAX-YMIN)/((double)NY);
|
|
}
|
|
|
|
void erase_area(double x, double y, double dx, double dy)
|
|
{
|
|
double pos[2], rgb[3];
|
|
|
|
hsl_to_rgb(220.0, 0.8, 0.7, rgb);
|
|
|
|
glColor3f(rgb[0], rgb[1], rgb[2]);
|
|
glBegin(GL_QUADS);
|
|
xy_to_pos(x - dx, y - dy, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(x + dx, y - dy, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(x + dx, y + dy, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(x - dx, y + dy, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
}
|
|
|
|
|
|
void erase_area_rgb(double x, double y, double dx, double dy, double rgb[3])
|
|
{
|
|
double pos[2];
|
|
|
|
glColor3f(rgb[0], rgb[1], rgb[2]);
|
|
glBegin(GL_QUADS);
|
|
xy_to_pos(x - dx, y - dy, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(x + dx, y - dy, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(x + dx, y + dy, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(x - dx, y + dy, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
}
|
|
|
|
|
|
void erase_area_hsl(double x, double y, double dx, double dy, double h, double s, double l)
|
|
{
|
|
double pos[2], rgb[3];
|
|
|
|
hsl_to_rgb(h, s, l, rgb);
|
|
erase_area_rgb(x, y, dx, dy, rgb);
|
|
}
|
|
|
|
void draw_rectangle(double x1, double y1, double x2, double y2)
|
|
{
|
|
double pos[2];
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
xy_to_pos(x1, y1, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(x2, y1, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(x2, y2, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(x1, y2, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
}
|
|
|
|
void draw_rotated_rectangle(double x1, double y1, double x2, double y2)
|
|
{
|
|
double pos[2];
|
|
double xa, ya, xb, yb, xc, yc;
|
|
|
|
xa = 0.5*(x1 - y2);
|
|
xb = 0.5*(x2 - y1);
|
|
xc = 0.5*(x1 - y1);
|
|
ya = 0.5*(x1 + y1);
|
|
yb = 0.5*(x2 + y2);
|
|
yc = 0.5*(x2 + y1);
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
xy_to_pos(xc, ya, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(xb, yc, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(xc, yb, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(xa, yc, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
}
|
|
|
|
void draw_circle(double x, double y, double r, int nseg)
|
|
{
|
|
int i;
|
|
double pos[2], alpha, dalpha;
|
|
|
|
dalpha = DPI/(double)nseg;
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<=nseg; i++)
|
|
{
|
|
alpha = (double)i*dalpha;
|
|
xy_to_pos(x + r*cos(alpha), y + r*sin(alpha), pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
void draw_colored_circle(double x, double y, double r, int nseg, double rgb[3])
|
|
{
|
|
int i;
|
|
double pos[2], alpha, dalpha;
|
|
|
|
dalpha = DPI/(double)nseg;
|
|
|
|
glColor3f(rgb[0], rgb[1], rgb[2]);
|
|
glBegin(GL_TRIANGLE_FAN);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
for (i=0; i<=nseg; i++)
|
|
{
|
|
alpha = (double)i*dalpha;
|
|
xy_to_pos(x + r*cos(alpha), y + r*sin(alpha), pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
|
|
glEnd();
|
|
}
|
|
|
|
void draw_tpolygon(t_polygon polygon)
|
|
{
|
|
int i;
|
|
double pos[2], alpha, dalpha;
|
|
|
|
dalpha = DPI/(double)polygon.nsides;
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<=polygon.nsides; i++)
|
|
{
|
|
alpha = PID*polygon.angle + (double)i*dalpha;
|
|
xy_to_pos(polygon.xc + polygon.radius*cos(alpha), polygon.yc + polygon.radius*sin(alpha), pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
|
|
void init_circle_config(t_circle circles[NMAXCIRCLES])
|
|
/* initialise the arrays circlex, circley, circlerad and circleactive */
|
|
/* for billiard shape D_CIRCLES */
|
|
{
|
|
int i, j, k, n, ncirc0, n_p_active, ncandidates=5000, naccepted;
|
|
double dx, dy, p, phi, r, r0, ra[5], sa[5], height, x, y = 0.0, gamma, dpoisson = 3.25*MU, xx[4], yy[4];
|
|
short int active_poisson[NMAXCIRCLES], far;
|
|
|
|
switch (CIRCLE_PATTERN) {
|
|
case (C_SQUARE):
|
|
{
|
|
ncircles = NGRIDX*NGRIDY;
|
|
dy = (YMAX - YMIN)/((double)NGRIDY);
|
|
for (i = 0; i < NGRIDX; i++)
|
|
for (j = 0; j < NGRIDY; j++)
|
|
{
|
|
n = NGRIDY*i + j;
|
|
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy;
|
|
circles[n].yc = YMIN + ((double)j + 0.5)*dy;
|
|
circles[n].radius = MU;
|
|
circles[n].active = 1;
|
|
}
|
|
break;
|
|
}
|
|
case (C_HEX):
|
|
{
|
|
ncircles = NGRIDX*(NGRIDY+1);
|
|
dy = (YMAX - YMIN)/((double)NGRIDY);
|
|
dx = dy*0.5*sqrt(3.0);
|
|
for (i = 0; i < NGRIDX; i++)
|
|
for (j = 0; j < NGRIDY+1; j++)
|
|
{
|
|
n = (NGRIDY+1)*i + j;
|
|
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy; /* is +0.5 needed? */
|
|
circles[n].yc = YMIN + ((double)j - 0.5)*dy;
|
|
if ((i+NGRIDX)%2 == 1) circles[n].yc += 0.5*dy;
|
|
circles[n].radius = MU;
|
|
/* activate only circles that intersect the domain */
|
|
if ((circles[n].yc < YMAX + MU)&&(circles[n].yc > YMIN - MU)) circles[n].active = 1;
|
|
else circles[n].active = 0;
|
|
}
|
|
break;
|
|
}
|
|
case (C_RAND_DISPLACED):
|
|
{
|
|
ncircles = NGRIDX*NGRIDY;
|
|
dy = (YMAX - YMIN)/((double)NGRIDY);
|
|
for (i = 0; i < NGRIDX; i++)
|
|
for (j = 0; j < NGRIDY; j++)
|
|
{
|
|
n = NGRIDY*i + j;
|
|
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
|
|
circles[n].yc = YMIN + ((double)j + 0.5 + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
|
|
circles[n].radius = MU*sqrt(1.0 + 0.8*((double)rand()/RAND_MAX - 0.5));
|
|
circles[n].active = 1;
|
|
}
|
|
break;
|
|
}
|
|
case (C_RAND_PERCOL):
|
|
{
|
|
ncircles = NGRIDX*NGRIDY;
|
|
dy = (YMAX - YMIN)/((double)NGRIDY);
|
|
for (i = 0; i < NGRIDX; i++)
|
|
for (j = 0; j < NGRIDY; j++)
|
|
{
|
|
n = NGRIDY*i + j;
|
|
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy;
|
|
circles[n].yc = YMIN + ((double)j + 0.5)*dy;
|
|
circles[n].radius = MU;
|
|
p = (double)rand()/RAND_MAX;
|
|
if (p < P_PERCOL) circles[n].active = 1;
|
|
else circles[n].active = 0;
|
|
}
|
|
break;
|
|
}
|
|
case (C_RAND_POISSON):
|
|
{
|
|
ncircles = NPOISSON;
|
|
for (n = 0; n < NPOISSON; n++)
|
|
{
|
|
circles[n].xc = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
|
|
circles[n].yc = (YMAX - YMIN)*(double)rand()/RAND_MAX + YMIN;
|
|
circles[n].radius = MU;
|
|
circles[n].active = 1;
|
|
}
|
|
break;
|
|
}
|
|
case (C_CLOAK):
|
|
{
|
|
ncircles = 200;
|
|
for (i = 0; i < 40; i++)
|
|
for (j = 0; j < 5; j++)
|
|
{
|
|
n = 5*i + j;
|
|
phi = (double)i*DPI/40.0;
|
|
r = LAMBDA*0.5*(1.0 + (double)j/5.0);
|
|
circles[n].xc = r*cos(phi);
|
|
circles[n].yc = r*sin(phi);
|
|
circles[n].radius = MU;
|
|
circles[n].active = 1;
|
|
}
|
|
break;
|
|
}
|
|
case (C_CLOAK_A): /* optimized model A1 by C. Jo et al */
|
|
{
|
|
ncircles = 200;
|
|
ra[0] = 0.0731; sa[0] = 1.115;
|
|
ra[1] = 0.0768; sa[1] = 1.292;
|
|
ra[2] = 0.0652; sa[2] = 1.464;
|
|
ra[3] = 0.056; sa[3] = 1.633;
|
|
ra[4] = 0.0375; sa[4] = 1.794;
|
|
for (i = 0; i < 40; i++)
|
|
for (j = 0; j < 5; j++)
|
|
{
|
|
n = 5*i + j;
|
|
phi = (double)i*DPI/40.0;
|
|
r = LAMBDA*sa[j];
|
|
circles[n].xc = r*cos(phi);
|
|
circles[n].yc = r*sin(phi);
|
|
circles[n].radius = LAMBDA*ra[j];
|
|
circles[n].active = 1;
|
|
}
|
|
break;
|
|
}
|
|
case (C_LASER):
|
|
{
|
|
ncircles = 17;
|
|
|
|
xx[0] = 0.5*(X_SHOOTER + X_TARGET);
|
|
xx[1] = LAMBDA - 0.5*(X_TARGET - X_SHOOTER);
|
|
xx[2] = -xx[0];
|
|
xx[3] = -xx[1];
|
|
|
|
yy[0] = 0.5*(Y_SHOOTER + Y_TARGET);
|
|
yy[1] = 1.0 - 0.5*(Y_TARGET - Y_SHOOTER);
|
|
yy[2] = -yy[0];
|
|
yy[3] = -yy[1];
|
|
|
|
for (i = 0; i < 4; i++)
|
|
for (j = 0; j < 4; j++)
|
|
{
|
|
circles[4*i + j].xc = xx[i];
|
|
circles[4*i + j].yc = yy[j];
|
|
|
|
}
|
|
|
|
circles[ncircles - 1].xc = X_TARGET;
|
|
circles[ncircles - 1].yc = Y_TARGET;
|
|
|
|
for (i=0; i<ncircles - 1; i++)
|
|
{
|
|
circles[i].radius = MU;
|
|
circles[i].active = 1;
|
|
}
|
|
|
|
circles[ncircles - 1].radius = 0.5*MU;
|
|
circles[ncircles - 1].active = 2;
|
|
|
|
break;
|
|
}
|
|
case (C_POISSON_DISC):
|
|
{
|
|
printf("Generating Poisson disc sample\n");
|
|
/* generate first circle */
|
|
circles[0].xc = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
|
|
circles[0].yc = (YMAX - YMIN)*(double)rand()/RAND_MAX + YMIN;
|
|
active_poisson[0] = 1;
|
|
// circles[0].active = 1;
|
|
n_p_active = 1;
|
|
ncircles = 1;
|
|
|
|
while ((n_p_active > 0)&&(ncircles < NMAXCIRCLES))
|
|
{
|
|
/* randomly select an active circle */
|
|
i = rand()%(ncircles);
|
|
while (!active_poisson[i]) i = rand()%(ncircles);
|
|
// printf("Starting from circle %i at (%.3f,%.3f)\n", i, circles[i].xc, circles[i].yc);
|
|
/* generate new candidates */
|
|
naccepted = 0;
|
|
for (j=0; j<ncandidates; j++)
|
|
{
|
|
r = dpoisson*(2.0*(double)rand()/RAND_MAX + 1.0);
|
|
phi = DPI*(double)rand()/RAND_MAX;
|
|
x = circles[i].xc + r*cos(phi);
|
|
y = circles[i].yc + r*sin(phi);
|
|
// printf("Testing new circle at (%.3f,%.3f)\t", x, y);
|
|
far = 1;
|
|
for (k=0; k<ncircles; k++) if ((k!=i))
|
|
{
|
|
/* new circle is far away from circle k */
|
|
far = far*((x - circles[k].xc)*(x - circles[k].xc) + (y - circles[k].yc)*(y - circles[k].yc) >= dpoisson*dpoisson);
|
|
/* new circle is in domain */
|
|
far = far*(vabs(x) < LAMBDA)*(y < YMAX)*(y > YMIN);
|
|
}
|
|
if (far) /* accept new circle */
|
|
{
|
|
printf("New circle at (%.3f,%.3f) accepted\n", x, y);
|
|
circles[ncircles].xc = x;
|
|
circles[ncircles].yc = y;
|
|
circles[ncircles].radius = MU;
|
|
circles[ncircles].active = 1;
|
|
active_poisson[ncircles] = 1;
|
|
ncircles++;
|
|
n_p_active++;
|
|
naccepted++;
|
|
}
|
|
// else printf("Rejected\n");
|
|
}
|
|
if (naccepted == 0) /* inactivate circle i */
|
|
{
|
|
// printf("No candidates work, inactivate circle %i\n", i);
|
|
active_poisson[i] = 0;
|
|
n_p_active--;
|
|
}
|
|
printf("%i active circles\n", n_p_active);
|
|
}
|
|
|
|
printf("Generated %i circles\n", ncircles);
|
|
break;
|
|
}
|
|
case (C_GOLDEN_MEAN):
|
|
{
|
|
ncircles = 300;
|
|
gamma = (sqrt(5.0) - 1.0)*0.5; /* golden mean */
|
|
height = YMAX - YMIN;
|
|
dx = 2.0*LAMBDA/((double)ncircles);
|
|
for (n = 0; n < ncircles; n++)
|
|
{
|
|
circles[n].xc = -LAMBDA + n*dx;
|
|
circles[n].yc = y;
|
|
y += height*gamma;
|
|
if (y > YMAX) y -= height;
|
|
circles[n].radius = MU;
|
|
circles[n].active = 1;
|
|
}
|
|
|
|
/* test for circles that overlap top or bottom boundary */
|
|
ncirc0 = ncircles;
|
|
for (n=0; n < ncirc0; n++)
|
|
{
|
|
if (circles[n].yc + circles[n].radius > YMAX)
|
|
{
|
|
circles[ncircles].xc = circles[n].xc;
|
|
circles[ncircles].yc = circles[n].yc - height;
|
|
circles[ncircles].radius = MU;
|
|
circles[ncircles].active = 1;
|
|
ncircles ++;
|
|
}
|
|
else if (circles[n].yc - circles[n].radius < YMIN)
|
|
{
|
|
circles[ncircles].xc = circles[n].xc;
|
|
circles[ncircles].yc = circles[n].yc + height;
|
|
circles[ncircles].radius = MU;
|
|
circles[ncircles].active = 1;
|
|
ncircles ++;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case (C_GOLDEN_SPIRAL):
|
|
{
|
|
ncircles = 1;
|
|
circles[0].xc = 0.0;
|
|
circles[0].yc = 0.0;
|
|
|
|
gamma = (sqrt(5.0) - 1.0)*PI; /* golden mean times 2Pi */
|
|
phi = 0.0;
|
|
r0 = 2.0*MU;
|
|
r = r0 + MU;
|
|
|
|
for (i=0; i<1000; i++)
|
|
{
|
|
x = r*cos(phi);
|
|
y = r*sin(phi);
|
|
|
|
phi += gamma;
|
|
r += MU*r0/r;
|
|
|
|
if ((vabs(x) < LAMBDA)&&(vabs(y) < YMAX + MU))
|
|
{
|
|
circles[ncircles].xc = x;
|
|
circles[ncircles].yc = y;
|
|
ncircles++;
|
|
}
|
|
}
|
|
|
|
for (i=0; i<ncircles; i++)
|
|
{
|
|
circles[i].radius = MU;
|
|
/* inactivate circles outside the domain */
|
|
if ((circles[i].yc < YMAX + MU)&&(circles[i].yc > YMIN - MU)) circles[i].active = 1;
|
|
// printf("i = %i, circlex = %.3lg, circley = %.3lg\n", i, circles[i].xc, circles[i].yc);
|
|
}
|
|
break;
|
|
}
|
|
case (C_SQUARE_HEX):
|
|
{
|
|
ncircles = NGRIDX*(NGRIDY+1);
|
|
dy = (YMAX - YMIN)/((double)NGRIDY);
|
|
dx = dy*0.5*sqrt(3.0);
|
|
for (i = 0; i < NGRIDX; i++)
|
|
for (j = 0; j < NGRIDY+1; j++)
|
|
{
|
|
n = (NGRIDY+1)*i + j;
|
|
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy; /* is +0.5 needed? */
|
|
circles[n].yc = YMIN + ((double)j - 0.5)*dy;
|
|
if (((i+NGRIDX)%4 == 2)||((i+NGRIDX)%4 == 3)) circles[n].yc += 0.5*dy;
|
|
circles[n].radius = MU;
|
|
/* activate only circles that intersect the domain */
|
|
if ((circles[n].yc < YMAX + MU)&&(circles[n].yc > YMIN - MU)) circles[n].active = 1;
|
|
else circles[n].active = 0;
|
|
}
|
|
break;
|
|
}
|
|
case (C_ONE):
|
|
{
|
|
circles[ncircles].xc = 0.0;
|
|
circles[ncircles].yc = 0.0;
|
|
circles[ncircles].radius = MU;
|
|
circles[ncircles].active = 1;
|
|
ncircles += 1;
|
|
break;
|
|
}
|
|
case (C_TWO): /* used for comparison with cloak */
|
|
{
|
|
circles[ncircles].xc = 0.0;
|
|
circles[ncircles].yc = 0.0;
|
|
circles[ncircles].radius = MU;
|
|
circles[ncircles].active = 2;
|
|
ncircles += 1;
|
|
|
|
circles[ncircles].xc = 0.0;
|
|
circles[ncircles].yc = 0.0;
|
|
circles[ncircles].radius = 2.0*MU;
|
|
circles[ncircles].active = 1;
|
|
ncircles += 1;
|
|
break;
|
|
}
|
|
case (C_NOTHING):
|
|
{
|
|
ncircles += 0;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
printf("Function init_circle_config not defined for this pattern \n");
|
|
}
|
|
}
|
|
}
|
|
|
|
void init_polygon_config(t_polygon polygons[NMAXCIRCLES])
|
|
/* initialise the polygon configuration, for billiard shape D_CIRCLES */
|
|
/* uses init_circle_config, this is where C++ would be more elegant */
|
|
{
|
|
int i;
|
|
t_circle circle[NMAXCIRCLES];
|
|
|
|
init_circle_config(circle);
|
|
for (i=0; i<NMAXCIRCLES; i++)
|
|
{
|
|
polygons[i].xc = circle[i].xc;
|
|
polygons[i].yc = circle[i].yc;
|
|
polygons[i].radius = circle[i].radius;
|
|
polygons[i].active = circle[i].active;
|
|
polygons[i].nsides = NPOLY;
|
|
|
|
if (RANDOM_POLY_ANGLE) polygons[i].angle = DPI*(double)rand()/RAND_MAX;
|
|
else polygons[i].angle = APOLY;
|
|
/*
|
|
if (i < ncircles) printf("(x,y) = (%.2f, %.2f), r = %.2f, angle = %.2f, sides = %i\n", polygons[i].xc, polygons[i].yc, polygons[i].radius, polygons[i].angle, polygons[i].nsides);*/
|
|
}
|
|
|
|
}
|
|
|
|
int axial_symmetry(double z1[2], double z2[2], double z[2], double zprime[2])
|
|
/* compute reflection of point z wrt axis through z1 and z2 */
|
|
{
|
|
double u[2], r, zdotu, zparallel[2], zperp[2];
|
|
|
|
/* compute unit vector parallel to z1-z2 */
|
|
u[0] = z2[0] - z1[0];
|
|
u[1] = z2[1] - z1[1];
|
|
r = module2(u[0], u[1]);
|
|
if (r == 0) return(0); /* z1 and z2 are the same */
|
|
|
|
u[0] = u[0]/r;
|
|
u[1] = u[1]/r;
|
|
// printf("u = (%.2f, %.2f)\n", u[0], u[1]);
|
|
|
|
/* projection of z1z on z1z2 */
|
|
zdotu = (z[0] - z1[0])*u[0] + (z[1] - z1[1])*u[1];
|
|
zparallel[0] = zdotu*u[0];
|
|
zparallel[1] = zdotu*u[1];
|
|
// printf("zparallel = (%.2f, %.2f)\n", zparallel[0], zparallel[1]);
|
|
|
|
/* normal vector to z1z2 */
|
|
zperp[0] = z[0] - z1[0] - zparallel[0];
|
|
zperp[1] = z[1] - z1[1] - zparallel[1];
|
|
// printf("zperp = (%.2f, %.2f)\n", zperp[0], zperp[1]);
|
|
|
|
/* reflected point */
|
|
zprime[0] = z[0] - 2.0*zperp[0];
|
|
zprime[1] = z[1] - 2.0*zperp[1];
|
|
|
|
return(1);
|
|
}
|
|
|
|
int axial_symmetry_tvertex(t_vertex z1, t_vertex z2, t_vertex z, t_vertex *zprime)
|
|
/* compute reflection of point z wrt axis through z1 and z2 */
|
|
{
|
|
double r, zdotu;
|
|
t_vertex u, zparallel, zperp;
|
|
|
|
/* compute unit vector parallel to z1-z2 */
|
|
u.x = z2.x - z1.x;
|
|
u.y = z2.y - z1.y;
|
|
r = module2(u.x, u.y);
|
|
if (r == 0) return(0); /* z1 and z2 are the same */
|
|
|
|
u.x = u.x/r;
|
|
u.y = u.y/r;
|
|
|
|
/* projection of z1z on z1z2 */
|
|
zdotu = (z.x - z1.x)*u.x + (z.y - z1.y)*u.y;
|
|
zparallel.x = zdotu*u.x;
|
|
zparallel.y = zdotu*u.y;
|
|
|
|
/* normal vector to z1z2 */
|
|
zperp.x = z.x - z1.x - zparallel.x;
|
|
zperp.y = z.y - z1.y - zparallel.y;
|
|
|
|
/* reflected point */
|
|
zprime->x = z.x - 2.0*zperp.x;
|
|
zprime->y = z.y - 2.0*zperp.y;
|
|
|
|
return(1);
|
|
}
|
|
|
|
int compute_tokarsky_coordinates(double xshift, double yshift, double scaling,
|
|
t_vertex polyline[NMAXPOLY])
|
|
/* compute positions of vertices of tokarsky room */
|
|
{
|
|
int i;
|
|
double pos[2];
|
|
|
|
polyline[0].x = 0.0; polyline[0].y = 2.0;
|
|
polyline[1].x = 1.0; polyline[1].y = 3.0;
|
|
polyline[2].x = 1.0; polyline[2].y = 4.0;
|
|
polyline[3].x = 2.0; polyline[3].y = 4.0;
|
|
polyline[4].x = 2.0; polyline[4].y = 3.0;
|
|
polyline[5].x = 3.0; polyline[5].y = 3.0;
|
|
polyline[6].x = 3.0; polyline[6].y = 2.0;
|
|
polyline[7].x = 5.0; polyline[7].y = 2.0;
|
|
polyline[8].x = 5.0; polyline[8].y = 3.0;
|
|
polyline[9].x = 6.0; polyline[9].y = 3.0;
|
|
|
|
polyline[10].x = 6.0; polyline[10].y = 4.0;
|
|
polyline[11].x = 7.0; polyline[11].y = 3.0;
|
|
polyline[12].x = 8.0; polyline[12].y = 3.0;
|
|
polyline[13].x = 8.0; polyline[13].y = 2.0;
|
|
polyline[14].x = 7.0; polyline[14].y = 2.0;
|
|
polyline[15].x = 7.0; polyline[15].y = 1.0;
|
|
polyline[16].x = 6.0; polyline[16].y = 0.0;
|
|
polyline[17].x = 6.0; polyline[17].y = 1.0;
|
|
polyline[18].x = 5.0; polyline[18].y = 1.0;
|
|
polyline[19].x = 4.0; polyline[19].y = 0.0;
|
|
|
|
polyline[20].x = 4.0; polyline[20].y = 1.0;
|
|
polyline[21].x = 3.0; polyline[21].y = 1.0;
|
|
polyline[22].x = 2.0; polyline[22].y = 0.0;
|
|
polyline[23].x = 2.0; polyline[23].y = 1.0;
|
|
polyline[24].x = 1.0; polyline[24].y = 1.0;
|
|
polyline[25].x = 1.0; polyline[25].y = 2.0;
|
|
|
|
for (i=0; i<26; i++)
|
|
{
|
|
polyline[i].x = (polyline[i].x + xshift)*scaling;
|
|
polyline[i].y = (polyline[i].y + yshift)*scaling;
|
|
xy_to_pos(polyline[i].x, polyline[i].y, pos);
|
|
polyline[i].posi = pos[0];
|
|
polyline[i].posj = pos[1];
|
|
}
|
|
return(26);
|
|
}
|
|
|
|
void compute_isospectral_coordinates(int type, int ishift, double xshift, double yshift, double scaling,
|
|
t_vertex polyline[NMAXPOLY])
|
|
/* compute positions of vertices of isospectral billiards */
|
|
/* central triangle has coordinates (0,0), (1,0) and (LAMBDA,MU) fed into affine transformation */
|
|
/* defined by (xshift - 0.5), (yshift - 0.25) and scaling*/
|
|
{
|
|
int i;
|
|
double pos[2];
|
|
|
|
polyline[ishift].x = (xshift - 0.5)*scaling;
|
|
polyline[ishift].y = (yshift - 0.25)*scaling;
|
|
|
|
polyline[ishift+1].x = (0.5+xshift)*scaling;
|
|
polyline[ishift+1].y = (yshift - 0.25)*scaling;
|
|
|
|
polyline[ishift+2].x = (LAMBDA+xshift - 0.5)*scaling;
|
|
polyline[ishift+2].y = (MU+yshift - 0.25)*scaling;
|
|
|
|
axial_symmetry_tvertex(polyline[ishift], polyline[ishift+2], polyline[ishift+1], &polyline[ishift+3]);
|
|
axial_symmetry_tvertex(polyline[ishift], polyline[ishift+1], polyline[ishift+2], &polyline[ishift+4]);
|
|
axial_symmetry_tvertex(polyline[ishift+1], polyline[ishift+2], polyline[ishift], &polyline[ishift+5]);
|
|
|
|
if (type == 0)
|
|
{
|
|
axial_symmetry_tvertex(polyline[ishift], polyline[ishift+3], polyline[ishift+2], &polyline[ishift+6]);
|
|
axial_symmetry_tvertex(polyline[ishift+1], polyline[ishift+4], polyline[ishift], &polyline[ishift+7]);
|
|
axial_symmetry_tvertex(polyline[ishift+2], polyline[ishift+5], polyline[ishift+1], &polyline[ishift+8]);
|
|
}
|
|
else
|
|
{
|
|
axial_symmetry_tvertex(polyline[ishift+2], polyline[ishift+3], polyline[ishift], &polyline[ishift+6]);
|
|
axial_symmetry_tvertex(polyline[ishift], polyline[ishift+4], polyline[ishift+1], &polyline[ishift+7]);
|
|
axial_symmetry_tvertex(polyline[ishift+1], polyline[ishift+5], polyline[ishift+2], &polyline[ishift+8]);
|
|
}
|
|
|
|
for (i=ishift; i<ishift+9; i++)
|
|
{
|
|
xy_to_pos(polyline[i].x, polyline[i].y, pos);
|
|
polyline[i].posi = pos[0];
|
|
polyline[i].posj = pos[1];
|
|
}
|
|
}
|
|
|
|
|
|
void compute_homophonic_coordinates(int type, int ishift, double xshift, double yshift, double scaling,
|
|
t_vertex polyline[NMAXPOLY])
|
|
/* compute positions of vertices of homophonic billiards */
|
|
{
|
|
int i;
|
|
double pos[2];
|
|
|
|
polyline[ishift].x = (0.5 + xshift)*scaling;
|
|
polyline[ishift].y = (yshift - 0.25)*scaling;
|
|
|
|
polyline[ishift+1].x = (0.25 + xshift)*scaling;
|
|
polyline[ishift+1].y = (0.25*sqrt(3.0) + yshift - 0.25)*scaling;
|
|
|
|
polyline[ishift+2].x = (xshift - 0.5)*scaling;
|
|
polyline[ishift+2].y = (yshift - 0.25)*scaling;
|
|
|
|
axial_symmetry_tvertex(polyline[ishift+1], polyline[ishift+2], polyline[ishift], &polyline[ishift+3]);
|
|
axial_symmetry_tvertex(polyline[ishift], polyline[ishift+1], polyline[ishift+2], &polyline[ishift+21]);
|
|
axial_symmetry_tvertex(polyline[ishift], polyline[ishift+21], polyline[ishift+1], &polyline[ishift+10]);
|
|
axial_symmetry_tvertex(polyline[ishift+10], polyline[ishift+21], polyline[ishift+0], &polyline[ishift+11]);
|
|
axial_symmetry_tvertex(polyline[ishift+11], polyline[ishift+21], polyline[ishift+10], &polyline[ishift+13]);
|
|
axial_symmetry_tvertex(polyline[ishift+11], polyline[ishift+13], polyline[ishift+21], &polyline[ishift+12]);
|
|
axial_symmetry_tvertex(polyline[ishift+13], polyline[ishift+21], polyline[ishift+11], &polyline[ishift+14]);
|
|
axial_symmetry_tvertex(polyline[ishift+14], polyline[ishift+21], polyline[ishift+13], &polyline[ishift+20]);
|
|
axial_symmetry_tvertex(polyline[ishift+14], polyline[ishift+20], polyline[ishift+21], &polyline[ishift+15]);
|
|
axial_symmetry_tvertex(polyline[ishift+20], polyline[ishift+15], polyline[ishift+14], &polyline[ishift+19]);
|
|
|
|
if (type == 0)
|
|
{
|
|
axial_symmetry_tvertex(polyline[ishift], polyline[ishift+2], polyline[ishift+1], &polyline[ishift+8]);
|
|
axial_symmetry_tvertex(polyline[ishift+2], polyline[ishift+8], polyline[ishift+0], &polyline[ishift+7]);
|
|
axial_symmetry_tvertex(polyline[ishift+2], polyline[ishift+7], polyline[ishift+8], &polyline[ishift+5]);
|
|
axial_symmetry_tvertex(polyline[ishift+2], polyline[ishift+5], polyline[ishift+7], &polyline[ishift+4]);
|
|
axial_symmetry_tvertex(polyline[ishift+5], polyline[ishift+7], polyline[ishift+2], &polyline[ishift+6]);
|
|
axial_symmetry_tvertex(polyline[ishift], polyline[ishift+8], polyline[ishift+2], &polyline[ishift+9]);
|
|
|
|
axial_symmetry_tvertex(polyline[ishift+15], polyline[ishift+19], polyline[ishift+20], &polyline[ishift+16]);
|
|
axial_symmetry_tvertex(polyline[ishift+16], polyline[ishift+19], polyline[ishift+15], &polyline[ishift+18]);
|
|
axial_symmetry_tvertex(polyline[ishift+16], polyline[ishift+18], polyline[ishift+19], &polyline[ishift+17]);
|
|
}
|
|
else
|
|
{
|
|
axial_symmetry_tvertex(polyline[ishift+2], polyline[ishift+3], polyline[ishift+1], &polyline[ishift+5]);
|
|
axial_symmetry_tvertex(polyline[ishift+3], polyline[ishift+5], polyline[ishift+2], &polyline[ishift+4]);
|
|
axial_symmetry_tvertex(polyline[ishift+2], polyline[ishift+5], polyline[ishift+3], &polyline[ishift+6]);
|
|
axial_symmetry_tvertex(polyline[ishift+2], polyline[ishift+6], polyline[ishift+5], &polyline[ishift+8]);
|
|
axial_symmetry_tvertex(polyline[ishift+6], polyline[ishift+8], polyline[ishift+2], &polyline[ishift+7]);
|
|
axial_symmetry_tvertex(polyline[ishift+2], polyline[ishift+8], polyline[ishift+6], &polyline[ishift+9]);
|
|
|
|
axial_symmetry_tvertex(polyline[ishift+10], polyline[ishift+11], polyline[ishift+21], &polyline[ishift+16]);
|
|
axial_symmetry_tvertex(polyline[ishift+11], polyline[ishift+12], polyline[ishift+13], &polyline[ishift+18]);
|
|
axial_symmetry_tvertex(polyline[ishift+16], polyline[ishift+18], polyline[ishift+11], &polyline[ishift+17]);
|
|
}
|
|
|
|
for (i=ishift; i<44; i++)
|
|
{
|
|
xy_to_pos(polyline[i].x, polyline[i].y, pos);
|
|
polyline[i].posi = pos[0];
|
|
polyline[i].posj = pos[1];
|
|
}
|
|
}
|
|
|
|
|
|
int compute_vonkoch_coordinates(int depth, t_vertex polyline[NMAXPOLY])
|
|
/* compute positions of vertices of von Koch snowflake fractal */
|
|
{
|
|
int nsides = 3, i, j, k, l, n, z, ii, jj, quater[MDEPTH], cond;
|
|
short int vkoch[NMAXPOLY], turnright;
|
|
double angle, length, x, y, pos[2];
|
|
|
|
for (k=0; k<depth; k++) nsides *= 4;
|
|
ncircles = nsides;
|
|
|
|
if (nsides > NMAXPOLY)
|
|
{
|
|
printf("NMAXPOLY needs to be increased to %i\n", nsides);
|
|
nsides = NMAXPOLY;
|
|
}
|
|
|
|
for (i=0; i<nsides/3; i++)
|
|
{
|
|
/* compute quaternary expansion of i */
|
|
ii = i;
|
|
for (l=0; l<depth; l++)
|
|
{
|
|
quater[l] = ii%4;
|
|
ii = ii - (ii%4);
|
|
ii = ii/4;
|
|
}
|
|
|
|
/* find first nonzero digit */
|
|
z = 0;
|
|
while ((quater[z] == 0)&&(z<depth)) z++;
|
|
|
|
/* compute left/right turns */
|
|
if (i==0) vkoch[0] = 0;
|
|
else if (z != depth)
|
|
{
|
|
if (quater[z] == 2) vkoch[i] = 0;
|
|
else vkoch[i] = 1;
|
|
}
|
|
}
|
|
|
|
/* compute vertices */
|
|
angle = 2.0*PI/3.0;
|
|
x = cos(PI/6.0);
|
|
y = -sin(PI/6.0);
|
|
length = 2.0*sin(PI/3.0);
|
|
|
|
for (k=0; k<depth; k++) length = length/3.0;
|
|
printf("Length = %.2f\n", length);
|
|
|
|
for (i=0; i<nsides; i++)
|
|
{
|
|
polyline[i].x = x*MU;
|
|
polyline[i].y = y*MU;
|
|
|
|
x += length*cos(angle);
|
|
y += length*sin(angle);
|
|
|
|
turnright = vkoch[i%(nsides/3)+1];
|
|
if (turnright) angle -= PI/3.0;
|
|
else angle += 2.0*PI/3.0;
|
|
|
|
while (angle > DPI) angle -= DPI;
|
|
while (angle < 0.0) angle += DPI;
|
|
|
|
xy_to_pos(x*MU, y*MU, pos);
|
|
polyline[i].posi = pos[0];
|
|
polyline[i].posj = pos[1];
|
|
}
|
|
|
|
return(nsides);
|
|
}
|
|
|
|
|
|
int init_polyline(int depth, t_vertex polyline[NMAXPOLY])
|
|
/* initialise variable polyline, for certain polygonal domain shapes */
|
|
{
|
|
switch (B_DOMAIN) {
|
|
case (D_TOKARSKY):
|
|
{
|
|
return(compute_tokarsky_coordinates(-4.0, -2.0, (XMAX - XMIN)/8.4, polyline));
|
|
}
|
|
case (D_ISOSPECTRAL):
|
|
{
|
|
compute_isospectral_coordinates(0, 0, ISO_XSHIFT_LEFT, ISO_YSHIFT_LEFT, ISO_SCALE, polyline);
|
|
compute_isospectral_coordinates(1, 9, ISO_XSHIFT_RIGHT, ISO_YSHIFT_RIGHT, ISO_SCALE, polyline);
|
|
return(18);
|
|
}
|
|
case (D_HOMOPHONIC):
|
|
{
|
|
compute_homophonic_coordinates(0, 0, ISO_XSHIFT_LEFT, ISO_YSHIFT_LEFT, ISO_SCALE, polyline);
|
|
compute_homophonic_coordinates(1, 22, ISO_XSHIFT_RIGHT, ISO_YSHIFT_RIGHT, ISO_SCALE, polyline);
|
|
return(44);
|
|
}
|
|
case (D_VONKOCH):
|
|
{
|
|
return(compute_vonkoch_coordinates(depth, polyline));
|
|
}
|
|
case (D_VONKOCH_HEATED):
|
|
{
|
|
return(compute_vonkoch_coordinates(depth, polyline));
|
|
}
|
|
default:
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void isospectral_initial_point(double x, double y, double left[2], double right[2])
|
|
/* compute initial coordinates in isospectral billiards */
|
|
{
|
|
left[0] = (x + ISO_XSHIFT_LEFT)*ISO_SCALE;
|
|
left[1] = (y + ISO_YSHIFT_LEFT)*ISO_SCALE;
|
|
right[0] = (x + ISO_XSHIFT_RIGHT)*ISO_SCALE;
|
|
right[1] = (y + ISO_YSHIFT_RIGHT)*ISO_SCALE;
|
|
}
|
|
|
|
void homophonic_initial_point(double xleft, double yleft, double xright, double yright, double left[2], double right[2])
|
|
/* compute initial coordinates in isospectral billiards */
|
|
{
|
|
left[0] = (xleft + ISO_XSHIFT_LEFT)*ISO_SCALE;
|
|
left[1] = (yleft + ISO_YSHIFT_LEFT)*ISO_SCALE;
|
|
right[0] = (xright + ISO_XSHIFT_RIGHT)*ISO_SCALE;
|
|
right[1] = (yright + ISO_YSHIFT_RIGHT)*ISO_SCALE;
|
|
}
|
|
|
|
int xy_in_triangle(double x, double y, double z1[2], double z2[2], double z3[2])
|
|
/* returns 1 iff (x,y) is inside the triangle with vertices z1, z2, z3 */
|
|
{
|
|
double v1, v2, v3;
|
|
|
|
/* compute wedge products */
|
|
v1 = (z2[0] - z1[0])*(y - z1[1]) - (z2[1] - z1[1])*(x - z1[0]);
|
|
v2 = (z3[0] - z2[0])*(y - z2[1]) - (z3[1] - z2[1])*(x - z2[0]);
|
|
v3 = (z1[0] - z3[0])*(y - z3[1]) - (z1[1] - z3[1])*(x - z3[0]);
|
|
|
|
if ((v1 >= 0.0)&&(v2 >= 0.0)&&(v3 >= 0.0)) return(1);
|
|
else return(0);
|
|
}
|
|
|
|
int xy_in_triangle_tvertex(double x, double y, t_vertex z1, t_vertex z2, t_vertex z3)
|
|
/* returns 1 iff (x,y) is inside the triangle with vertices z1, z2, z3 */
|
|
{
|
|
double v1, v2, v3;
|
|
|
|
/* compute wedge products */
|
|
v1 = (z2.x - z1.x)*(y - z1.y) - (z2.y - z1.y)*(x - z1.x);
|
|
v2 = (z3.x - z2.x)*(y - z2.y) - (z3.y - z2.y)*(x - z2.x);
|
|
v3 = (z1.x - z3.x)*(y - z3.y) - (z1.y - z3.y)*(x - z3.x);
|
|
|
|
if ((v1 >= 0.0)&&(v2 >= 0.0)&&(v3 >= 0.0)) return(1);
|
|
else return(0);
|
|
}
|
|
|
|
|
|
int xy_in_billiard(double x, double y)
|
|
/* returns 1 if (x,y) represents a point in the billiard */
|
|
// double x, y;
|
|
{
|
|
double l2, r2, r2mu, omega, b, c, angle, z, x1, y1, x2, y2, u, v, u1, v1, dx, dy, width;
|
|
int i, j, k, k1, k2, condition, m;
|
|
static int first = 1, nsides;
|
|
|
|
switch (B_DOMAIN) {
|
|
case (D_RECTANGLE):
|
|
{
|
|
if ((vabs(x) <LAMBDA)&&(vabs(y) < 1.0)) return(1);
|
|
else return(0);
|
|
break;
|
|
}
|
|
case (D_ELLIPSE):
|
|
{
|
|
if (x*x/(LAMBDA*LAMBDA) + y*y < 1.0) return(1);
|
|
else return(0);
|
|
break;
|
|
}
|
|
case (D_STADIUM):
|
|
{
|
|
if ((x > -0.5*LAMBDA)&&(x < 0.5*LAMBDA)&&(y > -1.0)&&(y < 1.0)) return(1);
|
|
else if (module2(x+0.5*LAMBDA, y) < 1.0) return(1);
|
|
else if (module2(x-0.5*LAMBDA, y) < 1.0) return(1);
|
|
else return(0);
|
|
break;
|
|
}
|
|
case (D_SINAI):
|
|
{
|
|
if (x*x + y*y > LAMBDA*LAMBDA) return(1);
|
|
else return(0);
|
|
break;
|
|
}
|
|
case (D_DIAMOND):
|
|
{
|
|
l2 = LAMBDA*LAMBDA;
|
|
r2 = l2 + (LAMBDA-1.0)*(LAMBDA-1.0);
|
|
if ((x*x + y*y < 1.0)&&((x-LAMBDA)*(x-LAMBDA) + (y-LAMBDA)*(y-LAMBDA) > r2)
|
|
&&((x-LAMBDA)*(x-LAMBDA) + (y+LAMBDA)*(y+LAMBDA) > r2)
|
|
&&((x+LAMBDA)*(x+LAMBDA) + (y-LAMBDA)*(y-LAMBDA) > r2)
|
|
&&((x+LAMBDA)*(x+LAMBDA) + (y+LAMBDA)*(y+LAMBDA) > r2)) return(1);
|
|
else return(0);
|
|
break;
|
|
}
|
|
case (D_TRIANGLE):
|
|
{
|
|
if ((x>-LAMBDA)&&(y>-1.0)&&(LAMBDA*y+x<0.0)) return(1);
|
|
else return(0);
|
|
break;
|
|
}
|
|
case (D_FLAT):
|
|
{
|
|
if (y > -LAMBDA) return(1);
|
|
else return(0);
|
|
break;
|
|
}
|
|
case (D_ANNULUS):
|
|
{
|
|
l2 = LAMBDA*LAMBDA;
|
|
r2 = x*x + y*y;
|
|
if ((r2 > l2)&&(r2 < 1.0)) return(1);
|
|
else return(0);
|
|
}
|
|
case (D_POLYGON):
|
|
{
|
|
condition = 1;
|
|
omega = DPI/((double)NPOLY);
|
|
c = cos(omega*0.5);
|
|
for (k=0; k<NPOLY; k++)
|
|
{
|
|
angle = APOLY*PID + (k+0.5)*omega;
|
|
condition = condition*(x*cos(angle) + y*sin(angle) < c);
|
|
}
|
|
// for (k=0; k<NPOLY; k++) condition = condition*(-x*sin((k+0.5)*omega) + y*cos((k+0.5)*omega) < c);
|
|
return(condition);
|
|
}
|
|
case (D_YOUNG):
|
|
{
|
|
if ((x < -MU)||(x > MU)) return(1);
|
|
else if ((vabs(y-LAMBDA) < MU)||(vabs(y+LAMBDA) < MU)) return (1);
|
|
else return(0);
|
|
}
|
|
case (D_GRATING):
|
|
{
|
|
k1 = -(int)((-YMIN)/LAMBDA);
|
|
k2 = (int)(YMAX/LAMBDA);
|
|
condition = 1;
|
|
for (i=k1; i<= k2; i++)
|
|
{
|
|
z = (double)i*LAMBDA;
|
|
condition = condition*(x*x + (y-z)*(y-z) > MU*MU);
|
|
}
|
|
// printf("x = %.3lg, y = %.3lg, k1 = %i, k2 = %i, condition = %i\n", x, y, k1, k2, condition);
|
|
return(condition);
|
|
}
|
|
case (D_EHRENFEST):
|
|
{
|
|
return(((x-1.0)*(x-1.0) + y*y < LAMBDA*LAMBDA)||((x+1.0)*(x+1.0) + y*y < LAMBDA*LAMBDA)||((vabs(x) < 1.0)&&(vabs(y) < MU)));
|
|
}
|
|
case (D_DISK_GRID):
|
|
{
|
|
dy = (YMAX - YMIN)/((double)NGRIDY);
|
|
for (i = -NGRIDX/2; i < NGRIDX/2; i++)
|
|
for (j = 0; j < NGRIDY; j++)
|
|
{
|
|
x1 = ((double)i + 0.5)*dy;
|
|
y1 = YMIN + ((double)j + 0.5)*dy;
|
|
if ((x-x1)*(x-x1) + (y-y1)*(y-y1) < MU*MU) return(0);
|
|
}
|
|
return(1);
|
|
}
|
|
case (D_DISK_HEX):
|
|
{
|
|
dy = (YMAX - YMIN)/((double)NGRIDY);
|
|
dx = dy*0.5*sqrt(3.0);
|
|
for (i = -NGRIDX/2; i < NGRIDX/2; i++)
|
|
for (j = -1; j < NGRIDY; j++)
|
|
{
|
|
x1 = ((double)i + 0.5)*dy;
|
|
y1 = YMIN + ((double)j + 0.5)*dy;
|
|
if ((i+NGRIDX)%2 == 1) y1 += 0.5*dy;
|
|
if ((x-x1)*(x-x1) + (y-y1)*(y-y1) < MU*MU) return(0);
|
|
}
|
|
return(1);
|
|
}
|
|
case (D_PARABOLA):
|
|
{
|
|
return(x > 0.25*y*y/LAMBDA - LAMBDA);
|
|
}
|
|
case (D_TWO_PARABOLAS):
|
|
{
|
|
x1 = 0.25*y*y/MU - MU - LAMBDA;
|
|
x2 = -x1;
|
|
width = 0.25*MU;
|
|
if (width > 0.2) width = 0.2;
|
|
if (vabs(y) > 1.5*MU) return(1);
|
|
else if ((x < x1 - width)||(x > x2 + width)) return(1);
|
|
else if ((x > x1)&&(x < x2)) return(1);
|
|
else return(0);
|
|
}
|
|
case (D_FOUR_PARABOLAS):
|
|
{
|
|
x1 = MU + LAMBDA - 0.25*y*y/MU;
|
|
y1 = MU + LAMBDA - 0.25*x*x/MU;
|
|
return((vabs(x) < x1)&&(vabs(y) < y1));
|
|
}
|
|
case (D_POLY_PARABOLAS):
|
|
{
|
|
condition = 1;
|
|
omega = DPI/((double)NPOLY);
|
|
for (k=0; k<NPOLY; k++)
|
|
{
|
|
angle = APOLY*PID + (k+0.5)*omega;
|
|
x1 = x*cos(angle) + y*sin(angle);
|
|
y1 = -x*sin(angle) + y*cos(angle);
|
|
condition = condition*(x1 < LAMBDA + MU - 0.25*y1*y1/MU);
|
|
}
|
|
return(condition);
|
|
}
|
|
case (D_PENROSE):
|
|
{
|
|
c = sqrt(LAMBDA*LAMBDA - (1.0 - MU)*(1.0 - MU));
|
|
width = 0.1*MU;
|
|
x1 = vabs(x);
|
|
y1 = vabs(y);
|
|
/* sides */
|
|
if (vabs(x) >= LAMBDA) return(0);
|
|
/* upper and lower ellipse */
|
|
else if ((vabs(y) >= MU)&&(x*x/(LAMBDA*LAMBDA) + (y1-MU)*(y1-MU)/((1.0-MU)*(1.0-MU)) >= 1.0)) return(0);
|
|
/* small ellipses */
|
|
else if ((vabs(x) <= c)&&(4.0*(x1-c)*(x1-c)/(MU*MU) + y*y/(MU*MU) <= 1.0)) return(0);
|
|
/* straight parts */
|
|
else if ((vabs(x) >= c)&&(vabs(y) <= width)) return(0);
|
|
else return(1);
|
|
}
|
|
case (D_HYPERBOLA):
|
|
{
|
|
b = MU*sqrt(1.0 + x*x/(LAMBDA*LAMBDA - MU*MU));
|
|
if (y > 1.02*b) return(1);
|
|
else if (y < 0.98*b) return (1);
|
|
else return(0);
|
|
}
|
|
case (D_TOKARSKY):
|
|
{
|
|
x1 = 4.0 + x/(XMAX - XMIN)*8.4;
|
|
y1 = 2.0 + y/(XMAX - XMIN)*8.4;
|
|
if ((x1 <= 0.0)||(x1 >= 8.0)) return(0);
|
|
else if (x1 < 1.0)
|
|
{
|
|
if (y1 <= 2.0) return(0);
|
|
else if (y1 >= x1 + 2.0) return(0);
|
|
else return(1);
|
|
}
|
|
else if (x1 < 2.0)
|
|
{
|
|
if (y1 <= 1.0) return(0);
|
|
else if (y1 >= 4.0) return(0);
|
|
else return(1);
|
|
}
|
|
else if (x1 < 3.0)
|
|
{
|
|
if (y1 <= x1 - 2.0) return(0);
|
|
else if (y1 >= 3.0) return(0);
|
|
else return(1);
|
|
}
|
|
else if (x1 < 4.0)
|
|
{
|
|
if (y1 <= 1.0) return(0);
|
|
else if (y1 >= 2.0) return(0);
|
|
else return(1);
|
|
}
|
|
else if (x1 < 5.0)
|
|
{
|
|
if (y1 <= x1 - 4.0) return(0);
|
|
else if (y1 >= 2.0) return(0);
|
|
else return(1);
|
|
}
|
|
else if (x1 < 6.0)
|
|
{
|
|
if (y1 <= 1.0) return(0);
|
|
else if (y1 >= 3.0) return(0);
|
|
else return(1);
|
|
}
|
|
else if (x1 < 7.0)
|
|
{
|
|
if (y1 <= x1 - 6.0) return(0);
|
|
else if (y1 >= 10.0 - x1) return(0);
|
|
else return(1);
|
|
}
|
|
else
|
|
{
|
|
if (y1 <= 2.0) return(0);
|
|
else if (y1 >= 3.0) return(0);
|
|
else return(1);
|
|
}
|
|
}
|
|
case (D_ISOSPECTRAL):
|
|
{
|
|
/* 1st triangle */
|
|
condition = xy_in_triangle_tvertex(x, y, polyline[0], polyline[1], polyline[2]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[0], polyline[4], polyline[1]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[1], polyline[5], polyline[2]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[0], polyline[2], polyline[3]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[1], polyline[4], polyline[7]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[2], polyline[5], polyline[8]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[0], polyline[3], polyline[6]);
|
|
|
|
/* 2nd triangle */
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[9], polyline[10], polyline[11]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[9], polyline[13], polyline[10]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[10], polyline[14], polyline[11]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[9], polyline[11], polyline[12]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[9], polyline[16], polyline[13]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[10], polyline[17], polyline[14]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[11], polyline[15], polyline[12]);
|
|
return(condition >= 1);
|
|
}
|
|
case (D_HOMOPHONIC):
|
|
{
|
|
/* conditions could be summarised in larger triangles, but this is to keep */
|
|
/* the option of using triangles with other angles than 30-60-90 */
|
|
|
|
/* 1st triangle */
|
|
condition = xy_in_triangle_tvertex(x, y, polyline[2], polyline[0], polyline[1]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[2], polyline[1], polyline[3]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[0], polyline[21], polyline[1]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[0], polyline[10], polyline[21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[10], polyline[11], polyline[21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[11], polyline[13], polyline[21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[11], polyline[12], polyline[13]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[13], polyline[14], polyline[21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[14], polyline[20], polyline[21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[14], polyline[15], polyline[20]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[15], polyline[19], polyline[20]);
|
|
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[2], polyline[4], polyline[5]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[2], polyline[5], polyline[7]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[5], polyline[6], polyline[7]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[2], polyline[7], polyline[8]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[2], polyline[8], polyline[0]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[0], polyline[8], polyline[9]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[0], polyline[9], polyline[10]);
|
|
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[15], polyline[16], polyline[19]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[16], polyline[17], polyline[18]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[16], polyline[18], polyline[19]);
|
|
|
|
/* 2nd triangle */
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+2], polyline[22+0], polyline[22+1]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+2], polyline[22+1], polyline[22+3]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+0], polyline[22+21], polyline[22+1]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+0], polyline[22+10], polyline[22+21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+10], polyline[22+11], polyline[22+21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+11], polyline[22+13], polyline[22+21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+11], polyline[22+12], polyline[22+13]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+13], polyline[22+14], polyline[22+21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+14], polyline[22+20], polyline[22+21]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+14], polyline[22+15], polyline[22+20]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+15], polyline[22+19], polyline[22+20]);
|
|
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+2], polyline[22+3], polyline[22+5]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+3], polyline[22+4], polyline[22+5]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+2], polyline[22+5], polyline[22+6]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+2], polyline[22+6], polyline[22+8]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+2], polyline[22+8], polyline[22+9]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+6], polyline[22+7], polyline[22+8]);
|
|
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+11], polyline[22+10], polyline[22+16]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+11], polyline[22+16], polyline[22+18]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+11], polyline[22+18], polyline[22+12]);
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[22+16], polyline[22+17], polyline[22+18]);
|
|
|
|
return(condition >= 1);
|
|
}
|
|
case (D_CIRCLES):
|
|
{
|
|
for (i = 0; i < ncircles; i++)
|
|
if (circles[i].active)
|
|
{
|
|
x1 = circles[i].xc;
|
|
y1 = circles[i].yc;
|
|
r2 = circles[i].radius*circles[i].radius;
|
|
if ((x-x1)*(x-x1) + (y-y1)*(y-y1) < r2) return(0);
|
|
}
|
|
return(1);
|
|
}
|
|
case (D_CIRCLES_IN_RECT): /* returns 2 inside circles, 0 outside rectangle */
|
|
{
|
|
for (i = 0; i < ncircles; i++)
|
|
if (circles[i].active)
|
|
{
|
|
x1 = circles[i].xc;
|
|
y1 = circles[i].yc;
|
|
r2 = circles[i].radius*circles[i].radius;
|
|
if ((x-x1)*(x-x1) + (y-y1)*(y-y1) < r2) return(2);
|
|
}
|
|
if ((vabs(x) >= LAMBDA)||(vabs(y) >= 1.0)) return(0);
|
|
else return(1);
|
|
}
|
|
case (D_POLYGONS):
|
|
{
|
|
for (i = 0; i < ncircles; i++)
|
|
if ((polygons[i].active)&&(in_tpolygon(x, y, polygons[i]))) return(0);
|
|
return(1);
|
|
}
|
|
case (D_VONKOCH):
|
|
{
|
|
condition = xy_in_triangle_tvertex(x, y, polyline[0], polyline[npolyline/3], polyline[2*npolyline/3]);
|
|
m = 1;
|
|
k = 1;
|
|
for (i = 0; i < MDEPTH; i++)
|
|
{
|
|
m = m*4;
|
|
for (j = 0; j < npolyline/m; j++)
|
|
condition += xy_in_triangle_tvertex(x, y, polyline[j*m + k], polyline[j*m + 2*k], polyline[j*m + 3*k]);
|
|
k = k*4;
|
|
}
|
|
return(condition >= 1);
|
|
}
|
|
case (D_MENGER):
|
|
{
|
|
x1 = 0.5*(x+1.0);
|
|
y1 = 0.5*(y+1.0);
|
|
for (k=0; k<MDEPTH; k++)
|
|
{
|
|
x1 = x1*(double)MRATIO;
|
|
y1 = y1*(double)MRATIO;
|
|
if ((vabs(x)<1.0)&&(vabs(y)<1.0)&&(((int)x1 % MRATIO)==MRATIO/2)&&(((int)y1 % MRATIO)==MRATIO/2)) return(0);
|
|
}
|
|
return(1);
|
|
}
|
|
case (D_JULIA_INT):
|
|
{
|
|
u = x/JULIA_SCALE;
|
|
v = y/JULIA_SCALE;
|
|
i = 0;
|
|
while ((i<MANDELLEVEL)&&(u*u+v*v < 1000.0*MANDELLIMIT))
|
|
{
|
|
u1 = u*u - v*v + julia_x;
|
|
v = 2.0*u*v + julia_y;
|
|
u = u1;
|
|
i++;
|
|
}
|
|
if (u*u + v*v < MANDELLIMIT) return(1);
|
|
else return(0);
|
|
}
|
|
case (D_MENGER_ROTATED):
|
|
{
|
|
x2 = 1.0*(x + y);
|
|
y2 = 1.0*(x - y);
|
|
if ((vabs(x2) < 1.0)&&(vabs(y2) < 1.0))
|
|
{
|
|
x1 = 0.5*(x2 + 1.0);
|
|
y1 = 0.5*(y2 + 1.0);
|
|
for (k=0; k<MDEPTH; k++)
|
|
{
|
|
x1 = x1*(double)MRATIO;
|
|
y1 = y1*(double)MRATIO;
|
|
if ((vabs(x)<1.0)&&(vabs(y)<1.0)&&(((int)x1 % MRATIO)==MRATIO/2)&&(((int)y1 % MRATIO)==MRATIO/2)) return(0);
|
|
}
|
|
}
|
|
return(1);
|
|
}
|
|
case (D_ANNULUS_HEATED): /* returns 2 if in inner circle */
|
|
{
|
|
l2 = LAMBDA*LAMBDA;
|
|
r2 = x*x + y*y;
|
|
r2mu = (x-MU)*(x-MU) + y*y;
|
|
if ((r2mu > l2)&&(r2 < 1.0)) return(1);
|
|
else if (r2mu <= l2) return(2);
|
|
else return (0);
|
|
}
|
|
case (D_MENGER_HEATED):
|
|
{
|
|
if ((vabs(x) >= 1.0)||(vabs(y) >= 1.0)) return(0);
|
|
else
|
|
{
|
|
x1 = 0.5*(x+1.0);
|
|
y1 = 0.5*(y+1.0);
|
|
for (k=0; k<MDEPTH; k++)
|
|
{
|
|
x1 = x1*(double)MRATIO;
|
|
y1 = y1*(double)MRATIO;
|
|
if ((((int)x1 % MRATIO)==MRATIO/2)&&(((int)y1 % MRATIO)==MRATIO/2)) return(k+2);
|
|
}
|
|
return(1);
|
|
}
|
|
}
|
|
case (D_MENGER_H_OPEN): /* returns 2 if in inner circle */
|
|
{
|
|
x1 = 0.5*(x+1.0);
|
|
y1 = 0.5*(y+1.0);
|
|
for (k=0; k<MDEPTH; k++)
|
|
{
|
|
x1 = x1*(double)MRATIO;
|
|
y1 = y1*(double)MRATIO;
|
|
if ((vabs(x)<1.0)&&(vabs(y)<1.0)&&(((int)x1 % MRATIO)==MRATIO/2)&&(((int)y1 % MRATIO)==MRATIO/2)) return(k+2);
|
|
}
|
|
return(1);
|
|
}
|
|
case (D_MANDELBROT):
|
|
{
|
|
u = 0.0;
|
|
v = 0.0;
|
|
i = 0;
|
|
while ((i<MANDELLEVEL)&&(u*u+v*v < 1000.0*MANDELLIMIT))
|
|
{
|
|
u1 = u*u - v*v + x;
|
|
v = 2.0*u*v + y;
|
|
u = u1;
|
|
i++;
|
|
/* old version used */
|
|
/* u1 = u*u - v*v - x; */
|
|
/* v = 2.0*u*v - y; */
|
|
}
|
|
if (u*u + v*v < MANDELLIMIT) return(0);
|
|
else if ((x-0.5)*(x-0.5)/3.0 + y*y/1.0 > 1.2) return(2);
|
|
else return(1);
|
|
}
|
|
case (D_MANDELBROT_CIRCLE):
|
|
{
|
|
u = 0.0;
|
|
v = 0.0;
|
|
i = 0;
|
|
while ((i<MANDELLEVEL)&&(u*u+v*v < 1000.0*MANDELLIMIT))
|
|
{
|
|
u1 = u*u - v*v + x;
|
|
v = 2.0*u*v + y;
|
|
u = u1;
|
|
i++;
|
|
}
|
|
if (u*u + v*v < MANDELLIMIT) return(0);
|
|
else if ((x-LAMBDA)*(x-LAMBDA) + (y-0.5)*(y-0.5) < MU*MU) return(2);
|
|
else return(1);
|
|
}
|
|
case (D_JULIA):
|
|
{
|
|
u = x/JULIA_SCALE;
|
|
v = y/JULIA_SCALE;
|
|
i = 0;
|
|
while ((i<MANDELLEVEL)&&(u*u+v*v < 1000.0*MANDELLIMIT))
|
|
{
|
|
u1 = u*u - v*v + julia_x;
|
|
v = 2.0*u*v + julia_y;
|
|
u = u1;
|
|
i++;
|
|
// printf("x = %.5lg y = %.5lg i = %i r2 = %.5lg\n", x, y, i, u*u+v*v);
|
|
}
|
|
// printf("i = %i x = %.5lg y = %.5lg r2 = %.5lg\n", i, x, y, u*u+v*v);
|
|
if (u*u + v*v < MANDELLIMIT) return(0);
|
|
else if (x*x/3.0 + y*y/1.0 > 1.2) return(2);
|
|
// else if ((vabs(x) > XMAX - 0.01)||(vabs(y) > YMAX - 0.01)) return(2);
|
|
else return(1);
|
|
}
|
|
case (D_VONKOCH_HEATED):
|
|
{
|
|
if (x*x + y*y > LAMBDA*LAMBDA) return(2);
|
|
|
|
x1 = x;
|
|
y1 = y;
|
|
condition = xy_in_triangle_tvertex(x1, y1, polyline[0], polyline[npolyline/3], polyline[2*npolyline/3]);
|
|
m = 1;
|
|
k = 1;
|
|
for (i = 0; i < MDEPTH; i++)
|
|
{
|
|
m = m*4;
|
|
for (j = 0; j < npolyline/m; j++)
|
|
condition += xy_in_triangle_tvertex(x1, y1, polyline[j*m + k], polyline[j*m + 2*k], polyline[j*m + 3*k]);
|
|
k = k*4;
|
|
}
|
|
if (condition > 0) return(0);
|
|
else return(1);
|
|
}
|
|
default:
|
|
{
|
|
printf("Function ij_in_billiard not defined for this billiard \n");
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
int ij_in_billiard(int i, int j)
|
|
/* returns 1 if (i,j) represents a point in the billiard */
|
|
{
|
|
double xy[2];
|
|
|
|
ij_to_xy(i, j, xy);
|
|
|
|
return(xy_in_billiard(xy[0], xy[1]));
|
|
}
|
|
|
|
void tvertex_lineto(t_vertex z)
|
|
/* draws boundary segments of isospectral billiard */
|
|
{
|
|
glVertex2d(z.posi, z.posj);
|
|
}
|
|
|
|
|
|
void draw_billiard() /* draws the billiard boundary */
|
|
{
|
|
double x0, x, y, x1, y1, dx, dy, phi, r = 0.01, pos[2], pos1[2], alpha, dphi, omega, z, l, width, a, b, c, ymax;
|
|
int i, j, k, k1, k2, mr2;
|
|
static int first = 1, nsides;
|
|
|
|
if (BLACK) glColor3f(1.0, 1.0, 1.0);
|
|
else glColor3f(0.0, 0.0, 0.0);
|
|
glLineWidth(BOUNDARY_WIDTH);
|
|
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
switch (B_DOMAIN) {
|
|
case (D_RECTANGLE):
|
|
{
|
|
glBegin(GL_LINE_LOOP);
|
|
xy_to_pos(LAMBDA, -1.0, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(LAMBDA, 1.0, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-LAMBDA, 1.0, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-LAMBDA, -1.0, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
break;
|
|
}
|
|
case (D_ELLIPSE):
|
|
{
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = (double)i*DPI/(double)NSEG;
|
|
x = LAMBDA*cos(phi);
|
|
y = sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd ();
|
|
|
|
/* draw foci */
|
|
if (FOCI)
|
|
{
|
|
glColor3f(0.3, 0.3, 0.3);
|
|
x0 = sqrt(LAMBDA*LAMBDA-1.0);
|
|
|
|
glLineWidth(2);
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
draw_circle(x0, 0.0, r, NSEG);
|
|
draw_circle(-x0, 0.0, r, NSEG);
|
|
}
|
|
break;
|
|
}
|
|
case (D_STADIUM):
|
|
{
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = -PID + (double)i*PI/(double)NSEG;
|
|
x = 0.5*LAMBDA + cos(phi);
|
|
y = sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = PID + (double)i*PI/(double)NSEG;
|
|
x = -0.5*LAMBDA + cos(phi);
|
|
y = sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd();
|
|
break;
|
|
}
|
|
case (D_SINAI):
|
|
{
|
|
draw_circle(0.0, 0.0, LAMBDA, NSEG);
|
|
break;
|
|
}
|
|
case (D_DIAMOND):
|
|
{
|
|
alpha = atan(1.0 - 1.0/LAMBDA);
|
|
dphi = (PID - 2.0*alpha)/(double)NSEG;
|
|
r = sqrt(LAMBDA*LAMBDA + (LAMBDA-1.0)*(LAMBDA-1.0));
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = alpha + (double)i*dphi;
|
|
x = -LAMBDA + r*cos(phi);
|
|
y = -LAMBDA + r*sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = alpha - PID + (double)i*dphi;
|
|
x = -LAMBDA + r*cos(phi);
|
|
y = LAMBDA + r*sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = alpha + PI + (double)i*dphi;
|
|
x = LAMBDA + r*cos(phi);
|
|
y = LAMBDA + r*sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = alpha + PID + (double)i*dphi;
|
|
x = LAMBDA + r*cos(phi);
|
|
y = -LAMBDA + r*sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd();
|
|
break;
|
|
}
|
|
case (D_TRIANGLE):
|
|
{
|
|
glBegin(GL_LINE_LOOP);
|
|
xy_to_pos(-LAMBDA, -1.0, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(LAMBDA, -1.0, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-LAMBDA, 1.0, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
break;
|
|
}
|
|
case (D_FLAT):
|
|
{
|
|
glBegin(GL_LINE_LOOP);
|
|
xy_to_pos(XMIN, -LAMBDA, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(XMAX, -LAMBDA, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
break;
|
|
}
|
|
case (D_ANNULUS):
|
|
{
|
|
draw_circle(0.0, 0.0, LAMBDA, NSEG);
|
|
draw_circle(0.0, 0.0, 1.0, NSEG);
|
|
break;
|
|
}
|
|
case (D_POLYGON):
|
|
{
|
|
omega = DPI/((double)NPOLY);
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<=NPOLY; i++)
|
|
{
|
|
x = cos(i*omega + APOLY*PID);
|
|
y = sin(i*omega + APOLY*PID);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd ();
|
|
break;
|
|
}
|
|
case (D_YOUNG):
|
|
{
|
|
glBegin(GL_LINE_STRIP);
|
|
xy_to_pos(-MU, YMIN, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-MU, -LAMBDA-MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(MU, -LAMBDA-MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(MU, YMIN, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
xy_to_pos(-MU, YMAX, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-MU, LAMBDA+MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(MU, LAMBDA+MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(MU, YMAX, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
xy_to_pos(-MU, -LAMBDA+MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-MU, LAMBDA-MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(MU, LAMBDA-MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(MU, -LAMBDA+MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
glEnd();
|
|
break;
|
|
}
|
|
case (D_GRATING):
|
|
{
|
|
k1 = -(int)(-YMIN/LAMBDA);
|
|
k2 = (int)(YMAX/LAMBDA);
|
|
for (i=k1; i<= k2; i++)
|
|
{
|
|
z = (double)i*LAMBDA;
|
|
draw_circle(0.0, z, MU, NSEG);
|
|
}
|
|
break;
|
|
}
|
|
case (D_EHRENFEST):
|
|
{
|
|
alpha = asin(MU/LAMBDA);
|
|
x0 = 1.0 - sqrt(LAMBDA*LAMBDA - MU*MU);
|
|
dphi = 2.0*(PI-alpha)/((double)NSEG);
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = -PI + alpha + (double)i*dphi;
|
|
x = 1.0 + LAMBDA*cos(phi);
|
|
y = LAMBDA*sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = alpha + (double)i*dphi;
|
|
x = -1.0 + LAMBDA*cos(phi);
|
|
y = LAMBDA*sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd ();
|
|
break;
|
|
}
|
|
case (D_DISK_GRID):
|
|
{
|
|
glLineWidth(2);
|
|
for (i = -NGRIDX/2; i < NGRIDX/2; i++)
|
|
for (j = 0; j < NGRIDY; j++)
|
|
{
|
|
dy = (YMAX - YMIN)/((double)NGRIDY);
|
|
dx = dy*0.5*sqrt(3.0);
|
|
x1 = ((double)i + 0.5)*dy;
|
|
y1 = YMIN + ((double)j + 0.5)*dy;
|
|
draw_circle(x1, y1, MU, NSEG);
|
|
}
|
|
break;
|
|
}
|
|
case (D_DISK_HEX):
|
|
{
|
|
glLineWidth(2);
|
|
for (i = -NGRIDX/2; i < NGRIDX/2; i++)
|
|
for (j = -1; j < NGRIDY; j++)
|
|
{
|
|
dy = (YMAX - YMIN)/((double)NGRIDY);
|
|
x1 = ((double)i + 0.5)*dy;
|
|
y1 = YMIN + ((double)j + 0.5)*dy;
|
|
if ((i+NGRIDX)%2 == 1) y1 += 0.5*dy;
|
|
draw_circle(x1, y1, MU, NSEG);
|
|
}
|
|
break;
|
|
}
|
|
case (D_PARABOLA):
|
|
{
|
|
dy = (YMAX - YMIN)/(double)NSEG;
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
y = YMIN + dy*(double)i;
|
|
x = 0.25*y*y/LAMBDA - LAMBDA;
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd ();
|
|
|
|
if (FOCI)
|
|
{
|
|
glColor3f(0.3, 0.3, 0.3);
|
|
draw_circle(0.0, 0.0, r, NSEG);
|
|
}
|
|
break;
|
|
}
|
|
case (D_TWO_PARABOLAS):
|
|
{
|
|
dy = 3.0*MU/(double)NSEG;
|
|
width = 0.25*MU;
|
|
if (width > 0.2) width = 0.2;
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
y = -1.5*MU + dy*(double)i;
|
|
x = 0.25*y*y/MU - MU - LAMBDA;
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
y = 1.5*MU - dy*(double)i;
|
|
x = 0.25*y*y/MU - (MU + width) - LAMBDA;
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd ();
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
y = -1.5*MU + dy*(double)i;
|
|
x = LAMBDA + MU - 0.25*y*y/MU;
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
y = 1.5*MU - dy*(double)i;
|
|
x = LAMBDA + (MU + width) - 0.25*y*y/MU;
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd ();
|
|
|
|
if (FOCI)
|
|
{
|
|
glColor3f(0.3, 0.3, 0.3);
|
|
draw_circle(-LAMBDA, 0.0, r, NSEG);
|
|
draw_circle(LAMBDA, 0.0, r, NSEG);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case (D_FOUR_PARABOLAS):
|
|
{
|
|
x1 = 2.0*(sqrt(MU*(2.0*MU + LAMBDA)) - MU);
|
|
|
|
dy = 2.0*x1/(double)NSEG;
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
y = -x1 + dy*(double)i;
|
|
x = MU + LAMBDA - 0.25*y*y/MU;
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
x = x1 - dy*(double)i;
|
|
y = MU + LAMBDA - 0.25*x*x/MU;
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
y = x1 - dy*(double)i;
|
|
x = -MU - LAMBDA + 0.25*y*y/MU;
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
x = -x1 + dy*(double)i;
|
|
y = -MU - LAMBDA + 0.25*x*x/MU;
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd ();
|
|
|
|
if (FOCI)
|
|
{
|
|
glColor3f(0.3, 0.3, 0.3);
|
|
draw_circle(-LAMBDA, 0.0, r, NSEG);
|
|
draw_circle(LAMBDA, 0.0, r, NSEG);
|
|
draw_circle(0.0, -LAMBDA, r, NSEG);
|
|
draw_circle(0.0, LAMBDA, r, NSEG);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case (D_POLY_PARABOLAS):
|
|
{
|
|
omega = PI/((double)NPOLY);
|
|
a = 0.25/MU;
|
|
b = 1.0/tan(omega);
|
|
c = LAMBDA + MU;
|
|
ymax = (-b + sqrt(b*b + 4.0*a*c))/(2.0*a);
|
|
dy = 2.0*ymax/(double)NSEG;
|
|
|
|
// printf("a = %.3lg, b = %.3lg, ymax = %.3lg\n", a, b,ymax);
|
|
glBegin(GL_LINE_LOOP);
|
|
for (k=0; k<NPOLY; k++)
|
|
{
|
|
alpha = APOLY*PID + (2.0*(double)k+1.0)*omega;
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
y1 = -ymax + dy*(double)i;
|
|
x1 = MU + LAMBDA - 0.25*y1*y1/MU;
|
|
x = x1*cos(alpha) - y1*sin(alpha);
|
|
y = x1*sin(alpha) + y1*cos(alpha);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
}
|
|
glEnd ();
|
|
|
|
if (FOCI)
|
|
{
|
|
glColor3f(0.3, 0.3, 0.3);
|
|
for (k=0; k<NPOLY; k++)
|
|
{
|
|
alpha = APOLY*PID + (2.0*(double)k+1.0)*omega;
|
|
draw_circle(LAMBDA*cos(alpha), LAMBDA*sin(alpha), r, NSEG);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case (D_PENROSE):
|
|
{
|
|
c = sqrt(LAMBDA*LAMBDA - (1.0 - MU)*(1.0 - MU));
|
|
width = 0.1*MU;
|
|
x1 = vabs(x);
|
|
y1 = vabs(y);
|
|
dphi = PI/(double)NSEG;
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
/* upper half ellipse */
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = (double)i*dphi;
|
|
x = LAMBDA*cos(phi);
|
|
y = MU + (1.0-MU)*sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
|
|
/* straight parts */
|
|
xy_to_pos(-LAMBDA, width, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-c, width, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-c, MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
|
|
/* left half ellipse */
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = (double)i*dphi;
|
|
x = -c + 0.5*MU*sin(phi);
|
|
y = MU*cos(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
|
|
/* straight parts */
|
|
xy_to_pos(-c, -width, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-LAMBDA, -width, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(-LAMBDA, -MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
|
|
/* lower half ellipse */
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = (double)i*dphi;
|
|
x = -LAMBDA*cos(phi);
|
|
y = -MU - (1.0-MU)*sin(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
|
|
/* straight parts */
|
|
xy_to_pos(LAMBDA, -width, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(c, -width, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(c, -MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
|
|
/* right half ellipse */
|
|
for (i=0; i<=NSEG; i++)
|
|
{
|
|
phi = (double)i*dphi;
|
|
x = c - 0.5*MU*sin(phi);
|
|
y = -MU*cos(phi);
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
|
|
/* straight parts */
|
|
xy_to_pos(c, width, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(LAMBDA, width, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
xy_to_pos(LAMBDA, MU, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
|
|
glEnd ();
|
|
break;
|
|
}
|
|
case (D_HYPERBOLA):
|
|
{
|
|
dx = (XMAX - XMIN)/(double)NSEG;
|
|
glBegin(GL_LINE_STRIP);
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
x = XMIN + dx*(double)i;
|
|
y = MU*1.02*sqrt(1.0 + x*x/(LAMBDA*LAMBDA - MU*MU));
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd ();
|
|
glBegin(GL_LINE_STRIP);
|
|
for (i = 0; i < NSEG+1; i++)
|
|
{
|
|
x = XMIN + dx*(double)i;
|
|
y = MU*0.98*sqrt(1.0 + x*x/(LAMBDA*LAMBDA - MU*MU));
|
|
xy_to_pos(x, y, pos);
|
|
glVertex2d(pos[0], pos[1]);
|
|
}
|
|
glEnd ();
|
|
|
|
if (FOCI)
|
|
{
|
|
glColor3f(0.3, 0.3, 0.3);
|
|
draw_circle(0.0, LAMBDA, r, NSEG);
|
|
draw_circle(0.0, -LAMBDA, r, NSEG);
|
|
}
|
|
break;
|
|
}
|
|
case (D_TOKARSKY):
|
|
{
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<npolyline; i++) tvertex_lineto(polyline[i]);
|
|
glEnd();
|
|
if (FOCI)
|
|
{
|
|
x = (XMAX - XMIN)/4.2;
|
|
glColor3f(0.3, 0.3, 0.3);
|
|
draw_circle(x, 0.0, r, NSEG);
|
|
draw_circle(-x, 0.0, r, NSEG);
|
|
}
|
|
break;
|
|
}
|
|
case (D_ISOSPECTRAL):
|
|
{
|
|
/* 1st triangle */
|
|
glBegin(GL_LINE_LOOP);
|
|
tvertex_lineto(polyline[0]);
|
|
tvertex_lineto(polyline[4]);
|
|
tvertex_lineto(polyline[7]);
|
|
tvertex_lineto(polyline[1]);
|
|
tvertex_lineto(polyline[5]);
|
|
tvertex_lineto(polyline[8]);
|
|
tvertex_lineto(polyline[2]);
|
|
tvertex_lineto(polyline[3]);
|
|
tvertex_lineto(polyline[6]);
|
|
glEnd();
|
|
|
|
/* inner lines */
|
|
glBegin(GL_LINE_LOOP);
|
|
tvertex_lineto(polyline[0]);
|
|
tvertex_lineto(polyline[1]);
|
|
tvertex_lineto(polyline[2]);
|
|
tvertex_lineto(polyline[0]);
|
|
tvertex_lineto(polyline[3]);
|
|
tvertex_lineto(polyline[2]);
|
|
tvertex_lineto(polyline[5]);
|
|
tvertex_lineto(polyline[1]);
|
|
tvertex_lineto(polyline[4]);
|
|
glEnd();
|
|
|
|
/* 2nd triangle */
|
|
glBegin(GL_LINE_LOOP);
|
|
tvertex_lineto( polyline[9]);
|
|
tvertex_lineto(polyline[16]);
|
|
tvertex_lineto(polyline[13]);
|
|
tvertex_lineto(polyline[10]);
|
|
tvertex_lineto(polyline[17]);
|
|
tvertex_lineto(polyline[14]);
|
|
tvertex_lineto(polyline[11]);
|
|
tvertex_lineto(polyline[15]);
|
|
tvertex_lineto(polyline[12]);
|
|
glEnd();
|
|
|
|
/* inner lines */
|
|
glBegin(GL_LINE_LOOP);
|
|
tvertex_lineto( polyline[9]);
|
|
tvertex_lineto(polyline[10]);
|
|
tvertex_lineto(polyline[11]);
|
|
tvertex_lineto( polyline[9]);
|
|
tvertex_lineto(polyline[13]);
|
|
tvertex_lineto(polyline[10]);
|
|
tvertex_lineto(polyline[14]);
|
|
tvertex_lineto(polyline[11]);
|
|
tvertex_lineto(polyline[12]);
|
|
glEnd();
|
|
break;
|
|
}
|
|
case (D_HOMOPHONIC):
|
|
{
|
|
/* 1st triangle */
|
|
glBegin(GL_LINE_LOOP);
|
|
tvertex_lineto(polyline[1]);
|
|
tvertex_lineto(polyline[3]);
|
|
tvertex_lineto(polyline[4]);
|
|
tvertex_lineto(polyline[5]);
|
|
tvertex_lineto(polyline[6]);
|
|
tvertex_lineto(polyline[8]);
|
|
tvertex_lineto(polyline[9]);
|
|
tvertex_lineto(polyline[10]);
|
|
tvertex_lineto(polyline[12]);
|
|
tvertex_lineto(polyline[13]);
|
|
tvertex_lineto(polyline[15]);
|
|
tvertex_lineto(polyline[16]);
|
|
tvertex_lineto(polyline[17]);
|
|
tvertex_lineto(polyline[18]);
|
|
tvertex_lineto(polyline[20]);
|
|
glEnd();
|
|
|
|
/* inner lines */
|
|
glLineWidth(BOUNDARY_WIDTH/2);
|
|
glBegin(GL_LINE_STRIP);
|
|
tvertex_lineto(polyline[9]);
|
|
tvertex_lineto(polyline[1]);
|
|
tvertex_lineto(polyline[2]);
|
|
tvertex_lineto(polyline[5]);
|
|
tvertex_lineto(polyline[7]);
|
|
tvertex_lineto(polyline[2]);
|
|
tvertex_lineto(polyline[8]);
|
|
tvertex_lineto(polyline[21]);
|
|
tvertex_lineto(polyline[10]);
|
|
tvertex_lineto(polyline[2]);
|
|
tvertex_lineto(polyline[21]);
|
|
tvertex_lineto(polyline[11]);
|
|
tvertex_lineto(polyline[13]);
|
|
tvertex_lineto(polyline[21]);
|
|
tvertex_lineto(polyline[14]);
|
|
tvertex_lineto(polyline[20]);
|
|
tvertex_lineto(polyline[15]);
|
|
tvertex_lineto(polyline[19]);
|
|
tvertex_lineto(polyline[16]);
|
|
tvertex_lineto(polyline[18]);
|
|
glEnd();
|
|
|
|
/* 2nd triangle */
|
|
glLineWidth(BOUNDARY_WIDTH);
|
|
glBegin(GL_LINE_LOOP);
|
|
tvertex_lineto(polyline[22+10]);
|
|
tvertex_lineto(polyline[22+16]);
|
|
tvertex_lineto(polyline[22+17]);
|
|
tvertex_lineto(polyline[22+18]);
|
|
tvertex_lineto(polyline[22+12]);
|
|
tvertex_lineto(polyline[22+13]);
|
|
tvertex_lineto(polyline[22+15]);
|
|
tvertex_lineto(polyline[22+19]);
|
|
tvertex_lineto(polyline[22+20]);
|
|
tvertex_lineto(polyline[22+1]);
|
|
tvertex_lineto(polyline[22+4]);
|
|
tvertex_lineto(polyline[22+5]);
|
|
tvertex_lineto(polyline[22+7]);
|
|
tvertex_lineto(polyline[22+8]);
|
|
tvertex_lineto(polyline[22+9]);
|
|
glEnd();
|
|
|
|
/* inner lines */
|
|
glLineWidth(BOUNDARY_WIDTH/2);
|
|
glBegin(GL_LINE_STRIP);
|
|
tvertex_lineto(polyline[22+2]);
|
|
tvertex_lineto(polyline[22+6]);
|
|
tvertex_lineto(polyline[22+8]);
|
|
tvertex_lineto(polyline[22+2]);
|
|
tvertex_lineto(polyline[22+5]);
|
|
tvertex_lineto(polyline[22+3]);
|
|
tvertex_lineto(polyline[22+2]);
|
|
tvertex_lineto(polyline[22+1]);
|
|
tvertex_lineto(polyline[22+0]);
|
|
tvertex_lineto(polyline[22+21]);
|
|
tvertex_lineto(polyline[22+18]);
|
|
tvertex_lineto(polyline[22+16]);
|
|
tvertex_lineto(polyline[22+13]);
|
|
tvertex_lineto(polyline[22+21]);
|
|
tvertex_lineto(polyline[22+10]);
|
|
tvertex_lineto(polyline[22+12]);
|
|
tvertex_lineto(polyline[22+21]);
|
|
tvertex_lineto(polyline[22+14]);
|
|
tvertex_lineto(polyline[22+20]);
|
|
tvertex_lineto(polyline[22+15]);
|
|
glEnd();
|
|
break;
|
|
}
|
|
case (D_VONKOCH):
|
|
{
|
|
glLineWidth(BOUNDARY_WIDTH/2);
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<npolyline; i++) tvertex_lineto(polyline[i]);
|
|
glEnd();
|
|
break;
|
|
}
|
|
case (D_CIRCLES):
|
|
{
|
|
glLineWidth(BOUNDARY_WIDTH);
|
|
for (i = 0; i < ncircles; i++)
|
|
if (circles[i].active) draw_circle(circles[i].xc, circles[i].yc, circles[i].radius, NSEG);
|
|
break;
|
|
}
|
|
case (D_CIRCLES_IN_RECT):
|
|
{
|
|
glLineWidth(BOUNDARY_WIDTH);
|
|
for (i = 0; i < ncircles; i++)
|
|
if (circles[i].active) draw_circle(circles[i].xc, circles[i].yc, circles[i].radius, NSEG);
|
|
draw_rectangle(-LAMBDA, -1.0, LAMBDA, 1.0);
|
|
if ((FOCI)&&(CIRCLE_PATTERN == C_LASER))
|
|
{
|
|
glColor3f(0.3, 0.3, 0.3);
|
|
draw_circle(X_SHOOTER, Y_SHOOTER, r, NSEG);
|
|
}
|
|
break;
|
|
}
|
|
case (D_POLYGONS):
|
|
{
|
|
glLineWidth(BOUNDARY_WIDTH);
|
|
for (i = 0; i < ncircles; i++)
|
|
if (polygons[i].active) draw_tpolygon(polygons[i]);
|
|
break;
|
|
}
|
|
case (D_MENGER):
|
|
{
|
|
glLineWidth(3);
|
|
// draw_rectangle(XMIN, -1.0, XMAX, 1.0);
|
|
|
|
/* level 1 */
|
|
if (MDEPTH > 0)
|
|
{
|
|
glLineWidth(2);
|
|
x = 1.0/((double)MRATIO);
|
|
draw_rectangle(x, x, -x, -x);
|
|
}
|
|
|
|
/* level 2 */
|
|
if (MDEPTH > 1)
|
|
{
|
|
glLineWidth(1);
|
|
mr2 = MRATIO*MRATIO;
|
|
l = 2.0/((double)mr2);
|
|
|
|
for (i=0; i<MRATIO; i++)
|
|
for (j=0; j<MRATIO; j++)
|
|
if ((i!=MRATIO/2)||(j!=MRATIO/2))
|
|
{
|
|
x = -1.0 - 0.5*l + 2.0*((double)i + 0.5)/((double)MRATIO);
|
|
y = -1.0 - 0.5*l + 2.0*((double)j + 0.5)/((double)MRATIO);
|
|
draw_rectangle(x, y, x+l, y+l);
|
|
}
|
|
}
|
|
|
|
/* level 3 */
|
|
if (MDEPTH > 2)
|
|
{
|
|
glLineWidth(1);
|
|
l = 2.0/((double)(mr2*MRATIO));
|
|
|
|
for (i=0; i<mr2; i++)
|
|
for (j=0; j<mr2; j++)
|
|
if ( (((i%MRATIO!=MRATIO/2))||(j%MRATIO!=MRATIO/2)) && (((i/MRATIO!=MRATIO/2))||(j/MRATIO!=MRATIO/2)) )
|
|
{
|
|
x = -1.0 - 0.5*l + 2.0*((double)i + 0.5)/((double)mr2);
|
|
y = -1.0 - 0.5*l + 2.0*((double)j + 0.5)/((double)mr2);
|
|
draw_rectangle(x, y, x+l, y+l);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case (D_JULIA_INT):
|
|
{
|
|
/* Do nothing */
|
|
break;
|
|
}
|
|
case (D_MENGER_ROTATED):
|
|
{
|
|
glLineWidth(3);
|
|
// draw_rectangle(XMIN, -1.0, XMAX, 1.0);
|
|
|
|
/* level 1 */
|
|
if (MDEPTH > 0)
|
|
{
|
|
glLineWidth(2);
|
|
x = 1.0/((double)MRATIO);
|
|
draw_rotated_rectangle(x, x, -x, -x);
|
|
}
|
|
|
|
/* level 2 */
|
|
if (MDEPTH > 1)
|
|
{
|
|
glLineWidth(1);
|
|
mr2 = MRATIO*MRATIO;
|
|
l = 2.0/((double)mr2);
|
|
|
|
for (i=0; i<MRATIO; i++)
|
|
for (j=0; j<MRATIO; j++)
|
|
if ((i!=MRATIO/2)||(j!=MRATIO/2))
|
|
{
|
|
x = -1.0 - 0.5*l + 2.0*((double)i + 0.5)/((double)MRATIO);
|
|
y = -1.0 - 0.5*l + 2.0*((double)j + 0.5)/((double)MRATIO);
|
|
draw_rotated_rectangle(x, y, x+l, y+l);
|
|
}
|
|
}
|
|
|
|
/* level 3 */
|
|
if (MDEPTH > 2)
|
|
{
|
|
glLineWidth(1);
|
|
l = 2.0/((double)(mr2*MRATIO));
|
|
|
|
for (i=0; i<mr2; i++)
|
|
for (j=0; j<mr2; j++)
|
|
if ( (((i%MRATIO!=MRATIO/2))||(j%MRATIO!=MRATIO/2)) && (((i/MRATIO!=MRATIO/2))||(j/MRATIO!=MRATIO/2)) )
|
|
{
|
|
x = -1.0 - 0.5*l + 2.0*((double)i + 0.5)/((double)mr2);
|
|
y = -1.0 - 0.5*l + 2.0*((double)j + 0.5)/((double)mr2);
|
|
draw_rotated_rectangle(x, y, x+l, y+l);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case (D_ANNULUS_HEATED):
|
|
{
|
|
draw_circle(MU, 0.0, LAMBDA, NSEG);
|
|
draw_circle(0.0, 0.0, 1.0, NSEG);
|
|
break;
|
|
}
|
|
case (D_MENGER_HEATED):
|
|
{
|
|
glLineWidth(3);
|
|
draw_rectangle(-1.0, -1.0, 1.0, 1.0);
|
|
|
|
/* level 1 */
|
|
if (MDEPTH > 0)
|
|
{
|
|
glLineWidth(2);
|
|
x = 1.0/((double)MRATIO);
|
|
draw_rectangle(x, x, -x, -x);
|
|
}
|
|
|
|
/* level 2 */
|
|
if (MDEPTH > 1)
|
|
{
|
|
glLineWidth(1);
|
|
mr2 = MRATIO*MRATIO;
|
|
l = 2.0/((double)mr2);
|
|
|
|
for (i=0; i<MRATIO; i++)
|
|
for (j=0; j<MRATIO; j++)
|
|
if ((i!=MRATIO/2)||(j!=MRATIO/2))
|
|
{
|
|
x = -1.0 - 0.5*l + 2.0*((double)i + 0.5)/((double)MRATIO);
|
|
y = -1.0 - 0.5*l + 2.0*((double)j + 0.5)/((double)MRATIO);
|
|
draw_rectangle(x, y, x+l, y+l);
|
|
}
|
|
}
|
|
|
|
/* level 3 */
|
|
if (MDEPTH > 2)
|
|
{
|
|
glLineWidth(1);
|
|
l = 2.0/((double)(mr2*MRATIO));
|
|
|
|
for (i=0; i<mr2; i++)
|
|
for (j=0; j<mr2; j++)
|
|
if ( (((i%MRATIO!=MRATIO/2))||(j%MRATIO!=MRATIO/2)) && (((i/MRATIO!=MRATIO/2))||(j/MRATIO!=MRATIO/2)) )
|
|
{
|
|
x = -1.0 - 0.5*l + 2.0*((double)i + 0.5)/((double)mr2);
|
|
y = -1.0 - 0.5*l + 2.0*((double)j + 0.5)/((double)mr2);
|
|
draw_rectangle(x, y, x+l, y+l);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case (D_MENGER_H_OPEN):
|
|
{
|
|
glLineWidth(3);
|
|
// draw_rectangle(XMIN, -1.0, XMAX, 1.0);
|
|
|
|
/* level 1 */
|
|
if (MDEPTH > 0)
|
|
{
|
|
glLineWidth(2);
|
|
x = 1.0/((double)MRATIO);
|
|
draw_rectangle(x, x, -x, -x);
|
|
}
|
|
|
|
/* level 2 */
|
|
if (MDEPTH > 1)
|
|
{
|
|
glLineWidth(1);
|
|
mr2 = MRATIO*MRATIO;
|
|
l = 2.0/((double)mr2);
|
|
|
|
for (i=0; i<MRATIO; i++)
|
|
for (j=0; j<MRATIO; j++)
|
|
if ((i!=MRATIO/2)||(j!=MRATIO/2))
|
|
{
|
|
x = -1.0 - 0.5*l + 2.0*((double)i + 0.5)/((double)MRATIO);
|
|
y = -1.0 - 0.5*l + 2.0*((double)j + 0.5)/((double)MRATIO);
|
|
draw_rectangle(x, y, x+l, y+l);
|
|
}
|
|
}
|
|
|
|
/* level 3 */
|
|
if (MDEPTH > 2)
|
|
{
|
|
glLineWidth(1);
|
|
l = 2.0/((double)(mr2*MRATIO));
|
|
|
|
for (i=0; i<mr2; i++)
|
|
for (j=0; j<mr2; j++)
|
|
if ( (((i%MRATIO!=MRATIO/2))||(j%MRATIO!=MRATIO/2)) && (((i/MRATIO!=MRATIO/2))||(j/MRATIO!=MRATIO/2)) )
|
|
{
|
|
x = -1.0 - 0.5*l + 2.0*((double)i + 0.5)/((double)mr2);
|
|
y = -1.0 - 0.5*l + 2.0*((double)j + 0.5)/((double)mr2);
|
|
draw_rectangle(x, y, x+l, y+l);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case (D_MANDELBROT):
|
|
{
|
|
/* Do nothing */
|
|
break;
|
|
}
|
|
case (D_MANDELBROT_CIRCLE):
|
|
{
|
|
/* Do nothing */
|
|
break;
|
|
}
|
|
case (D_JULIA):
|
|
{
|
|
/* Do nothing */
|
|
break;
|
|
}
|
|
case (D_VONKOCH_HEATED):
|
|
{
|
|
glLineWidth(BOUNDARY_WIDTH/2);
|
|
glBegin(GL_LINE_LOOP);
|
|
for (i=0; i<npolyline; i++) glVertex2d(polyline[i].posi, polyline[i].posj);
|
|
glEnd();
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
printf("Function draw_billiard not defined for this billiard \n");
|
|
}
|
|
}
|
|
}
|
|
|
|
void draw_color_scheme(double x1, double y1, double x2, double y2, int plot, double min, double max)
|
|
{
|
|
int j, k, ij_botleft[2], ij_topright[2], imin, imax, jmin, jmax;
|
|
double y, dy, dy_e, rgb[3], value;
|
|
|
|
xy_to_ij(x1, y1, ij_botleft);
|
|
xy_to_ij(x2, y2, ij_topright);
|
|
|
|
if (ROTATE_COLOR_SCHEME)
|
|
{
|
|
jmin = ij_botleft[0];
|
|
jmax = ij_topright[0];
|
|
imin = ij_botleft[1];
|
|
imax = ij_topright[1];
|
|
}
|
|
else
|
|
{
|
|
imin = ij_botleft[0];
|
|
imax = ij_topright[0];
|
|
jmin = ij_botleft[1];
|
|
jmax = ij_topright[1];
|
|
}
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
dy = (max - min)/((double)(jmax - jmin));
|
|
dy_e = max/((double)(jmax - jmin));
|
|
|
|
for (j = jmin; j < jmax; j++)
|
|
{
|
|
switch (plot) {
|
|
case (P_AMPLITUDE):
|
|
{
|
|
value = min + 1.0*dy*(double)(j - jmin);
|
|
color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
|
|
break;
|
|
}
|
|
case (P_ENERGY):
|
|
{
|
|
value = dy_e*(double)(j - jmin)*100.0/E_SCALE;
|
|
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym(COLOR_SCHEME, value, 1.0, 1, rgb);
|
|
else color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
|
|
break;
|
|
}
|
|
case (P_MEAN_ENERGY):
|
|
{
|
|
value = dy_e*(double)(j - jmin)*100.0/E_SCALE;
|
|
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym(COLOR_SCHEME, value, 1.0, 1, rgb);
|
|
else color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
|
|
break;
|
|
}
|
|
case (P_PHASE):
|
|
{
|
|
value = min + 1.0*dy*(double)(j - jmin);
|
|
color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
|
|
break;
|
|
}
|
|
}
|
|
glColor3f(rgb[0], rgb[1], rgb[2]);
|
|
if (ROTATE_COLOR_SCHEME)
|
|
{
|
|
glVertex2i(j, imin);
|
|
glVertex2i(j, imax);
|
|
glVertex2i(j+1, imax);
|
|
glVertex2i(j+1, imin);
|
|
}
|
|
else
|
|
{
|
|
glVertex2i(imin, j);
|
|
glVertex2i(imax, j);
|
|
glVertex2i(imax, j+1);
|
|
glVertex2i(imin, j+1);
|
|
}
|
|
}
|
|
glEnd ();
|
|
|
|
glColor3f(1.0, 1.0, 1.0);
|
|
glLineWidth(BOUNDARY_WIDTH);
|
|
draw_rectangle(x1, y1, x2, y2);
|
|
}
|
|
|
|
|