2021-05-29 16:50:49 +02:00
/*********************/
/* Graphics routines */
/*********************/
2021-10-24 15:20:56 +02:00
# include "colors_waves.c"
2023-01-22 16:49:04 +01:00
# define TIFF_FREE_PERIOD 1
2021-10-24 15:20:56 +02:00
2021-12-28 15:42:56 +01:00
int writetiff_new ( 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 ;
}
free ( image ) ; /* prenvents RAM consumption*/
TIFFClose ( file ) ;
return 0 ;
}
2021-10-24 15:20:56 +02:00
2021-05-29 16:50:49 +02:00
int writetiff ( char * filename , char * description , int x , int y , int width , int height , int compression )
{
TIFF * file ;
GLubyte * image , * p ;
int i ;
2022-11-20 23:17:39 +01:00
static int counter = 0 ;
2021-05-29 16:50:49 +02:00
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 ;
}
2022-10-18 23:28:20 +02:00
/* added 9/9/22 and removed again, since it produces an unwanted "band" on the right */
2022-11-20 23:17:39 +01:00
/* readded 5/11/22 */
2023-01-22 16:49:04 +01:00
if ( SAVE_MEMORY ) free ( image ) ; /* prevents RAM consumption*/
// {
// counter++;
// if (counter%TIFF_FREE_PERIOD == 0)
// {
// free(image); /* prevents RAM consumption*/
// counter = 0;
// }
// }
2021-05-29 16:50:49 +02:00
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 ) ;
}
2021-12-28 15:42:56 +01:00
void test_save_frame ( ) /* some tests with various resolutions */
{
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 ) ; // works for 1080p -> "-50px"
// choose one of the following according to the comment beside.
// writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT-40, COMPRESSION_LZW);
/* to use with 1080p in drop_billiard.c- probably the best because it's
// generating 1080p image, lighter, and then cropping those 40 pixels to
// avoid the strange band*/
// writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT-50, COMPRESSION_LZW); // works for 1080p -> "-50px" band!!!
// writetiff(n2, "Wave equation in a planar domain", 0, 0, 1920, 1080-40, COMPRESSION_LZW); //another perfect 1080p from 1440p in setup
// writetiff(n2, "Wave equation in a planar domain", -WINWIDTH/8+320, -WINHEIGHT/8+180, WINWIDTH-640, WINHEIGHT-400, COMPRESSION_LZW); // perfect 1040p from 1440p in setup
}
void test_save_frame_counter ( int counter ) /* some tests with various resolutions */
/* 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 ) ; // works for 1080p -> "-50px"
// choose one of the following according to the comment beside.
// writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT-40, COMPRESSION_LZW);
/* to use with 1080p in drop_billiard.c- probably the best because it's
// generating 1080p image, lighter, and then cropping those 40 pixels to
// avoid the strange band*/
// writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT-50, COMPRESSION_LZW); // works for 1080p -> "-50px" band!!!
// writetiff(n2, "Wave equation in a planar domain", 0, 0, 1920, 1080-40, COMPRESSION_LZW); //another perfect 1080p from 1440p in setup
// writetiff(n2, "BWave equation in a planar domain", -WINWIDTH/8+320, -WINHEIGHT/8+180, WINWIDTH-640, WINHEIGHT-400, COMPRESSION_LZW); // perfect 1040p from 1440p in setup
}
2021-05-29 16:50:49 +02:00
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 ) ;
}
2021-08-15 11:49:37 +02:00
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 ) ;
}
2021-09-26 16:47:29 +02:00
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
}
}
2021-05-29 16:50:49 +02:00
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
}
}
2021-06-20 23:31:23 +02:00
2021-05-29 16:50:49 +02:00
/*********************/
/* some basic math */
/*********************/
2021-08-15 11:49:37 +02:00
double vabs ( double x ) /* absolute value */
2021-05-29 16:50:49 +02:00
{
double res ;
if ( x < 0.0 ) res = - x ;
else res = x ;
return ( res ) ;
}
2021-08-15 11:49:37 +02:00
double module2 ( double x , double y ) /* Euclidean norm */
2021-05-29 16:50:49 +02:00
{
double m ;
m = sqrt ( x * x + y * y ) ;
return ( m ) ;
}
2021-08-15 11:49:37 +02:00
double argument ( double x , double y )
2021-05-29 16:50:49 +02:00
{
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 ) ;
}
2023-09-02 11:36:15 +02:00
double iabs ( int i ) /* absolute value */
{
int res ;
if ( i < 0 ) res = - i ;
else res = i ;
return ( i ) ;
}
2021-05-29 16:50:49 +02:00
2023-03-25 19:56:19 +01:00
double gaussian ( )
/* returns standard normal random variable, using Box-Mueller algorithm */
{
static double V1 , V2 , S ;
static int phase = 0 ;
double X ;
if ( phase = = 0 )
{
do
{
double U1 = ( double ) rand ( ) / RAND_MAX ;
double U2 = ( double ) rand ( ) / RAND_MAX ;
V1 = 2 * U1 - 1 ;
V2 = 2 * U2 - 1 ;
S = V1 * V1 + V2 * V2 ;
}
while ( S > = 1 | | S = = 0 ) ;
X = V1 * sqrt ( - 2 * log ( S ) / S ) ;
}
else X = V2 * sqrt ( - 2 * log ( S ) / S ) ;
phase = 1 - phase ;
return X ;
}
2021-11-12 16:22:24 +01:00
// 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 ) ;
}
2021-05-29 16:50:49 +02:00
/*********************/
/* 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 */
2021-08-15 11:49:37 +02:00
void xy_to_ij ( double x , double y , int ij [ 2 ] )
2021-05-29 16:50:49 +02:00
/* 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 ) ;
}
2022-11-20 23:17:39 +01:00
void xy_to_ij_safe ( double x , double y , int ij [ 2 ] )
/* convert (x,y) position to (i,j) in table representing wave, making sure (i,j) are between 0 and NX or NY */
{
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 ) ;
if ( ij [ 0 ] < 0 ) ij [ 0 ] = 0 ;
if ( ij [ 0 ] > NX - 1 ) ij [ 0 ] = NX - 1 ;
if ( ij [ 1 ] < 0 ) ij [ 1 ] = 0 ;
if ( ij [ 1 ] > NY - 1 ) ij [ 1 ] = NY - 1 ;
}
2021-08-15 11:49:37 +02:00
void xy_to_pos ( double x , double y , double pos [ 2 ] )
2021-05-29 16:50:49 +02:00
/* 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 ;
}
2021-08-15 11:49:37 +02:00
void ij_to_xy ( int i , int j , double xy [ 2 ] )
2021-05-29 16:50:49 +02:00
/* 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 ) ;
}
2021-08-15 11:49:37 +02:00
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 ( ) ;
}
2023-09-02 11:36:15 +02:00
void erase_area_ij ( int imin , int jmin , int imax , int jmax )
{
glColor3f ( 0.0 , 0.0 , 0.0 ) ;
glBegin ( GL_QUADS ) ;
glVertex2i ( imin , jmin ) ;
glVertex2i ( imax , jmin ) ;
glVertex2i ( imax , jmax ) ;
glVertex2i ( imin , jmax ) ;
glEnd ( ) ;
}
2021-09-01 17:03:02 +02:00
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 ) ;
}
2022-02-05 18:44:39 +01:00
void draw_line ( double x1 , double y1 , double x2 , double y2 )
{
double pos [ 2 ] ;
glBegin ( GL_LINE_STRIP ) ;
xy_to_pos ( x1 , y1 , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
xy_to_pos ( x2 , y2 , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
glEnd ( ) ;
}
2021-08-15 11:49:37 +02:00
void draw_rectangle ( double x1 , double y1 , double x2 , double y2 )
2021-06-20 23:31:23 +02:00
{
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 ( ) ;
}
2021-05-29 16:50:49 +02:00
2022-10-18 23:28:20 +02:00
void draw_filled_rectangle ( double x1 , double y1 , double x2 , double y2 )
{
double pos [ 2 ] ;
glBegin ( GL_TRIANGLE_FAN ) ;
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 ( ) ;
}
2021-08-15 11:49:37 +02:00
void draw_rotated_rectangle ( double x1 , double y1 , double x2 , double y2 )
2021-07-18 15:06:59 +02:00
{
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 ( ) ;
}
2021-08-15 11:49:37 +02:00
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 ( ) ;
}
2022-10-18 23:28:20 +02:00
void draw_circle_arc ( double x , double y , double r , double angle1 , double dangle , int nseg )
{
int i ;
double pos [ 2 ] , alpha , dalpha ;
dalpha = dangle / ( double ) nseg ;
glBegin ( GL_LINE_STRIP ) ;
for ( i = 0 ; i < = nseg ; i + + )
{
alpha = angle1 + ( double ) i * dalpha ;
xy_to_pos ( x + r * cos ( alpha ) , y + r * sin ( alpha ) , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
}
glEnd ( ) ;
}
2021-08-15 11:49:37 +02:00
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 ( ) ;
}
2021-11-12 16:22:24 +01:00
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 ( ) ;
}
2021-08-15 11:49:37 +02:00
2022-08-20 16:02:07 +02:00
int init_circle_config_pattern ( t_circle circles [ NMAXCIRCLES ] , int circle_pattern )
2021-07-18 15:06:59 +02:00
/* initialise the arrays circlex, circley, circlerad and circleactive */
/* for billiard shape D_CIRCLES */
{
2021-09-01 17:03:02 +02:00
int i , j , k , n , ncirc0 , n_p_active , ncandidates = 5000 , naccepted ;
2021-12-28 15:42:56 +01:00
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 ] , dr , dphi ;
2021-09-01 17:03:02 +02:00
short int active_poisson [ NMAXCIRCLES ] , far ;
2021-07-18 15:06:59 +02:00
2022-08-20 16:02:07 +02:00
switch ( circle_pattern ) {
2021-07-18 15:06:59 +02:00
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 ;
2021-11-12 16:22:24 +01:00
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 ;
2021-07-18 15:06:59 +02:00
}
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 ;
2021-11-12 16:22:24 +01:00
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 ;
2021-08-15 11:49:37 +02:00
/* activate only circles that intersect the domain */
2021-11-12 16:22:24 +01:00
if ( ( circles [ n ] . yc < YMAX + MU ) & & ( circles [ n ] . yc > YMIN - MU ) ) circles [ n ] . active = 1 ;
else circles [ n ] . active = 0 ;
2021-07-18 15:06:59 +02:00
}
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 ;
2022-08-20 16:02:07 +02:00
circles [ n ] . xc = ( ( double ) ( i - NGRIDX / 2 ) + 0.5 + 0.5 * ( ( double ) rand ( ) / RAND_MAX - 0.5 ) ) * dy ;
circles [ n ] . yc = YMIN + 0.5 + ( ( double ) j + 0.5 + 0.5 * ( ( double ) rand ( ) / RAND_MAX - 0.5 ) ) * dy ;
2021-11-12 16:22:24 +01:00
circles [ n ] . radius = MU * sqrt ( 1.0 + 0.8 * ( ( double ) rand ( ) / RAND_MAX - 0.5 ) ) ;
circles [ n ] . active = 1 ;
2021-07-18 15:06:59 +02:00
}
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 ;
2021-11-12 16:22:24 +01:00
circles [ n ] . xc = ( ( double ) ( i - NGRIDX / 2 ) + 0.5 ) * dy ;
circles [ n ] . yc = YMIN + ( ( double ) j + 0.5 ) * dy ;
circles [ n ] . radius = MU ;
2021-07-18 15:06:59 +02:00
p = ( double ) rand ( ) / RAND_MAX ;
2021-11-12 16:22:24 +01:00
if ( p < P_PERCOL ) circles [ n ] . active = 1 ;
else circles [ n ] . active = 0 ;
2021-07-18 15:06:59 +02:00
}
break ;
}
case ( C_RAND_POISSON ) :
{
ncircles = NPOISSON ;
for ( n = 0 ; n < NPOISSON ; n + + )
{
2021-11-12 16:22:24 +01:00
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 ;
2021-07-18 15:06:59 +02:00
}
break ;
}
2021-07-30 10:25:50 +02:00
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 ) ;
2021-11-12 16:22:24 +01:00
circles [ n ] . xc = r * cos ( phi ) ;
circles [ n ] . yc = r * sin ( phi ) ;
circles [ n ] . radius = MU ;
circles [ n ] . active = 1 ;
2021-07-30 10:25:50 +02:00
}
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 ] ;
2021-11-12 16:22:24 +01:00
circles [ n ] . xc = r * cos ( phi ) ;
circles [ n ] . yc = r * sin ( phi ) ;
circles [ n ] . radius = LAMBDA * ra [ j ] ;
circles [ n ] . active = 1 ;
2021-07-30 10:25:50 +02:00
}
break ;
}
2021-10-24 15:20:56 +02:00
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 + + )
{
2021-11-12 16:22:24 +01:00
circles [ 4 * i + j ] . xc = xx [ i ] ;
circles [ 4 * i + j ] . yc = yy [ j ] ;
2021-10-24 15:20:56 +02:00
}
2021-11-12 16:22:24 +01:00
circles [ ncircles - 1 ] . xc = X_TARGET ;
circles [ ncircles - 1 ] . yc = Y_TARGET ;
2021-10-24 15:20:56 +02:00
for ( i = 0 ; i < ncircles - 1 ; i + + )
{
2021-11-12 16:22:24 +01:00
circles [ i ] . radius = MU ;
circles [ i ] . active = 1 ;
2021-10-24 15:20:56 +02:00
}
2021-11-12 16:22:24 +01:00
circles [ ncircles - 1 ] . radius = 0.5 * MU ;
circles [ ncircles - 1 ] . active = 2 ;
2021-10-24 15:20:56 +02:00
break ;
}
2021-09-01 17:03:02 +02:00
case ( C_POISSON_DISC ) :
{
printf ( " Generating Poisson disc sample \n " ) ;
/* generate first circle */
2021-11-12 16:22:24 +01:00
circles [ 0 ] . xc = LAMBDA * ( 2.0 * ( double ) rand ( ) / RAND_MAX - 1.0 ) ;
circles [ 0 ] . yc = ( YMAX - YMIN ) * ( double ) rand ( ) / RAND_MAX + YMIN ;
2021-09-01 17:03:02 +02:00
active_poisson [ 0 ] = 1 ;
2021-11-12 16:22:24 +01:00
// circles[0].active = 1;
2021-09-01 17:03:02 +02:00
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 ) ;
2021-11-12 16:22:24 +01:00
// printf("Starting from circle %i at (%.3f,%.3f)\n", i, circles[i].xc, circles[i].yc);
2021-09-01 17:03:02 +02:00
/* 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 ;
2021-11-12 16:22:24 +01:00
x = circles [ i ] . xc + r * cos ( phi ) ;
y = circles [ i ] . yc + r * sin ( phi ) ;
2021-09-01 17:03:02 +02:00
// 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 */
2021-11-12 16:22:24 +01:00
far = far * ( ( x - circles [ k ] . xc ) * ( x - circles [ k ] . xc ) + ( y - circles [ k ] . yc ) * ( y - circles [ k ] . yc ) > = dpoisson * dpoisson ) ;
2021-09-01 17:03:02 +02:00
/* 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 ) ;
2021-11-12 16:22:24 +01:00
circles [ ncircles ] . xc = x ;
circles [ ncircles ] . yc = y ;
circles [ ncircles ] . radius = MU ;
circles [ ncircles ] . active = 1 ;
2021-09-01 17:03:02 +02:00
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 ;
}
2021-08-15 11:49:37 +02:00
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 + + )
{
2021-11-12 16:22:24 +01:00
circles [ n ] . xc = - LAMBDA + n * dx ;
circles [ n ] . yc = y ;
2021-08-15 11:49:37 +02:00
y + = height * gamma ;
if ( y > YMAX ) y - = height ;
2021-11-12 16:22:24 +01:00
circles [ n ] . radius = MU ;
circles [ n ] . active = 1 ;
2021-08-15 11:49:37 +02:00
}
/* test for circles that overlap top or bottom boundary */
ncirc0 = ncircles ;
for ( n = 0 ; n < ncirc0 ; n + + )
{
2021-11-12 16:22:24 +01:00
if ( circles [ n ] . yc + circles [ n ] . radius > YMAX )
2021-08-15 11:49:37 +02:00
{
2021-11-12 16:22:24 +01:00
circles [ ncircles ] . xc = circles [ n ] . xc ;
circles [ ncircles ] . yc = circles [ n ] . yc - height ;
circles [ ncircles ] . radius = MU ;
circles [ ncircles ] . active = 1 ;
2021-08-15 11:49:37 +02:00
ncircles + + ;
}
2021-11-12 16:22:24 +01:00
else if ( circles [ n ] . yc - circles [ n ] . radius < YMIN )
2021-08-15 11:49:37 +02:00
{
2021-11-12 16:22:24 +01:00
circles [ ncircles ] . xc = circles [ n ] . xc ;
circles [ ncircles ] . yc = circles [ n ] . yc + height ;
circles [ ncircles ] . radius = MU ;
circles [ ncircles ] . active = 1 ;
2021-08-15 11:49:37 +02:00
ncircles + + ;
}
}
break ;
}
case ( C_GOLDEN_SPIRAL ) :
{
ncircles = 1 ;
2021-11-12 16:22:24 +01:00
circles [ 0 ] . xc = 0.0 ;
circles [ 0 ] . yc = 0.0 ;
2021-08-15 11:49:37 +02:00
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 ) )
{
2021-11-12 16:22:24 +01:00
circles [ ncircles ] . xc = x ;
circles [ ncircles ] . yc = y ;
2021-08-15 11:49:37 +02:00
ncircles + + ;
}
}
for ( i = 0 ; i < ncircles ; i + + )
{
2021-11-12 16:22:24 +01:00
circles [ i ] . radius = MU ;
2021-08-15 11:49:37 +02:00
/* inactivate circles outside the domain */
2021-11-12 16:22:24 +01:00
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);
2021-08-15 11:49:37 +02:00
}
2021-09-01 17:03:02 +02:00
break ;
2021-08-15 11:49:37 +02:00
}
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 ;
2021-11-12 16:22:24 +01:00
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 ;
2021-08-15 11:49:37 +02:00
/* activate only circles that intersect the domain */
2021-11-12 16:22:24 +01:00
if ( ( circles [ n ] . yc < YMAX + MU ) & & ( circles [ n ] . yc > YMIN - MU ) ) circles [ n ] . active = 1 ;
else circles [ n ] . active = 0 ;
2021-08-15 11:49:37 +02:00
}
break ;
}
2021-12-28 15:42:56 +01:00
case ( C_RINGS ) :
{
ncircles = NGRIDX * NGRIDY ;
dphi = DPI / ( ( double ) NGRIDX ) ;
dr = 0.5 * LAMBDA / ( double ) NGRIDY ;
for ( i = 0 ; i < NGRIDX ; i + + )
for ( j = 0 ; j < NGRIDY ; j + + )
{
n = NGRIDY * i + j ;
phi = ( double ) i * dphi ;
r = 0.5 * LAMBDA + ( double ) j * dr ;
circles [ n ] . xc = r * cos ( phi ) ;
circles [ n ] . yc = r * sin ( phi ) ;
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 ;
}
2022-02-05 18:44:39 +01:00
case ( C_RINGS_T ) :
{
ncircles = NGRIDX * NGRIDY ;
dphi = DPI / ( ( double ) NGRIDX ) ;
dr = 0.5 * LAMBDA / ( double ) NGRIDY ;
for ( i = 0 ; i < NGRIDX ; i + + )
for ( j = 0 ; j < NGRIDY ; j + + )
{
n = NGRIDY * i + j ;
phi = ( double ) i * dphi ;
phi + = 0.5 * ( double ) j * dphi ;
r = 0.5 * LAMBDA + ( double ) j * dr ;
circles [ n ] . xc = r * cos ( phi ) ;
circles [ n ] . yc = r * sin ( phi ) ;
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_RINGS_SPIRAL ) :
{
ncircles = 0 ;
// circles[0].xc = 0.5*LAMBDA;
// circles[0].yc = 0.0;
gamma = ( sqrt ( 5.0 ) - 1.0 ) * PI ; /* golden mean times 2Pi */
phi = 0.0 ;
r0 = 0.5 * LAMBDA ;
r = r0 + MU ;
for ( i = 0 ; i < 1000 ; i + + )
{
x = r * cos ( phi ) ;
y = r * sin ( phi ) ;
phi + = gamma ;
r + = 0.1 * MU * r0 / r ;
if ( x * x + y * y < LAMBDA )
{
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 ;
}
break ;
}
2023-09-02 11:36:15 +02:00
case ( C_HEX_BOTTOM ) :
{
ncircles = NGRIDX * ( NGRIDY + 1 ) ;
dy = ( - YMIN ) / ( ( double ) NGRIDY ) ;
// dx = dy*0.5*sqrt(3.0);
dx = ( XMAX - XMIN ) / ( ( double ) NGRIDX ) ;
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 ) * dx ; /* 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_HEX_BOTTOM2 ) :
{
ncircles = NGRIDX * ( NGRIDY + 1 ) ;
dy = ( - YMIN ) / ( ( double ) NGRIDY ) ;
dx = 2.0 * LAMBDA / ( ( double ) NGRIDX ) ;
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 ) * dx ; /* 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_SQUARE_BOTTOM ) :
{
ncircles = NGRIDX * ( NGRIDY + 1 ) ;
dy = ( - YMIN ) / ( ( double ) NGRIDY ) ;
dx = 2.0 * LAMBDA / ( ( double ) NGRIDX ) ;
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 ) * dx ;
circles [ n ] . yc = YMIN + ( ( double ) j - 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 ;
}
2021-08-15 11:49:37 +02:00
case ( C_ONE ) :
{
2021-11-12 16:22:24 +01:00
circles [ ncircles ] . xc = 0.0 ;
circles [ ncircles ] . yc = 0.0 ;
circles [ ncircles ] . radius = MU ;
circles [ ncircles ] . active = 1 ;
2021-08-15 11:49:37 +02:00
ncircles + = 1 ;
break ;
}
case ( C_TWO ) : /* used for comparison with cloak */
{
2021-11-12 16:22:24 +01:00
circles [ ncircles ] . xc = 0.0 ;
circles [ ncircles ] . yc = 0.0 ;
circles [ ncircles ] . radius = MU ;
circles [ ncircles ] . active = 2 ;
2021-08-15 11:49:37 +02:00
ncircles + = 1 ;
2021-11-12 16:22:24 +01:00
circles [ ncircles ] . xc = 0.0 ;
circles [ ncircles ] . yc = 0.0 ;
circles [ ncircles ] . radius = 2.0 * MU ;
circles [ ncircles ] . active = 1 ;
2021-08-15 11:49:37 +02:00
ncircles + = 1 ;
break ;
}
case ( C_NOTHING ) :
{
ncircles + = 0 ;
break ;
}
2021-07-18 15:06:59 +02:00
default :
{
printf ( " Function init_circle_config not defined for this pattern \n " ) ;
}
}
2022-08-20 16:02:07 +02:00
return ( ncircles ) ;
2021-07-18 15:06:59 +02:00
}
2022-08-20 16:02:07 +02:00
int init_circle_config ( t_circle circles [ NMAXCIRCLES ] )
/* for backward compatibility */
{
return ( init_circle_config_pattern ( circles , CIRCLE_PATTERN ) ) ;
}
int init_polygon_config_pattern ( t_polygon polygons [ NMAXCIRCLES ] , int circle_pattern )
2021-11-12 16:22:24 +01:00
/* initialise the polygon configuration, for billiard shape D_CIRCLES */
/* uses init_circle_config, this is where C++ would be more elegant */
{
2022-08-20 16:02:07 +02:00
int i , ncircles ;
2021-11-12 16:22:24 +01:00
t_circle circle [ NMAXCIRCLES ] ;
2022-08-20 16:02:07 +02:00
ncircles = init_circle_config_pattern ( circle , circle_pattern ) ;
2021-11-12 16:22:24 +01:00
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 ) ; */
}
2021-12-28 15:42:56 +01:00
/* adjust angles for C_RINGS configuration */
2022-08-20 16:02:07 +02:00
if ( ( circle_pattern = = C_RINGS ) | | ( circle_pattern = = C_RINGS_T ) | | ( circle_pattern = = C_RINGS_SPIRAL ) )
2021-12-28 15:42:56 +01:00
for ( i = 0 ; i < ncircles ; i + + ) if ( polygons [ i ] . active )
polygons [ i ] . angle + = argument ( polygons [ i ] . xc , polygons [ i ] . yc ) / PID ;
2022-08-20 16:02:07 +02:00
return ( ncircles ) ;
2021-11-12 16:22:24 +01:00
}
2022-08-20 16:02:07 +02:00
int init_polygon_config ( t_polygon polygons [ NMAXCIRCLES ] )
/* for backward compatibility */
{
return ( init_polygon_config_pattern ( polygons , CIRCLE_PATTERN ) ) ;
}
2021-10-24 15:20:56 +02:00
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 ) ;
}
2021-11-12 16:22:24 +01:00
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 ) ;
}
2021-10-24 15:20:56 +02:00
2021-11-12 16:22:24 +01:00
void compute_isospectral_coordinates ( int type , int ishift , double xshift , double yshift , double scaling ,
t_vertex polyline [ NMAXPOLY ] )
2021-10-24 15:20:56 +02:00
/* 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*/
{
2021-11-12 16:22:24 +01:00
int i ;
double pos [ 2 ] ;
2021-10-24 15:20:56 +02:00
2021-11-12 16:22:24 +01:00
polyline [ ishift ] . x = ( xshift - 0.5 ) * scaling ;
polyline [ ishift ] . y = ( yshift - 0.25 ) * scaling ;
2021-10-24 15:20:56 +02:00
2021-11-12 16:22:24 +01:00
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 ] ) ;
}
2021-10-24 15:20:56 +02:00
2021-11-12 16:22:24 +01:00
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 ] ;
}
}
2021-10-24 15:20:56 +02:00
2021-12-28 15:42:56 +01:00
int compute_tokaprime_coordinates ( double xshift , t_vertex polyline [ NMAXPOLY ] )
/* compute positions of vertices of Tokarsky room made of 86 triangles */
{
double ta , tb , a , b , pos [ 2 ] ;
int i ;
polyline [ 0 ] . x = 0.0 ;
polyline [ 0 ] . y = 1.0 ;
polyline [ 1 ] . x = 0.0 ;
polyline [ 1 ] . y = 1.0 - LAMBDA ;
ta = tan ( 0.05 * PI ) ;
tb = tan ( 0.4 * PI ) ;
a = LAMBDA * tb / ( ta + tb ) ;
b = a * ta ;
polyline [ 2 ] . x = b ;
polyline [ 2 ] . y = 1.0 - a ;
axial_symmetry_tvertex ( polyline [ 0 ] , polyline [ 2 ] , polyline [ 1 ] , & polyline [ 3 ] ) ;
axial_symmetry_tvertex ( polyline [ 0 ] , polyline [ 3 ] , polyline [ 2 ] , & polyline [ 4 ] ) ;
axial_symmetry_tvertex ( polyline [ 3 ] , polyline [ 4 ] , polyline [ 0 ] , & polyline [ 43 ] ) ;
for ( i = 4 ; i < 42 ; i + + )
axial_symmetry_tvertex ( polyline [ i ] , polyline [ 43 ] , polyline [ i - 1 ] , & polyline [ i + 1 ] ) ;
for ( i = 2 ; i < 44 ; i + + )
{
polyline [ i + 42 ] . x = - polyline [ i ] . x ;
polyline [ i + 42 ] . y = polyline [ i ] . y ;
}
for ( i = 0 ; i < 86 ; i + + )
{
polyline [ i ] . x + = xshift ;
xy_to_pos ( polyline [ i ] . x , polyline [ i ] . y , pos ) ;
polyline [ i ] . posi = pos [ 0 ] ;
polyline [ i ] . posj = pos [ 1 ] ;
}
return ( 86 ) ;
}
2021-11-12 16:22:24 +01:00
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 ] ) ;
2021-10-24 15:20:56 +02:00
if ( type = = 0 )
{
2021-11-12 16:22:24 +01:00
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 ] ) ;
2021-10-24 15:20:56 +02:00
}
else
{
2021-11-12 16:22:24 +01:00
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 */
2021-12-28 15:42:56 +01:00
angle = APOLY * PID + 2.0 * PI / 3.0 ;
x = LAMBDA * cos ( APOLY * PID - PI / 6.0 ) ;
y = LAMBDA * sin ( APOLY * PID - PI / 6.0 ) ;
length = 2.0 * LAMBDA * sin ( PI / 3.0 ) ;
2021-11-12 16:22:24 +01:00
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 ) ;
}
2021-12-28 15:42:56 +01:00
int compute_star_coordinates ( t_vertex polyline [ NMAXPOLY ] )
/* compute positions of vertices of star-shaped domain */
{
int i ;
double alpha , r , x , y , pos [ 2 ] ;
alpha = DPI / ( double ) NPOLY ;
for ( i = 0 ; i < NPOLY ; i + + )
{
if ( i % 2 = = 0 ) r = LAMBDA - MU ;
else r = LAMBDA ;
x = r * cos ( APOLY * PID + alpha * ( double ) i ) ;
y = r * sin ( APOLY * PID + alpha * ( double ) i ) ;
polyline [ i ] . x = x ;
polyline [ i ] . y = y ;
xy_to_pos ( x , y , pos ) ;
polyline [ i ] . posi = pos [ 0 ] ;
polyline [ i ] . posj = pos [ 1 ] ;
}
/* add origin to compute xy_in_billiard */
polyline [ NPOLY ] . x = 0.0 ;
polyline [ NPOLY ] . y = 0.0 ;
return ( NPOLY ) ;
}
2022-02-05 18:44:39 +01:00
int compute_fresnel_coordinates ( t_vertex polyline [ NMAXPOLY ] )
/* compute positions of vertices approximating Fresnel lens */
{
int i ;
double ymax , dy , x , y , x1 , pos [ 2 ] ;
ymax = 0.9 * LAMBDA ;
dy = 2.0 * ymax / ( double ) NSEG ;
2022-03-13 15:29:50 +01:00
if ( LAMBDA > 0.0 ) x = - MU ;
else x = MU ;
polyline [ 0 ] . x = x ;
2022-02-05 18:44:39 +01:00
polyline [ 0 ] . y = - ymax ;
2022-03-13 15:29:50 +01:00
xy_to_pos ( x , - ymax , pos ) ;
2022-02-05 18:44:39 +01:00
polyline [ 0 ] . posi = pos [ 0 ] ;
polyline [ 0 ] . posj = pos [ 1 ] ;
for ( i = 1 ; i < NSEG ; i + + )
{
y = - ymax + dy * ( double ) i ;
x = sqrt ( LAMBDA * LAMBDA - y * y ) - vabs ( LAMBDA ) ;
// x = sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA*LAMBDA;
while ( x < = 0.0 ) x + = MU ;
2022-03-13 15:29:50 +01:00
if ( LAMBDA < 0.0 ) x = - x ;
2022-02-05 18:44:39 +01:00
polyline [ i ] . x = x ;
polyline [ i ] . y = y ;
xy_to_pos ( x , y , pos ) ;
polyline [ i ] . posi = pos [ 0 ] ;
polyline [ i ] . posj = pos [ 1 ] ;
}
2022-03-13 15:29:50 +01:00
if ( LAMBDA > 0.0 ) x = - MU ;
else x = MU ;
polyline [ NSEG ] . x = x ;
2022-02-05 18:44:39 +01:00
polyline [ NSEG ] . y = ymax ;
2022-03-13 15:29:50 +01:00
xy_to_pos ( x , ymax , pos ) ;
2022-02-05 18:44:39 +01:00
polyline [ NSEG ] . posi = pos [ 0 ] ;
polyline [ NSEG ] . posj = pos [ 1 ] ;
return ( NSEG + 1 ) ;
}
int compute_double_fresnel_coordinates ( t_vertex polyline [ NMAXPOLY ] , double xshift )
/* compute positions of vertices approximating two facing Fresnel lenses */
{
int i ;
double pos [ 2 ] ;
compute_fresnel_coordinates ( polyline ) ;
for ( i = 0 ; i < = NSEG ; i + + )
{
polyline [ i ] . x - = xshift ;
xy_to_pos ( polyline [ i ] . x , polyline [ i ] . y , pos ) ;
polyline [ i ] . posi = pos [ 0 ] ;
polyline [ i ] . posj = pos [ 1 ] ;
polyline [ NSEG + 1 + i ] . x = - polyline [ i ] . x ;
polyline [ NSEG + 1 + i ] . y = polyline [ i ] . y ;
xy_to_pos ( polyline [ NSEG + 1 + i ] . x , polyline [ NSEG + 1 + i ] . y , pos ) ;
polyline [ NSEG + 1 + i ] . posi = pos [ 0 ] ;
polyline [ NSEG + 1 + i ] . posj = pos [ 1 ] ;
}
return ( 2 * NSEG + 2 ) ;
}
int compute_noisepanel_coordinates ( t_vertex polyline [ NMAXPOLY ] )
2022-03-13 15:29:50 +01:00
/* compute positions of vertices of noise panel */
2022-02-05 18:44:39 +01:00
{
int i , n , even ;
double ymax , dy , x , y , x1 , pos [ 2 ] ;
/* find the leftmost point */
x = 0.0 ;
n = 0 ;
while ( x > XMIN )
{
x - = LAMBDA ;
n + + ;
}
if ( n % 2 = = 0 ) even = 1 ;
else even = 0 ;
i = 0 ;
while ( x < = XMAX + LAMBDA )
{
if ( even ) y = YMIN + 0.1 ;
else y = YMIN + 0.1 + MU ;
2022-05-14 20:58:08 +02:00
x1 = x ;
if ( x1 > XMAX ) x1 = XMAX ;
else if ( x1 < XMIN ) x1 = XMIN ;
polyline [ i ] . x = x1 ;
2022-02-05 18:44:39 +01:00
polyline [ i ] . y = y ;
2022-05-14 20:58:08 +02:00
xy_to_pos ( x1 , y , pos ) ;
2022-02-05 18:44:39 +01:00
polyline [ i ] . posi = pos [ 0 ] ;
polyline [ i ] . posj = pos [ 1 ] ;
x + = LAMBDA ;
even = 1 - even ;
i + + ;
}
n = i ;
for ( i = 0 ; i < n ; i + + )
{
polyline [ n + i ] . x = polyline [ n - i - 1 ] . x ;
polyline [ n + i ] . y = - polyline [ n - i - 1 ] . y ;
polyline [ n + i ] . posi = polyline [ n - i - 1 ] . posi ;
polyline [ n + i ] . posj = NY - polyline [ n - i - 1 ] . posj ;
}
return ( 2 * n ) ;
}
2021-12-28 15:42:56 +01:00
2022-06-25 15:49:37 +02:00
int compute_noisepanel_rect_coordinates ( t_vertex polyline [ NMAXPOLY ] )
/* compute positions of vertices of noise panel */
{
int i , n , even ;
double ymax , dy , x , y , x1 , pos [ 2 ] ;
/* find the leftmost point */
x = - NPWIDTH ;
n = 0 ;
while ( x > XMIN )
{
x - = LAMBDA ;
n + + ;
}
if ( n % 2 = = 0 ) even = 1 ;
else even = 0 ;
i = 0 ;
while ( x < = 0.0 )
{
if ( even ) y = YMIN + 0.1 ;
else y = YMIN + 0.1 + MU ;
x1 = x ;
if ( x1 > XMAX ) x1 = XMAX ;
else if ( x1 < XMIN ) x1 = XMIN ;
polyline [ i ] . x = x1 ;
polyline [ i ] . y = y ;
xy_to_pos ( x1 , y , pos ) ;
polyline [ i ] . posi = pos [ 0 ] ;
polyline [ i ] . posj = pos [ 1 ] ;
x + = LAMBDA ;
even = 1 - even ;
i + + ;
}
n = i ;
for ( i = 0 ; i < n ; i + + )
{
polyline [ n + i ] . x = polyline [ n - i - 1 ] . x ;
polyline [ n + i ] . y = - polyline [ n - i - 1 ] . y ;
polyline [ n + i ] . posi = polyline [ n - i - 1 ] . posi ;
polyline [ n + i ] . posj = NY - polyline [ n - i - 1 ] . posj ;
}
return ( 2 * n ) ;
}
2022-03-13 15:29:50 +01:00
int compute_qrd_coordinates ( t_vertex polyline [ NMAXPOLY ] )
/* compute positions of quadratic noise diffuser */
{
int n = 0 , b , k , k1 , kmin , kmax ;
double x , y , x1 , y1 = YMIN , pos [ 2 ] ;
kmin = ( int ) ( XMIN / LAMBDA ) - 2 ;
kmax = ( int ) ( XMAX / LAMBDA ) + 2 ;
for ( b = - 1 ; b < = 1 ; b + = 2 )
{
if ( b = = 1 ) y1 = YMAX ;
for ( k = kmin ; k < kmax ; k + + )
{
x = LAMBDA * ( ( double ) ( k ) - 0.5 ) ;
k1 = ( k * k ) % 13 ;
if ( b = = - 1 ) y = YMIN + ( MU / 13.0 ) * ( 14.0 - ( double ) k1 ) ;
else y = YMAX - ( MU / 13.0 ) * ( 14.0 - ( double ) k1 ) ;
polyline [ n ] . x = x ;
polyline [ n ] . y = y1 ;
xy_to_pos ( x , y1 , pos ) ;
polyline [ n ] . posi = pos [ 0 ] ;
polyline [ n ] . posj = pos [ 1 ] ;
n + + ;
polyline [ n ] . x = x ;
polyline [ n ] . y = y ;
xy_to_pos ( x , y , pos ) ;
polyline [ n ] . posi = pos [ 0 ] ;
polyline [ n ] . posj = pos [ 1 ] ;
n + + ;
y1 = y ;
}
}
return ( n ) ;
}
2023-01-22 16:49:04 +01:00
int compute_maze_coordinates ( t_rectangle polyrect [ NMAXPOLY ] , int type )
/* compute positions of maze */
2022-10-18 23:28:20 +02:00
{
t_maze * maze ;
int i , j , n , nsides = 0 , ropening ;
2023-03-25 19:56:19 +01:00
double dx , dy , x1 , y1 , x0 , padding = 0.02 , pos [ 2 ] , width = MAZE_WIDTH ;
2022-10-18 23:28:20 +02:00
maze = ( t_maze * ) malloc ( NXMAZE * NYMAZE * sizeof ( t_maze ) ) ;
2023-01-22 16:49:04 +01:00
ropening = ( NYMAZE + 1 ) / 2 ;
2022-10-18 23:28:20 +02:00
init_maze ( maze ) ;
2023-01-22 16:49:04 +01:00
/* move the entrance for maze type with two channels */
if ( type = = 2 )
{
n = nmaze ( 0 , ropening - 1 ) ;
maze [ n ] . west = 0 ;
n = nmaze ( 0 , ropening ) ;
maze [ n ] . west = 1 ;
}
2022-10-18 23:28:20 +02:00
/* build walls of maze */
2022-11-20 23:17:39 +01:00
// x0 = LAMBDA - 1.0;
2022-10-18 23:28:20 +02:00
dx = ( YMAX - YMIN - 2.0 * padding ) / ( double ) ( NXMAZE ) ;
dy = ( YMAX - YMIN - 2.0 * padding ) / ( double ) ( NYMAZE ) ;
for ( i = 0 ; i < NXMAZE ; i + + )
for ( j = 0 ; j < NYMAZE ; j + + )
{
n = nmaze ( i , j ) ;
x1 = YMIN + padding + ( double ) i * dx + MAZE_XSHIFT ;
y1 = YMIN + padding + ( double ) j * dy ;
if ( ( ( i > 0 ) | | ( j ! = ropening ) ) & & ( maze [ n ] . west ) )
{
polyrect [ nsides ] . x1 = x1 - width ;
polyrect [ nsides ] . y1 = y1 - width ;
polyrect [ nsides ] . x2 = x1 + width ;
polyrect [ nsides ] . y2 = y1 + width + dy ;
2023-01-22 16:49:04 +01:00
nsides + + ;
2022-10-18 23:28:20 +02:00
}
2023-01-22 16:49:04 +01:00
2022-10-18 23:28:20 +02:00
if ( maze [ n ] . south )
{
polyrect [ nsides ] . x1 = x1 - width ;
polyrect [ nsides ] . y1 = y1 - width ;
polyrect [ nsides ] . x2 = x1 + width + dx ;
polyrect [ nsides ] . y2 = y1 + width ;
2023-01-22 16:49:04 +01:00
nsides + + ;
2022-10-18 23:28:20 +02:00
}
}
/* top side of maze */
polyrect [ nsides ] . x1 = YMIN + padding + MAZE_XSHIFT ;
polyrect [ nsides ] . y1 = YMAX - padding - width ;
polyrect [ nsides ] . x2 = YMAX - padding + MAZE_XSHIFT ;
polyrect [ nsides ] . y2 = YMAX - padding + width ;
nsides + + ;
/* right side of maze */
y1 = YMIN + padding + dy * ( ( double ) ropening ) ;
x1 = YMAX - padding + MAZE_XSHIFT ;
polyrect [ nsides ] . x1 = x1 - width ;
polyrect [ nsides ] . y1 = YMIN - 1.0 ;
polyrect [ nsides ] . x2 = x1 + width ;
polyrect [ nsides ] . y2 = y1 - dy ;
nsides + + ;
polyrect [ nsides ] . x1 = x1 - width ;
polyrect [ nsides ] . y1 = y1 ;
polyrect [ nsides ] . x2 = x1 + width ;
polyrect [ nsides ] . y2 = YMAX + 1.0 ;
nsides + + ;
/* left side of maze */
x1 = YMIN + padding + MAZE_XSHIFT ;
polyrect [ nsides ] . x1 = x1 - width ;
polyrect [ nsides ] . y1 = YMIN - 1.0 ;
polyrect [ nsides ] . x2 = x1 + width ;
polyrect [ nsides ] . y2 = YMIN + padding ;
nsides + + ;
polyrect [ nsides ] . x1 = x1 - width ;
polyrect [ nsides ] . y1 = YMAX - padding ;
polyrect [ nsides ] . x2 = x1 + width ;
polyrect [ nsides ] . y2 = YMAX + 1.0 ;
nsides + + ;
2023-01-22 16:49:04 +01:00
if ( type = = 1 ) /* maze with closed sides */
2022-10-18 23:28:20 +02:00
{
polyrect [ nsides ] . x1 = XMIN - 0.5 * width ;
polyrect [ nsides ] . y1 = YMIN - 0.5 * width ;
polyrect [ nsides ] . x2 = XMIN + 0.5 * width ;
polyrect [ nsides ] . y2 = YMAX + 0.5 * width ;
nsides + + ;
polyrect [ nsides ] . x1 = XMIN - 0.5 * width ;
polyrect [ nsides ] . y1 = YMIN - 0.5 * width ;
polyrect [ nsides ] . x2 = x1 + 0.5 * width ;
polyrect [ nsides ] . y2 = YMIN + 0.5 * width ;
nsides + + ;
polyrect [ nsides ] . x1 = XMIN - 0.5 * width ;
polyrect [ nsides ] . y1 = YMAX - 0.5 * width ;
polyrect [ nsides ] . x2 = x1 + 0.5 * width ;
polyrect [ nsides ] . y2 = YMAX + 0.5 * width ;
nsides + + ;
}
2023-01-22 16:49:04 +01:00
else if ( type = = 2 ) /* maze with channels */
{
/* right channel */
y1 = YMIN + padding + dy * ( ( double ) ropening ) ;
x1 = YMAX - padding + MAZE_XSHIFT ;
polyrect [ nsides ] . x1 = x1 - 0.5 * width ;
polyrect [ nsides ] . y1 = YMIN - padding ;
polyrect [ nsides ] . x2 = XMAX + padding ;
polyrect [ nsides ] . y2 = y1 - dy + width ;
nsides + + ;
polyrect [ nsides ] . x1 = x1 - 0.5 * width ;
polyrect [ nsides ] . y1 = y1 - width ;
polyrect [ nsides ] . x2 = XMAX + padding ;
polyrect [ nsides ] . y2 = YMAX + padding ;
nsides + + ;
2023-03-25 19:56:19 +01:00
2023-01-22 16:49:04 +01:00
/* left channel */
x1 = YMIN + padding + MAZE_XSHIFT ;
polyrect [ nsides ] . x1 = XMIN - padding ;
polyrect [ nsides ] . y1 = YMIN - padding ;
polyrect [ nsides ] . x2 = x1 + 0.5 * width ;
polyrect [ nsides ] . y2 = y1 - dy + width ;
nsides + + ;
polyrect [ nsides ] . x1 = XMIN - padding ;
polyrect [ nsides ] . y1 = y1 - width ;
polyrect [ nsides ] . x2 = x1 + 0.5 * width ;
polyrect [ nsides ] . y2 = YMAX + padding ;
nsides + + ;
}
2022-10-18 23:28:20 +02:00
for ( i = 0 ; i < nsides ; i + + )
{
xy_to_pos ( polyrect [ i ] . x1 , polyrect [ i ] . y1 , pos ) ;
polyrect [ i ] . posi1 = pos [ 0 ] ;
polyrect [ i ] . posj1 = pos [ 1 ] ;
xy_to_pos ( polyrect [ i ] . x2 , polyrect [ i ] . y2 , pos ) ;
polyrect [ i ] . posi2 = pos [ 0 ] ;
polyrect [ i ] . posj2 = pos [ 1 ] ;
}
free ( maze ) ;
return ( nsides ) ;
}
2023-01-22 16:49:04 +01:00
int compute_circular_maze_coordinates ( t_rect_rotated polyrectrot [ NMAXPOLY ] , t_arc polyarc [ NMAXPOLY ] , int * npolyrect_rot , int * npolyarc )
/* compute positions of circular maze */
{
int nblocks , block , i , j , n , p , q , np , na ;
double rmin , rmax , angle , r , dr , phi , dphi , ww , width = 0.02 ;
t_maze * maze ;
maze = ( t_maze * ) malloc ( NXMAZE * NYMAZE * sizeof ( t_maze ) ) ;
init_circular_maze ( maze ) ;
np = 0 ;
na = 0 ;
/* build walls of maze */
nblocks = NYMAZE / NXMAZE ;
rmin = 0.15 ;
rmax = 1.0 ;
angle = DPI / ( double ) nblocks ;
dr = ( rmax - rmin ) / ( double ) ( NXMAZE ) ;
/* add straight walls */
for ( block = 0 ; block < nblocks ; block + + )
{
dphi = angle ;
/* first circle */
n = nmaze ( 0 , block * NXMAZE ) ;
r = rmin - 0.5 * width ;
phi = ( double ) block * angle ;
if ( maze [ n ] . south )
{
polyrectrot [ np ] . x1 = r * cos ( phi ) + MAZE_XSHIFT ;
polyrectrot [ np ] . y1 = r * sin ( phi ) ;
polyrectrot [ np ] . x2 = ( r + dr + width ) * cos ( phi ) + MAZE_XSHIFT ;
polyrectrot [ np ] . y2 = ( r + dr + width ) * sin ( phi ) ;
polyrectrot [ np ] . width = width ;
np + + ;
}
/* second circle */
r = rmin + dr - 0.5 * width ;
dphi * = 0.5 ;
for ( q = 0 ; q < 2 ; q + + )
{
n = nmaze ( 1 , block * NXMAZE + q ) ;
phi = ( double ) ( block ) * angle + ( double ) q * dphi ;
if ( maze [ n ] . south )
{
polyrectrot [ np ] . x1 = r * cos ( phi ) + MAZE_XSHIFT ;
polyrectrot [ np ] . y1 = r * sin ( phi ) ;
polyrectrot [ np ] . x2 = ( r + dr + width ) * cos ( phi ) + MAZE_XSHIFT ;
polyrectrot [ np ] . y2 = ( r + dr + width ) * sin ( phi ) ;
polyrectrot [ np ] . width = width ;
np + + ;
}
}
/* other circles */
ww = 2 ;
i = 2 ;
while ( ww < NXMAZE )
{
dphi * = 0.5 ;
for ( p = 0 ; p < ww ; p + + )
{
r = rmin + ( double ) i * dr - 0.5 * width ;
// printf("Segment, i = %i, dphi = %.2lg, r = %.2lg\n", i, dphi, r);
for ( q = 0 ; q < 2 * ww ; q + + )
{
j = block * NXMAZE + q ;
n = nmaze ( i , j ) ;
phi = ( double ) ( block ) * angle + ( double ) q * dphi ;
if ( maze [ n ] . south )
{
polyrectrot [ np ] . x1 = r * cos ( phi ) + MAZE_XSHIFT ;
polyrectrot [ np ] . y1 = r * sin ( phi ) ;
polyrectrot [ np ] . x2 = ( r + dr + width ) * cos ( phi ) + MAZE_XSHIFT ;
polyrectrot [ np ] . y2 = ( r + dr + width ) * sin ( phi ) ;
polyrectrot [ np ] . width = width ;
np + + ;
}
}
i + + ;
}
ww * = 2 ;
}
}
/* add circular arcs */
for ( block = 0 ; block < nblocks ; block + + )
{
dphi = angle ;
/* first circle */
n = nmaze ( 0 , block * NXMAZE ) ;
r = rmin ;
phi = ( double ) block * angle ;
if ( ( block > 0 ) & & ( maze [ n ] . west ) )
{
polyarc [ na ] . xc = MAZE_XSHIFT ;
polyarc [ na ] . yc = 0.0 ;
polyarc [ na ] . r = r ;
polyarc [ na ] . angle1 = phi ;
polyarc [ na ] . dangle = dphi ;
polyarc [ na ] . width = width ;
na + + ;
}
/* second circle */
r = rmin + dr ;
dphi * = 0.5 ;
for ( q = 0 ; q < 2 ; q + + )
{
n = nmaze ( 1 , block * NXMAZE + q ) ;
phi = ( double ) ( block ) * angle + ( double ) q * dphi ;
if ( maze [ n ] . west )
{
polyarc [ na ] . xc = MAZE_XSHIFT ;
polyarc [ na ] . yc = 0.0 ;
polyarc [ na ] . r = r ;
polyarc [ na ] . angle1 = phi ;
polyarc [ na ] . dangle = dphi ;
polyarc [ na ] . width = width ;
na + + ;
}
}
/* other circles */
ww = 2 ;
i = 2 ;
while ( ww < NXMAZE )
{
dphi * = 0.5 ;
for ( p = 0 ; p < ww ; p + + )
{
r = rmin + ( double ) i * dr ;
printf ( " Circle, i = %i, dphi = %.2lg, r = %.2lg \n " , i , dphi , r ) ;
for ( q = 0 ; q < 2 * ww ; q + + )
{
j = block * NXMAZE + q ;
n = nmaze ( i , j ) ;
phi = ( double ) ( block ) * angle + ( double ) q * dphi ;
if ( maze [ n ] . west )
{
polyarc [ na ] . xc = MAZE_XSHIFT ;
polyarc [ na ] . yc = 0.0 ;
polyarc [ na ] . r = r ;
polyarc [ na ] . angle1 = phi ;
polyarc [ na ] . dangle = dphi ;
polyarc [ na ] . width = width ;
na + + ;
}
}
i + + ;
}
ww * = 2 ;
}
}
/* outer boundary of maze */
polyarc [ na ] . xc = MAZE_XSHIFT ;
polyarc [ na ] . yc = 0.0 ;
polyarc [ na ] . r = rmax ;
polyarc [ na ] . angle1 = dphi ;
polyarc [ na ] . dangle = DPI - dphi ;
polyarc [ na ] . width = width ;
na + + ;
* npolyrect_rot = np ;
* npolyarc = na ;
free ( maze ) ;
}
2023-07-08 23:28:23 +02:00
int compute_interior_maze_coordinates ( t_rectangle polyrect [ NMAXPOLY ] , int type )
/* compute positions of complement of maze */
{
t_maze * maze ;
int i , j , n , nsides = 0 , ropening ;
double dx , dy , x1 , y1 , x0 , padding = 0.02 , pos [ 2 ] , width = MAZE_WIDTH ;
/* TODO */
maze = ( t_maze * ) malloc ( NXMAZE * NYMAZE * sizeof ( t_maze ) ) ;
ropening = ( NYMAZE + 1 ) / 2 ;
init_maze ( maze ) ;
/* move the entrance for maze type with two channels */
if ( type = = 2 )
{
n = nmaze ( 0 , ropening - 1 ) ;
maze [ n ] . west = 0 ;
n = nmaze ( 0 , ropening ) ;
maze [ n ] . west = 1 ;
}
/* build walls of maze */
// x0 = LAMBDA - 1.0;
dx = ( YMAX - YMIN - 2.0 * padding ) / ( double ) ( NXMAZE ) ;
dy = ( YMAX - YMIN - 2.0 * padding ) / ( double ) ( NYMAZE ) ;
for ( i = 0 ; i < NXMAZE ; i + + )
for ( j = 0 ; j < NYMAZE ; j + + )
{
n = nmaze ( i , j ) ;
x1 = YMIN + padding + ( double ) i * dx + MAZE_XSHIFT ;
y1 = YMIN + padding + ( double ) j * dy ;
if ( ! maze [ n ] . west )
{
polyrect [ nsides ] . x1 = x1 - 0.5 * dx - width ;
polyrect [ nsides ] . y1 = y1 + 0.5 * dx - width ;
polyrect [ nsides ] . x2 = x1 + 0.5 * dx + width ;
polyrect [ nsides ] . y2 = y1 + 0.5 * dx + width ;
nsides + + ;
}
if ( ! maze [ n ] . south )
{
polyrect [ nsides ] . x1 = x1 + 0.5 * dx - width ;
polyrect [ nsides ] . y1 = y1 - 0.5 * dx - width ;
polyrect [ nsides ] . x2 = x1 + 0.5 * dx + width ;
polyrect [ nsides ] . y2 = y1 + 0.5 * dx + width ;
nsides + + ;
}
}
/* right channel of maze */
y1 = YMIN + padding + dy * ( ( double ) ropening ) ;
x1 = YMAX - padding + MAZE_XSHIFT ;
polyrect [ nsides ] . x1 = x1 - 0.5 * dx - width ;
polyrect [ nsides ] . y1 = y1 - 0.5 * dy - width ;
polyrect [ nsides ] . x2 = XMAX ;
polyrect [ nsides ] . y2 = y1 - 0.5 * dy + width ;
nsides + + ;
/* left channel of maze */
x1 = YMIN + padding + MAZE_XSHIFT ;
polyrect [ nsides ] . x1 = XMIN ;
polyrect [ nsides ] . y1 = y1 - 0.5 * dy - width ;
polyrect [ nsides ] . x2 = x1 + 0.5 * dx + width ;
polyrect [ nsides ] . y2 = y1 - 0.5 * dy + width ;
nsides + + ;
for ( i = 0 ; i < nsides ; i + + )
{
xy_to_pos ( polyrect [ i ] . x1 , polyrect [ i ] . y1 , pos ) ;
polyrect [ i ] . posi1 = pos [ 0 ] ;
polyrect [ i ] . posj1 = pos [ 1 ] ;
xy_to_pos ( polyrect [ i ] . x2 , polyrect [ i ] . y2 , pos ) ;
polyrect [ i ] . posi2 = pos [ 0 ] ;
polyrect [ i ] . posj2 = pos [ 1 ] ;
}
free ( maze ) ;
return ( nsides ) ;
}
2021-11-12 16:22:24 +01:00
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 ) ) ;
}
2021-12-28 15:42:56 +01:00
case ( D_TOKA_PRIME ) :
{
return ( compute_tokaprime_coordinates ( - MU , polyline ) ) ;
}
2021-11-12 16:22:24 +01:00
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 ) ) ;
}
2021-12-28 15:42:56 +01:00
case ( D_STAR ) :
{
return ( compute_star_coordinates ( polyline ) ) ;
}
2022-02-05 18:44:39 +01:00
case ( D_FRESNEL ) :
{
return ( compute_fresnel_coordinates ( polyline ) ) ;
}
case ( D_DOUBLE_FRESNEL ) :
{
return ( compute_double_fresnel_coordinates ( polyline , LAMBDA ) ) ;
}
case ( D_NOISEPANEL ) :
{
return ( compute_noisepanel_coordinates ( polyline ) ) ;
}
2022-06-25 15:49:37 +02:00
case ( D_NOISEPANEL_RECT ) :
{
return ( compute_noisepanel_rect_coordinates ( polyline ) ) ;
}
2022-03-13 15:29:50 +01:00
case ( D_QRD ) :
{
return ( compute_qrd_coordinates ( polyline ) ) ;
}
2021-11-12 16:22:24 +01:00
default :
{
return ( 0 ) ;
}
2021-10-24 15:20:56 +02:00
}
}
2022-10-18 23:28:20 +02:00
int init_polyrect ( t_rectangle polyrect [ NMAXPOLY ] )
/* initialise variable polyrect, for certain polygonal domain shapes */
{
switch ( B_DOMAIN ) {
case ( D_MAZE ) :
{
return ( compute_maze_coordinates ( polyrect , 0 ) ) ;
}
case ( D_MAZE_CLOSED ) :
{
return ( compute_maze_coordinates ( polyrect , 1 ) ) ;
}
2023-01-22 16:49:04 +01:00
case ( D_MAZE_CHANNELS ) :
{
return ( compute_maze_coordinates ( polyrect , 2 ) ) ;
}
2022-10-18 23:28:20 +02:00
default :
{
if ( ( ADD_POTENTIAL ) & & ( POTENTIAL = = POT_MAZE ) ) return ( compute_maze_coordinates ( polyrect , 1 ) ) ;
return ( 0 ) ;
}
}
}
2023-03-25 19:56:19 +01:00
int init_polyrect_euler ( t_rectangle polyrect [ NMAXPOLY ] , int domain )
/* initialise variable polyrect, for certain polygonal domain shapes */
{
switch ( domain ) {
case ( D_MAZE ) :
{
return ( compute_maze_coordinates ( polyrect , 0 ) ) ;
}
case ( D_MAZE_CLOSED ) :
{
return ( compute_maze_coordinates ( polyrect , 1 ) ) ;
}
case ( D_MAZE_CHANNELS ) :
{
return ( compute_maze_coordinates ( polyrect , 2 ) ) ;
}
2023-07-08 23:28:23 +02:00
case ( D_MAZE_CHANNELS_INT ) :
{
return ( compute_interior_maze_coordinates ( polyrect , 2 ) ) ;
}
2023-03-25 19:56:19 +01:00
}
}
2023-01-22 16:49:04 +01:00
void init_polyrect_arc ( t_rect_rotated polyrectrot [ NMAXPOLY ] , t_arc polyarc [ NMAXPOLY ] , int * npolyrect , int * npolyarc )
/* initialise variables polyrectrot and polyarc, for certain domain shapes */
{
switch ( B_DOMAIN ) {
case ( D_MAZE_CIRCULAR ) :
{
compute_circular_maze_coordinates ( polyrectrot , polyarc , npolyrect , npolyarc ) ;
break ;
}
}
}
2022-10-18 23:28:20 +02:00
2021-10-24 15:20:56 +02:00
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 ;
}
2021-11-12 16:22:24 +01:00
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 ;
}
2021-10-24 15:20:56 +02:00
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 ) ;
}
2021-11-12 16:22:24 +01:00
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 ) ;
}
2021-10-24 15:20:56 +02:00
2022-10-18 23:28:20 +02:00
int xy_in_polyrect ( double x , double y , t_rectangle rectangle )
/* returns 1 if (x,y) is in rectangle */
{
double x1 , y1 , x2 , y2 ;
if ( rectangle . x1 < rectangle . x2 )
{
x1 = rectangle . x1 ;
x2 = rectangle . x2 ;
}
else
{
x1 = rectangle . x2 ;
x2 = rectangle . x1 ;
}
if ( rectangle . y1 < rectangle . y2 )
{
y1 = rectangle . y1 ;
y2 = rectangle . y2 ;
}
else
{
y1 = rectangle . y2 ;
y2 = rectangle . y1 ;
}
if ( x < x1 ) return ( 0 ) ;
if ( x > x2 ) return ( 0 ) ;
if ( y < y1 ) return ( 0 ) ;
if ( y > y2 ) return ( 0 ) ;
return ( 1 ) ;
}
int ij_in_polyrect ( double i , double j , t_rectangle rectangle )
/* returns 1 if (x,y) is in rectangle */
{
int i1 , i2 , j1 , j2 ;
if ( rectangle . posi1 < rectangle . posi2 )
{
i1 = rectangle . posi1 ;
i2 = rectangle . posi2 ;
}
else
{
i1 = rectangle . posi2 ;
i2 = rectangle . posi1 ;
}
if ( rectangle . posj1 < rectangle . posj2 )
{
j1 = rectangle . posj1 ;
j2 = rectangle . posj2 ;
}
else
{
j1 = rectangle . posj2 ;
j2 = rectangle . posj1 ;
}
if ( i < i1 ) return ( 0 ) ;
if ( i > i2 ) return ( 0 ) ;
if ( j < j1 ) return ( 0 ) ;
if ( j > j2 ) return ( 0 ) ;
return ( 1 ) ;
}
2023-01-22 16:49:04 +01:00
int xy_in_rectrotated ( double x , double y , t_rect_rotated rectrot )
/* returns 1 if (x,y) is in rectangle */
{
double l , u1 , u2 , v1 , v2 , pscal , h2 ;
l = module2 ( rectrot . x2 - rectrot . x1 , rectrot . y2 - rectrot . y1 ) ;
if ( l = = 0.0 ) return ( 0 ) ;
/* unit vector along axis */
u1 = ( rectrot . x2 - rectrot . x1 ) / l ;
u2 = ( rectrot . y2 - rectrot . y1 ) / l ;
/* vector from one extremity to (x,y) */
v1 = x - rectrot . x1 ;
v2 = y - rectrot . y1 ;
/* inner product */
pscal = u1 * v1 + u2 * v2 ;
if ( pscal < 0.0 ) return ( 0 ) ;
if ( pscal > l ) return ( 0 ) ;
h2 = v1 * v1 + v2 * v2 - pscal * pscal ;
return ( 4.0 * h2 < = rectrot . width * rectrot . width ) ;
}
int xy_in_arc ( double x , double y , t_arc arc )
/* returns 1 if (x,y) is in arc */
{
double rho , phi , alpha ;
rho = module2 ( x - arc . xc , y - arc . yc ) ;
if ( vabs ( rho - arc . r ) > 0.5 * arc . width ) return ( 0 ) ;
phi = argument ( x - arc . xc , y - arc . yc ) ;
alpha = phi - arc . angle1 ;
while ( alpha < 0.0 ) alpha + = DPI ;
while ( alpha > DPI ) alpha - = DPI ;
return ( alpha < = arc . dangle ) ;
}
2022-10-18 23:28:20 +02:00
2022-08-20 16:02:07 +02:00
int xy_in_billiard_single_domain ( double x , double y , int b_domain , int ncirc , t_circle * circles )
2021-05-29 16:50:49 +02:00
/* returns 1 if (x,y) represents a point in the billiard */
{
2023-01-22 16:49:04 +01:00
double l2 , r2 , r2mu , omega , b , c , angle , z , x1 , y1 , x2 , y2 , u , v , u1 , v1 , dx , dy , width , alpha , s , a , r , height , ca , sa , l , ht ;
2021-12-28 15:42:56 +01:00
int i , j , k , k1 , k2 , condition = 0 , m ;
2021-11-12 16:22:24 +01:00
static int first = 1 , nsides ;
2023-01-22 16:49:04 +01:00
static double h , hh , ra , rb , ll , salpha ;
2021-05-29 16:50:49 +02:00
2022-08-20 16:02:07 +02:00
switch ( b_domain ) {
2022-05-14 20:58:08 +02:00
case ( D_NOTHING ) :
{
return ( 1 ) ;
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_RECTANGLE ) :
2021-05-29 16:50:49 +02:00
{
if ( ( vabs ( x ) < LAMBDA ) & & ( vabs ( y ) < 1.0 ) ) return ( 1 ) ;
else return ( 0 ) ;
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_ELLIPSE ) :
2021-05-29 16:50:49 +02:00
{
if ( x * x / ( LAMBDA * LAMBDA ) + y * y < 1.0 ) return ( 1 ) ;
else return ( 0 ) ;
break ;
}
2022-11-20 23:17:39 +01:00
case ( D_EXT_ELLIPSE ) :
{
if ( x * x / ( LAMBDA * LAMBDA ) + y * y / ( MU * MU ) > 1.0 ) return ( 1 ) ;
else return ( 0 ) ;
break ;
}
case ( D_EXT_ELLIPSE_CURVED ) :
{
y1 = y + 0.4 * x * x ;
if ( x * x / ( LAMBDA * LAMBDA ) + y1 * y1 / ( MU * MU ) > 1.0 ) return ( 1 ) ;
else return ( 0 ) ;
break ;
}
case ( D_EXT_ELLIPSE_CURVED_BDRY ) :
{
if ( y > YMAX - 0.05 ) return ( 0 ) ;
if ( y < YMIN + 0.05 ) return ( 0 ) ;
y1 = y + 0.4 * x * x ;
if ( x * x / ( LAMBDA * LAMBDA ) + y1 * y1 / ( MU * MU ) > 1.0 ) return ( 1 ) ;
else return ( 0 ) ;
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_STADIUM ) :
2021-05-29 16:50:49 +02:00
{
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 ;
}
2021-08-15 11:49:37 +02:00
case ( D_SINAI ) :
2021-05-29 16:50:49 +02:00
{
if ( x * x + y * y > LAMBDA * LAMBDA ) return ( 1 ) ;
else return ( 0 ) ;
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_DIAMOND ) :
2021-05-29 16:50:49 +02:00
{
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 ;
}
2021-08-15 11:49:37 +02:00
case ( D_TRIANGLE ) :
2021-05-29 16:50:49 +02:00
{
if ( ( x > - LAMBDA ) & & ( y > - 1.0 ) & & ( LAMBDA * y + x < 0.0 ) ) return ( 1 ) ;
else return ( 0 ) ;
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_FLAT ) :
2021-05-29 16:50:49 +02:00
{
if ( y > - LAMBDA ) return ( 1 ) ;
else return ( 0 ) ;
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_ANNULUS ) :
2021-05-29 16:50:49 +02:00
{
l2 = LAMBDA * LAMBDA ;
r2 = x * x + y * y ;
if ( ( r2 > l2 ) & & ( r2 < 1.0 ) ) return ( 1 ) ;
else return ( 0 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_POLYGON ) :
2021-05-29 16:50:49 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_YOUNG ) :
2021-05-29 16:50:49 +02:00
{
if ( ( x < - MU ) | | ( x > MU ) ) return ( 1 ) ;
else if ( ( vabs ( y - LAMBDA ) < MU ) | | ( vabs ( y + LAMBDA ) < MU ) ) return ( 1 ) ;
else return ( 0 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_GRATING ) :
2021-05-29 16:50:49 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_EHRENFEST ) :
2021-05-29 16:50:49 +02:00
{
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 ) ) ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_DISK_GRID ) :
2021-07-18 15:06:59 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_DISK_HEX ) :
2021-07-18 15:06:59 +02:00
{
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 ) ;
}
2021-09-01 17:03:02 +02:00
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 ) ;
}
2021-09-26 16:47:29 +02:00
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 + + )
{
2023-01-22 16:49:04 +01:00
angle = APOLY * PID + ( ( double ) k + 0.5 ) * omega ;
2021-09-26 16:47:29 +02:00
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 ) ;
}
2021-10-03 14:24:56 +02:00
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 ) ;
}
}
2021-12-28 15:42:56 +01:00
case ( D_TOKA_PRIME ) :
{
// x1 = vabs(x);
if ( x + MU > 0.0 ) x1 = x ;
else x1 = - 2.0 * MU - x ;
condition = xy_in_triangle_tvertex ( x1 , y , polyline [ 0 ] , polyline [ 1 ] , polyline [ 2 ] ) ;
condition + = xy_in_triangle_tvertex ( x1 , y , polyline [ 0 ] , polyline [ 2 ] , polyline [ 3 ] ) ;
condition + = xy_in_triangle_tvertex ( x1 , y , polyline [ i ] , polyline [ 3 ] , polyline [ 4 ] ) ;
for ( i = 3 ; i < 42 ; i + + )
condition + = xy_in_triangle_tvertex ( x1 , y , polyline [ i ] , polyline [ 43 ] , polyline [ i + 1 ] ) ;
condition + = xy_in_triangle_tvertex ( x1 , y , polyline [ 42 ] , polyline [ 43 ] , polyline [ 3 ] ) ;
return ( condition > = 1 ) ;
}
2021-10-24 15:20:56 +02:00
case ( D_ISOSPECTRAL ) :
{
/* 1st triangle */
2021-11-12 16:22:24 +01:00
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 ] ) ;
2021-10-24 15:20:56 +02:00
/* 2nd triangle */
2021-11-12 16:22:24 +01:00
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 ] ) ;
2021-10-24 15:20:56 +02:00
return ( condition > = 1 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_CIRCLES ) :
2021-07-18 15:06:59 +02:00
{
2022-08-20 16:02:07 +02:00
for ( i = 0 ; i < ncirc ; i + + )
2021-11-12 16:22:24 +01:00
if ( circles [ i ] . active )
2021-07-18 15:06:59 +02:00
{
2021-11-12 16:22:24 +01:00
x1 = circles [ i ] . xc ;
y1 = circles [ i ] . yc ;
r2 = circles [ i ] . radius * circles [ i ] . radius ;
2021-07-18 15:06:59 +02:00
if ( ( x - x1 ) * ( x - x1 ) + ( y - y1 ) * ( y - y1 ) < r2 ) return ( 0 ) ;
}
return ( 1 ) ;
}
2021-10-24 15:20:56 +02:00
case ( D_CIRCLES_IN_RECT ) : /* returns 2 inside circles, 0 outside rectangle */
{
2022-08-20 16:02:07 +02:00
for ( i = 0 ; i < ncirc ; i + + )
2021-11-12 16:22:24 +01:00
if ( circles [ i ] . active )
2021-10-24 15:20:56 +02:00
{
2021-11-12 16:22:24 +01:00
x1 = circles [ i ] . xc ;
y1 = circles [ i ] . yc ;
r2 = circles [ i ] . radius * circles [ i ] . radius ;
2021-10-24 15:20:56 +02:00
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 ) ;
}
2021-11-12 16:22:24 +01:00
case ( D_POLYGONS ) :
{
2022-08-20 16:02:07 +02:00
for ( i = 0 ; i < ncirc ; i + + )
2021-11-12 16:22:24 +01:00
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 ) ;
}
2021-12-28 15:42:56 +01:00
case ( D_STAR ) :
{
condition = xy_in_triangle_tvertex ( x , y , polyline [ NPOLY ] , polyline [ NPOLY - 1 ] , polyline [ 0 ] ) ;
for ( i = 0 ; i < NPOLY - 1 ; i + + )
condition + = xy_in_triangle_tvertex ( x , y , polyline [ NPOLY ] , polyline [ i ] , polyline [ i + 1 ] ) ;
return ( condition > = 1 ) ;
}
2022-02-05 18:44:39 +01:00
case ( D_FRESNEL ) :
{
2022-03-13 15:29:50 +01:00
if ( vabs ( y ) > 0.9 * vabs ( LAMBDA ) ) return ( 1 ) ;
2022-02-05 18:44:39 +01:00
if ( vabs ( x ) > MU ) return ( 1 ) ;
2022-03-13 15:29:50 +01:00
x1 = sqrt ( LAMBDA * LAMBDA - y * y ) - vabs ( LAMBDA ) ;
2022-02-05 18:44:39 +01:00
while ( x1 < = 0.0 ) x1 + = MU ;
2022-03-13 15:29:50 +01:00
if ( LAMBDA > 0.0 )
{
if ( x < x1 ) return ( 0 ) ;
else return ( 1 ) ;
}
else
{
x1 = - x1 ;
if ( x > x1 ) return ( 0 ) ;
else return ( 1 ) ;
}
2022-02-05 18:44:39 +01:00
}
case ( D_DOUBLE_FRESNEL ) :
{
if ( vabs ( y ) > 0.9 * vabs ( LAMBDA ) ) return ( 1 ) ;
if ( LAMBDA > 0.0 )
{
if ( vabs ( x ) > LAMBDA + MU ) return ( 1 ) ;
x1 = sqrt ( LAMBDA * LAMBDA - y * y ) - LAMBDA ;
while ( x1 < = 0.0 ) x1 + = MU ;
x1 - = LAMBDA ;
if ( vabs ( x ) > - x1 ) return ( 0 ) ;
else return ( 1 ) ;
}
else
{
if ( vabs ( x ) < - LAMBDA - MU ) return ( 1 ) ;
x1 = sqrt ( LAMBDA * LAMBDA - y * y ) + LAMBDA ;
while ( x1 < = 0.0 ) x1 + = MU ;
x1 - = LAMBDA ;
if ( vabs ( x ) > x1 ) return ( 1 ) ;
else return ( 0 ) ;
}
}
case ( D_NOISEPANEL ) :
{
x1 = vabs ( x ) ;
while ( x1 > 2.0 * LAMBDA ) x1 - = 2.0 * LAMBDA ;
if ( x1 < = LAMBDA ) y1 = 0.1 + MU * x1 / LAMBDA ;
else y1 = 0.1 + 2.0 * MU - MU * x1 / LAMBDA ;
return ( ( y > YMIN + y1 ) & & ( y < YMAX - y1 ) ) ;
2022-03-13 15:29:50 +01:00
}
2022-06-25 15:49:37 +02:00
case ( D_NOISEPANEL_RECT ) :
{
x1 = - x ;
if ( x1 > NPWIDTH )
{
while ( x1 > 2.0 * LAMBDA ) x1 - = 2.0 * LAMBDA ;
if ( x1 < = LAMBDA ) y1 = 0.1 + MU * x1 / LAMBDA ;
else y1 = 0.1 + 2.0 * MU - MU * x1 / LAMBDA ;
return ( ( y > YMIN + y1 ) & & ( y < YMAX - y1 ) & & ( x > XMIN + 0.1 ) ) ;
}
else if ( x > NPWIDTH )
{
return ( ( vabs ( y ) < YMAX - 0.1 ) & & ( x < XMAX - 0.1 ) ) ;
}
else return ( 0 ) ;
}
2022-03-13 15:29:50 +01:00
case ( D_QRD ) :
{
x1 = vabs ( x ) / LAMBDA ;
k = ( int ) ( x1 + 0.5 ) ;
k1 = ( k * k ) % 13 ;
y1 = ( MU / 13.0 ) * ( 14.0 - ( double ) k1 ) ;
return ( ( y > YMIN + y1 ) & & ( y < YMAX - y1 ) ) ;
}
2022-06-25 15:49:37 +02:00
case ( D_QRD_ASYM ) :
{
if ( y > 0.0 )
{
x1 = vabs ( x ) / LAMBDA ;
k = ( int ) ( x1 + 0.5 ) ;
k1 = ( k * k ) % 13 ;
y1 = ( MU / 13.0 ) * ( 14.0 - ( double ) k1 ) ;
return ( y < YMAX - y1 ) ;
}
else
{
x1 = vabs ( x + 1.0 ) / LAMBDA ;
k = ( int ) ( x1 + 0.5 ) ;
k1 = ( k * k ) % 17 ;
y1 = ( MU / 17.0 ) * ( 18.0 - ( double ) k1 ) ;
return ( y > YMIN + y1 ) ;
}
}
2022-03-13 15:29:50 +01:00
case ( D_CIRCLE_SEGMENT ) :
{
if ( vabs ( y ) > 0.9 * vabs ( LAMBDA ) ) return ( 1 ) ;
y1 = 0.9 * LAMBDA ;
x1 = sqrt ( LAMBDA * LAMBDA - y1 * y1 ) - vabs ( LAMBDA ) + MU ;
if ( ( LAMBDA > 0.0 ) & & ( x < x1 ) ) return ( 1 ) ;
else if ( ( LAMBDA < 0.0 ) & & ( x > - x1 ) ) return ( 1 ) ;
x1 = sqrt ( LAMBDA * LAMBDA - y * y ) - vabs ( LAMBDA ) + MU ;
if ( LAMBDA > 0.0 )
{
if ( x < x1 ) return ( 0 ) ;
else return ( 1 ) ;
}
else
{
if ( x > - x1 ) return ( 0 ) ;
else return ( 1 ) ;
}
2022-02-05 18:44:39 +01:00
}
2022-06-25 15:49:37 +02:00
case ( D_GROOVE ) :
{
s = 0.85 * LAMBDA ;
a = 0.5 * LAMBDA ;
x1 = x - XMIN - ( double ) ( ( int ) ( ( x - XMIN ) / LAMBDA ) ) * LAMBDA ;
if ( x1 < a ) return ( y > YMIN + LAMBDA ) ;
else return ( y > YMIN + LAMBDA + s ) ;
}
2022-08-20 16:02:07 +02:00
case ( D_FABRY_PEROT ) :
{
return ( vabs ( x - y * LAMBDA / YMAX ) > 0.5 * MU ) ;
}
case ( D_LSHAPE ) :
{
if ( vabs ( x ) > LAMBDA ) return ( 0 ) ;
else if ( vabs ( y ) > 1.0 ) return ( 0 ) ;
else if ( ( x > 0.0 ) & & ( y > 0.0 ) ) return ( 0 ) ;
else return ( 1 ) ;
}
2022-10-18 23:28:20 +02:00
case ( D_WAVEGUIDE ) :
{
x1 = XMIN + MU ;
x2 = XMAX - 2.0 * MU - 1.5 * LAMBDA ;
y1 = 0.5 * LAMBDA ;
y2 = 1.5 * LAMBDA ;
if ( x < x1 ) return ( 0 ) ;
if ( x > x2 + 1.5 * LAMBDA ) return ( 0 ) ;
if ( vabs ( y ) > y2 ) return ( 0 ) ;
if ( x < x2 ) return ( vabs ( y ) > = y1 ) ;
r = module2 ( x - x2 , y ) ;
if ( r < 0.5 * LAMBDA ) return ( 0 ) ;
if ( r > 1.5 * LAMBDA ) return ( 0 ) ;
return ( 1 ) ;
}
case ( D_WAVEGUIDE_W ) :
{
x1 = vabs ( x ) ;
width = LAMBDA - 2.0 * MU ;
height = 0.5 * MU ;
if ( x1 > 2.0 * LAMBDA - MU ) return ( 0 ) ;
if ( vabs ( y ) > MU + width + height ) return ( 0 ) ;
if ( y > = height )
{
r = module2 ( x1 , y - height ) ;
if ( ( r > MU ) & & ( r < MU + width ) ) return ( 1 ) ;
if ( x1 > LAMBDA + MU ) return ( 1 ) ;
return ( 0 ) ;
}
if ( y < = - height )
{
r = module2 ( x1 - LAMBDA , y + height ) ;
if ( ( r > MU ) & & ( r < MU + width ) ) return ( 1 ) ;
return ( 0 ) ;
}
if ( x1 > LAMBDA + MU ) return ( 1 ) ;
if ( ( x1 > MU ) & & ( x1 < MU + width ) ) return ( 1 ) ;
return ( 0 ) ;
}
case ( D_MAZE ) :
{
for ( i = 0 ; i < npolyrect ; i + + )
if ( ( x > polyrect [ i ] . x1 ) & & ( x < polyrect [ i ] . x2 ) & & ( y > polyrect [ i ] . y1 ) & & ( y < polyrect [ i ] . y2 ) ) return ( 0 ) ;
return ( 1 ) ;
}
case ( D_MAZE_CLOSED ) :
{
for ( i = 0 ; i < npolyrect ; i + + )
if ( ( x > polyrect [ i ] . x1 ) & & ( x < polyrect [ i ] . x2 ) & & ( y > polyrect [ i ] . y1 ) & & ( y < polyrect [ i ] . y2 ) ) return ( 0 ) ;
return ( 1 ) ;
}
2023-01-22 16:49:04 +01:00
case ( D_MAZE_CHANNELS ) :
{
for ( i = 0 ; i < npolyrect ; i + + )
if ( ( x > polyrect [ i ] . x1 ) & & ( x < polyrect [ i ] . x2 ) & & ( y > polyrect [ i ] . y1 ) & & ( y < polyrect [ i ] . y2 ) ) return ( 0 ) ;
return ( 1 ) ;
}
case ( D_MAZE_CIRCULAR ) :
{
for ( i = 0 ; i < npolyrect_rot ; i + + )
if ( xy_in_rectrotated ( x , y , polyrectrot [ i ] ) ) return ( 0 ) ;
for ( i = 0 ; i < npolyarc ; i + + )
if ( xy_in_arc ( x , y , polyarc [ i ] ) ) return ( 0 ) ;
return ( 1 ) ;
}
2022-11-20 23:17:39 +01:00
case ( D_CHESSBOARD ) :
{
i = ( int ) ( vabs ( x ) / LAMBDA + 0.5 ) ;
j = ( int ) ( vabs ( y ) / LAMBDA + 0.5 ) ;
if ( ( i + j ) % 2 = = 0 ) return ( 1 ) ;
else return ( 0 ) ;
}
case ( D_TRIANGLE_TILES ) :
{
if ( first )
{
h = LAMBDA / ( 2.0 * sqrt ( 3.0 ) ) ;
hh = h * 3.0 ;
first = 0 ;
}
i = ( int ) ( ( y + h ) / hh + 10.0 ) ;
y1 = sin ( DPI / 3.0 ) * x - 0.5 * y ;
j = ( int ) ( ( y1 + h ) / hh + 10.0 ) ;
y1 = sin ( - DPI / 3.0 ) * x - 0.5 * y ;
k = ( int ) ( ( y1 + h ) / hh + 10.0 ) ;
if ( ( i + j + k ) % 2 = = 0 ) return ( 1 ) ;
else return ( 0 ) ;
}
case ( D_HEX_TILES ) :
{
if ( first )
{
ra = - 1.0 / sqrt ( 3.0 ) ;
rb = - 2.0 * ra ;
first = 0 ;
}
x1 = ( x + ra * y ) / LAMBDA + 30.0 ;
y1 = rb * y / LAMBDA + 30.0 ;
x1 = x1 - ( double ) ( 3 * ( int ) ( x1 / 3.0 ) ) ;
y1 = y1 - ( double ) ( 3 * ( int ) ( y1 / 3.0 ) ) ;
if ( ( x1 > 2.0 ) & & ( y1 < 1.0 ) ) return ( 1 ) ;
if ( ( x1 < 1.0 ) & & ( y1 > 2.0 ) ) return ( 1 ) ;
if ( x1 + y1 < 1.0 ) return ( 1 ) ;
if ( x1 + y1 > 5.0 ) return ( 1 ) ;
return ( 0 ) ;
}
2023-01-22 16:49:04 +01:00
case ( D_FUNNELS ) :
{
y1 = y ;
if ( y > 0.5 * YMAX ) y1 - = YMAX ;
if ( y < - 0.5 * YMAX ) y1 + = YMAX ;
y1 = vabs ( y1 - MU * x ) ;
y1 = vabs ( y1 - 0.5 * YMAX ) * 2.0 / YMAX ;
if ( y1 > 0.25 * ( 1.0 + LAMBDA + x * x ) ) return ( 0 ) ;
return ( 1 ) ;
}
case ( D_ONE_FUNNEL ) :
{
y1 = vabs ( y ) ;
if ( y1 > MU + LAMBDA * x * x ) return ( 0 ) ;
return ( 1 ) ;
}
case ( D_LENSES_RING ) :
{
if ( first )
{
salpha = DPI / ( double ) NPOLY ;
h = LAMBDA * tan ( PI / ( double ) NPOLY ) ;
if ( h < MU ) ll = sqrt ( MU * MU - h * h ) ;
else ll = 0.0 ;
first = 0 ;
}
for ( i = 0 ; i < NPOLY ; i + + )
{
ca = cos ( ( double ) i * salpha + APOLY * PID ) ;
sa = sin ( ( double ) i * salpha + APOLY * PID ) ;
x1 = x * ca + y * sa ;
y1 = - x * sa + y * ca ;
if ( ( module2 ( x1 - LAMBDA - ll , y1 ) < MU ) & & ( module2 ( x1 - LAMBDA + ll , y1 ) < MU ) ) return ( 0 ) ;
}
return ( 1 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_MENGER ) :
2021-06-20 23:31:23 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_JULIA_INT ) :
2021-06-20 23:31:23 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_MENGER_ROTATED ) :
2021-07-18 15:06:59 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_ANNULUS_HEATED ) : /* returns 2 if in inner circle */
2021-06-20 23:31:23 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_MENGER_HEATED ) :
2021-06-20 23:31:23 +02:00
{
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 ) ;
}
}
2021-08-15 11:49:37 +02:00
case ( D_MENGER_H_OPEN ) : /* returns 2 if in inner circle */
2021-06-20 23:31:23 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_MANDELBROT ) :
2021-06-20 23:31:23 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_MANDELBROT_CIRCLE ) :
2021-06-20 23:31:23 +02:00
{
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 ) ;
}
2021-08-15 11:49:37 +02:00
case ( D_JULIA ) :
2021-06-20 23:31:23 +02:00
{
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 ) ;
}
2021-11-12 16:22:24 +01:00
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 ) ;
}
2021-05-29 16:50:49 +02:00
default :
{
printf ( " Function ij_in_billiard not defined for this billiard \n " ) ;
return ( 0 ) ;
}
}
}
2022-08-20 16:02:07 +02:00
int xy_in_billiard ( double x , double y )
/* returns 1 if (x,y) represents a point in the billiard */
{
if ( COMPARISON )
{
if ( y > 0.0 ) return ( xy_in_billiard_single_domain ( x , y , B_DOMAIN , ncircles , circles ) ) ;
else return ( xy_in_billiard_single_domain ( x , y , B_DOMAIN_B , ncircles_b , circles_b ) ) ;
}
else return ( xy_in_billiard_single_domain ( x , y , B_DOMAIN , ncircles , circles ) ) ;
}
2021-08-15 11:49:37 +02:00
int ij_in_billiard ( int i , int j )
2021-05-29 16:50:49 +02:00
/* 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 ] ) ) ;
}
2021-11-12 16:22:24 +01:00
void tvertex_lineto ( t_vertex z )
2021-10-24 15:20:56 +02:00
/* draws boundary segments of isospectral billiard */
{
2021-11-12 16:22:24 +01:00
glVertex2d ( z . posi , z . posj ) ;
2021-10-24 15:20:56 +02:00
}
2022-11-20 23:17:39 +01:00
void hex_transfo ( double u , double v , double * x , double * y )
/* linear transformation of plane used for hex tiles */
{
static double ra , rb ;
static int first = 1 ;
if ( first )
{
ra = 0.5 ;
rb = 0.5 * sqrt ( 3.0 ) ;
first = 0 ;
}
* x = u + ra * v ;
* y = rb * v ;
}
2022-06-25 15:49:37 +02:00
void draw_billiard ( int fade , double fade_value ) /* draws the billiard boundary */
2021-05-29 16:50:49 +02:00
{
2023-01-22 16:49:04 +01:00
double x0 , y0 , x , y , x1 , y1 , x2 , y2 , dx , dy , phi , r = 0.01 , pos [ 2 ] , pos1 [ 2 ] , alpha , dphi , omega , z , l , width , a , b , c , ymax , height , xmax , ca , sa ;
2022-11-20 23:17:39 +01:00
int i , j , k , k1 , k2 , mr2 , ntiles ;
2021-11-12 16:22:24 +01:00
static int first = 1 , nsides ;
2023-01-22 16:49:04 +01:00
static double h , hh , sqr3 , ll , salpha , arcangle ;
2021-05-29 16:50:49 +02:00
2022-06-25 15:49:37 +02:00
if ( fade )
{
if ( BLACK ) glColor3f ( fade_value , fade_value , fade_value ) ;
else glColor3f ( 1.0 - fade_value , 1.0 - fade_value , 1.0 - fade_value ) ;
}
else
{
if ( BLACK ) glColor3f ( 1.0 , 1.0 , 1.0 ) ;
else glColor3f ( 0.0 , 0.0 , 0.0 ) ;
}
2021-07-30 10:25:50 +02:00
glLineWidth ( BOUNDARY_WIDTH ) ;
2021-05-29 16:50:49 +02:00
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 )
{
2022-06-25 15:49:37 +02:00
if ( fade ) glColor3f ( 0.3 * fade_value , 0.3 * fade_value , 0.3 * fade_value ) ;
else glColor3f ( 0.3 , 0.3 , 0.3 ) ;
2021-05-29 16:50:49 +02:00
x0 = sqrt ( LAMBDA * LAMBDA - 1.0 ) ;
glLineWidth ( 2 ) ;
glEnable ( GL_LINE_SMOOTH ) ;
2021-08-15 11:49:37 +02:00
draw_circle ( x0 , 0.0 , r , NSEG ) ;
draw_circle ( - x0 , 0.0 , r , NSEG ) ;
2021-05-29 16:50:49 +02:00
}
break ;
}
2022-11-20 23:17:39 +01:00
case ( D_EXT_ELLIPSE ) :
{
glBegin ( GL_LINE_LOOP ) ;
for ( i = 0 ; i < = NSEG ; i + + )
{
phi = ( double ) i * DPI / ( double ) NSEG ;
x = LAMBDA * cos ( phi ) ;
y = MU * sin ( phi ) ;
xy_to_pos ( x , y , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
}
glEnd ( ) ;
/* draw foci */
if ( FOCI )
{
if ( fade ) glColor3f ( 0.3 * fade_value , 0.3 * fade_value , 0.3 * fade_value ) ;
else glColor3f ( 0.3 , 0.3 , 0.3 ) ;
x0 = sqrt ( LAMBDA * LAMBDA - MU * MU ) ;
glLineWidth ( 2 ) ;
glEnable ( GL_LINE_SMOOTH ) ;
draw_circle ( x0 , 0.0 , r , NSEG ) ;
draw_circle ( - x0 , 0.0 , r , NSEG ) ;
}
break ;
}
case ( D_EXT_ELLIPSE_CURVED ) :
{
glBegin ( GL_LINE_LOOP ) ;
for ( i = 0 ; i < = NSEG ; i + + )
{
phi = ( double ) i * DPI / ( double ) NSEG ;
x = LAMBDA * cos ( phi ) ;
y = MU * sin ( phi ) - 0.4 * x * x ;
xy_to_pos ( x , y , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
}
glEnd ( ) ;
break ;
}
case ( D_EXT_ELLIPSE_CURVED_BDRY ) :
{
glBegin ( GL_LINE_LOOP ) ;
for ( i = 0 ; i < = NSEG ; i + + )
{
phi = ( double ) i * DPI / ( double ) NSEG ;
x = LAMBDA * cos ( phi ) ;
y = MU * sin ( phi ) - 0.4 * x * x ;
xy_to_pos ( x , y , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
}
glEnd ( ) ;
draw_line ( XMIN , YMAX - 0.05 , XMAX , YMAX - 0.05 ) ;
draw_line ( XMIN , YMIN + 0.05 , XMAX , YMIN + 0.05 ) ;
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_STADIUM ) :
2021-05-29 16:50:49 +02:00
{
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 ;
}
2021-08-15 11:49:37 +02:00
case ( D_SINAI ) :
2021-05-29 16:50:49 +02:00
{
2021-08-15 11:49:37 +02:00
draw_circle ( 0.0 , 0.0 , LAMBDA , NSEG ) ;
2021-05-29 16:50:49 +02:00
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_DIAMOND ) :
2021-05-29 16:50:49 +02:00
{
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 ) :
{
2021-08-15 11:49:37 +02:00
draw_circle ( 0.0 , 0.0 , LAMBDA , NSEG ) ;
draw_circle ( 0.0 , 0.0 , 1.0 , NSEG ) ;
2021-05-29 16:50:49 +02:00
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 ;
}
2021-08-15 11:49:37 +02:00
case ( D_GRATING ) :
2021-05-29 16:50:49 +02:00
{
k1 = - ( int ) ( - YMIN / LAMBDA ) ;
k2 = ( int ) ( YMAX / LAMBDA ) ;
for ( i = k1 ; i < = k2 ; i + + )
{
z = ( double ) i * LAMBDA ;
2021-08-15 11:49:37 +02:00
draw_circle ( 0.0 , z , MU , NSEG ) ;
2021-05-29 16:50:49 +02:00
}
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_EHRENFEST ) :
2021-05-29 16:50:49 +02:00
{
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 ;
}
2021-08-15 11:49:37 +02:00
case ( D_DISK_GRID ) :
2021-07-18 15:06:59 +02:00
{
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 ;
2021-08-15 11:49:37 +02:00
draw_circle ( x1 , y1 , MU , NSEG ) ;
2021-07-18 15:06:59 +02:00
}
break ;
}
2021-08-15 11:49:37 +02:00
case ( D_DISK_HEX ) :
2021-07-18 15:06:59 +02:00
{
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 ;
2021-08-15 11:49:37 +02:00
draw_circle ( x1 , y1 , MU , NSEG ) ;
2021-07-18 15:06:59 +02:00
}
break ;
}
2021-09-01 17:03:02 +02:00
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 ;
}
2021-09-26 16:47:29 +02:00
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 + + )
{
2021-10-24 15:20:56 +02:00
alpha = APOLY * PID + ( 2.0 * ( double ) k + 1.0 ) * omega ;
2021-09-26 16:47:29 +02:00
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 ;
}
2021-10-03 14:24:56 +02:00
case ( D_TOKARSKY ) :
{
glBegin ( GL_LINE_LOOP ) ;
2021-11-12 16:22:24 +01:00
for ( i = 0 ; i < npolyline ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
2021-10-03 14:24:56 +02:00
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 ;
}
2021-12-28 15:42:56 +01:00
case ( D_TOKA_PRIME ) :
{
glBegin ( GL_LINE_LOOP ) ;
tvertex_lineto ( polyline [ 0 ] ) ;
for ( i = 4 ; i < 43 ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
tvertex_lineto ( polyline [ 3 ] ) ;
tvertex_lineto ( polyline [ 2 ] ) ;
tvertex_lineto ( polyline [ 1 ] ) ;
tvertex_lineto ( polyline [ 44 ] ) ;
tvertex_lineto ( polyline [ 45 ] ) ;
for ( i = 84 ; i > 45 ; i - - ) tvertex_lineto ( polyline [ i ] ) ;
glEnd ( ) ;
/* inner lines */
// glLineWidth(BOUNDARY_WIDTH/2);
glLineWidth ( 1 ) ;
glColor3f ( 0.75 , 0.75 , 0.75 ) ;
glBegin ( GL_LINE_STRIP ) ;
tvertex_lineto ( polyline [ 0 ] ) ;
tvertex_lineto ( polyline [ 1 ] ) ;
tvertex_lineto ( polyline [ 2 ] ) ;
tvertex_lineto ( polyline [ 0 ] ) ;
tvertex_lineto ( polyline [ 3 ] ) ;
tvertex_lineto ( polyline [ 4 ] ) ;
glEnd ( ) ;
glBegin ( GL_LINE_STRIP ) ;
tvertex_lineto ( polyline [ 0 ] ) ;
tvertex_lineto ( polyline [ 44 ] ) ;
tvertex_lineto ( polyline [ 45 ] ) ;
tvertex_lineto ( polyline [ 0 ] ) ;
tvertex_lineto ( polyline [ 46 ] ) ;
tvertex_lineto ( polyline [ 45 ] ) ;
glEnd ( ) ;
for ( i = 3 ; i < 43 ; i + + )
{
glBegin ( GL_LINE_STRIP ) ;
tvertex_lineto ( polyline [ i ] ) ;
tvertex_lineto ( polyline [ 43 ] ) ;
glEnd ( ) ;
glBegin ( GL_LINE_STRIP ) ;
tvertex_lineto ( polyline [ i + 42 ] ) ;
tvertex_lineto ( polyline [ 85 ] ) ;
glEnd ( ) ;
}
break ;
}
2021-10-24 15:20:56 +02:00
case ( D_ISOSPECTRAL ) :
{
/* 1st triangle */
glBegin ( GL_LINE_LOOP ) ;
2021-11-12 16:22:24 +01:00
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 ] ) ;
2021-10-24 15:20:56 +02:00
glEnd ( ) ;
/* inner lines */
glBegin ( GL_LINE_LOOP ) ;
2021-11-12 16:22:24 +01:00
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 ] ) ;
2021-10-24 15:20:56 +02:00
glEnd ( ) ;
/* 2nd triangle */
glBegin ( GL_LINE_LOOP ) ;
2021-11-12 16:22:24 +01:00
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 ] ) ;
2021-10-24 15:20:56 +02:00
glEnd ( ) ;
/* inner lines */
glBegin ( GL_LINE_LOOP ) ;
2021-11-12 16:22:24 +01:00
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 ] ) ;
2021-10-24 15:20:56 +02:00
glEnd ( ) ;
break ;
}
2021-12-28 15:42:56 +01:00
case ( D_STAR ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
glBegin ( GL_LINE_LOOP ) ;
for ( i = 0 ; i < npolyline ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
glEnd ( ) ;
break ;
}
2022-02-05 18:44:39 +01:00
case ( D_FRESNEL ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
glBegin ( GL_LINE_LOOP ) ;
for ( i = 0 ; i < npolyline ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
glEnd ( ) ;
break ;
}
case ( D_DOUBLE_FRESNEL ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
glBegin ( GL_LINE_LOOP ) ;
for ( i = 0 ; i < npolyline / 2 ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
glEnd ( ) ;
glBegin ( GL_LINE_LOOP ) ;
for ( i = npolyline / 2 ; i < npolyline ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
glEnd ( ) ;
break ;
}
case ( D_NOISEPANEL ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
glBegin ( GL_LINE_STRIP ) ;
for ( i = 0 ; i < npolyline ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
glEnd ( ) ;
break ;
}
2022-06-25 15:49:37 +02:00
case ( D_NOISEPANEL_RECT ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
glBegin ( GL_LINE_STRIP ) ;
for ( i = 0 ; i < npolyline ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
glEnd ( ) ;
break ;
}
2022-03-13 15:29:50 +01:00
case ( D_QRD ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
glBegin ( GL_LINE_STRIP ) ;
for ( i = 0 ; i < npolyline / 2 ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
glEnd ( ) ;
glBegin ( GL_LINE_STRIP ) ;
for ( i = npolyline / 2 ; i < npolyline ; i + + ) tvertex_lineto ( polyline [ i ] ) ;
glEnd ( ) ;
break ;
}
2022-08-20 16:02:07 +02:00
case ( D_FABRY_PEROT ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
draw_line ( - LAMBDA - 0.5 * MU , YMIN , LAMBDA - 0.5 * MU , YMAX ) ;
draw_line ( - LAMBDA + 0.5 * MU , YMIN , LAMBDA + 0.5 * MU , YMAX ) ;
break ;
}
2022-10-18 23:28:20 +02:00
case ( D_WAVEGUIDE ) :
{
x1 = XMIN + MU ;
x2 = XMAX - 2.0 * MU - 1.5 * LAMBDA ;
y1 = 0.5 * LAMBDA ;
y2 = 1.5 * LAMBDA ;
glLineWidth ( BOUNDARY_WIDTH ) ;
draw_line ( x1 , y1 , x2 , y1 ) ;
draw_line ( x1 , y1 , x1 , y2 ) ;
draw_line ( x1 , y2 , x2 , y2 ) ;
draw_line ( x1 , - y1 , x2 , - y1 ) ;
draw_line ( x1 , - y1 , x1 , - y2 ) ;
draw_line ( x1 , - y2 , x2 , - y2 ) ;
dphi = PI / ( double ) NSEG ;
glBegin ( GL_LINE_STRIP ) ;
for ( i = 0 ; i < NSEG ; i + + )
{
phi = - PID + dphi * ( double ) i ;
x = x2 + y2 * cos ( phi ) ;
y = y2 * sin ( phi ) ;
xy_to_pos ( x , y , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
}
glEnd ( ) ;
glBegin ( GL_LINE_STRIP ) ;
for ( i = 0 ; i < NSEG ; i + + )
{
phi = - PID + dphi * ( double ) i ;
x = x2 + y1 * cos ( phi ) ;
y = y1 * sin ( phi ) ;
xy_to_pos ( x , y , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
}
glEnd ( ) ;
break ;
}
case ( D_WAVEGUIDE_W ) :
{
width = LAMBDA - 2.0 * MU ;
height = 0.5 * MU ;
draw_circle_arc ( 0.0 , height , MU , 0.0 , PI , NSEG ) ;
draw_circle_arc ( 0.0 , height , MU + width , 0.0 , PI , NSEG ) ;
draw_circle_arc ( LAMBDA , - height , MU , PI , PI , NSEG ) ;
draw_circle_arc ( LAMBDA , - height , MU + width , PI , PI , NSEG ) ;
draw_circle_arc ( - LAMBDA , - height , MU , PI , PI , NSEG ) ;
draw_circle_arc ( - LAMBDA , - height , MU + width , PI , PI , NSEG ) ;
draw_line ( - 2.0 * LAMBDA + MU , - height , - 2.0 * LAMBDA + MU , height + MU + width ) ;
draw_line ( - 2.0 * LAMBDA + MU , height + MU + width , - 2.0 * LAMBDA + MU + width , height + MU + width ) ;
draw_line ( - 2.0 * LAMBDA + MU + width , height + MU + width , - 2.0 * LAMBDA + MU + width , - height ) ;
draw_line ( - MU - width , - height , - MU - width , height ) ;
draw_line ( - MU , - height , - MU , height ) ;
draw_line ( 2.0 * LAMBDA - MU , - height , 2.0 * LAMBDA - MU , height + MU + width ) ;
draw_line ( 2.0 * LAMBDA - MU , height + MU + width , 2.0 * LAMBDA - MU - width , height + MU + width ) ;
draw_line ( 2.0 * LAMBDA - MU - width , height + MU + width , 2.0 * LAMBDA - MU - width , - height ) ;
draw_line ( MU + width , - height , MU + width , height ) ;
draw_line ( MU , - height , MU , height ) ;
break ;
}
2022-03-13 15:29:50 +01:00
case ( D_CIRCLE_SEGMENT ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
glBegin ( GL_LINE_LOOP ) ;
for ( i = 0 ; i < NSEG ; i + + )
{
y = - 0.9 * LAMBDA + ( double ) i * 1.8 * LAMBDA / ( double ) NSEG ;
if ( LAMBDA > 0.0 ) x = sqrt ( LAMBDA * LAMBDA - y * y ) - LAMBDA + MU ;
else x = - sqrt ( LAMBDA * LAMBDA - y * y ) - LAMBDA - MU ;
xy_to_pos ( x , y , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
}
y = 0.9 * LAMBDA ;
if ( LAMBDA > 0.0 ) x = sqrt ( LAMBDA * LAMBDA - y * y ) - LAMBDA + MU ;
else x = - sqrt ( LAMBDA * LAMBDA - y * y ) - LAMBDA - MU ;
xy_to_pos ( x , y , pos ) ;
glVertex2d ( pos [ 0 ] , pos [ 1 ] ) ;
glEnd ( ) ;
break ;
}
2021-07-18 15:06:59 +02:00
case ( D_CIRCLES ) :
{
2021-07-30 10:25:50 +02:00
glLineWidth ( BOUNDARY_WIDTH ) ;
2021-07-18 15:06:59 +02:00
for ( i = 0 ; i < ncircles ; i + + )
2021-11-12 16:22:24 +01:00
if ( circles [ i ] . active ) draw_circle ( circles [ i ] . xc , circles [ i ] . yc , circles [ i ] . radius , NSEG ) ;
2021-07-18 15:06:59 +02:00
break ;
}
2021-10-24 15:20:56 +02:00
case ( D_CIRCLES_IN_RECT ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
for ( i = 0 ; i < ncircles ; i + + )
2021-11-12 16:22:24 +01:00
if ( circles [ i ] . active ) draw_circle ( circles [ i ] . xc , circles [ i ] . yc , circles [ i ] . radius , NSEG ) ;
2021-10-24 15:20:56 +02:00
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 ;
}
2021-11-12 16:22:24 +01:00
case ( D_POLYGONS ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
for ( i = 0 ; i < ncircles ; i + + )
if ( polygons [ i ] . active ) draw_tpolygon ( polygons [ i ] ) ;
break ;
}
2022-10-18 23:28:20 +02:00
case ( D_MAZE ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
if ( fade ) glColor3f ( 0.15 * fade_value , 0.15 * fade_value , 0.15 * fade_value ) ;
else glColor3f ( 0.15 , 0.15 , 0.15 ) ;
for ( i = 0 ; i < npolyrect ; i + + )
draw_filled_rectangle ( polyrect [ i ] . x1 , polyrect [ i ] . y1 , polyrect [ i ] . x2 , polyrect [ i ] . y2 ) ;
break ;
}
case ( D_MAZE_CLOSED ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
if ( fade ) glColor3f ( 0.15 * fade_value , 0.15 * fade_value , 0.15 * fade_value ) ;
else glColor3f ( 0.15 , 0.15 , 0.15 ) ;
for ( i = 0 ; i < npolyrect ; i + + )
draw_filled_rectangle ( polyrect [ i ] . x1 , polyrect [ i ] . y1 , polyrect [ i ] . x2 , polyrect [ i ] . y2 ) ;
break ;
}
2023-01-22 16:49:04 +01:00
case ( D_MAZE_CHANNELS ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
if ( fade ) glColor3f ( 0.15 * fade_value , 0.15 * fade_value , 0.15 * fade_value ) ;
else glColor3f ( 0.15 , 0.15 , 0.15 ) ;
for ( i = 0 ; i < npolyrect ; i + + )
draw_filled_rectangle ( polyrect [ i ] . x1 , polyrect [ i ] . y1 , polyrect [ i ] . x2 , polyrect [ i ] . y2 ) ;
break ;
}
case ( D_MAZE_CIRCULAR ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
if ( fade ) glColor3f ( 0.15 * fade_value , 0.15 * fade_value , 0.15 * fade_value ) ;
else glColor3f ( 0.15 , 0.15 , 0.15 ) ;
/* TODO */
break ;
}
2022-11-20 23:17:39 +01:00
case ( D_CHESSBOARD ) :
{
glLineWidth ( BOUNDARY_WIDTH ) ;
x = 0.5 * LAMBDA ;
while ( x < XMAX )
{
draw_line ( x , YMIN , x , YMAX ) ;
x + = LAMBDA ;
}
x = - 0.5 * LAMBDA ;
while ( x > XMIN )
{
draw_line ( x , YMIN , x , YMAX ) ;
x - = LAMBDA ;
}
y = 0.5 * LAMBDA ;
while ( y < YMAX )
{
draw_line ( XMIN , y , XMAX , y ) ;
y + = LAMBDA ;
}
y = - 0.5 * LAMBDA ;
while ( y > YMIN )
{
draw_line ( XMIN , y , XMAX , y ) ;
y - = LAMBDA ;
}
break ;
}
case ( D_TRIANGLE_TILES ) :
{
if ( first )
{
h = LAMBDA / ( 2.0 * sqrt ( 3.0 ) ) ;
hh = h * 3.0 ;
sqr3 = sqrt ( 3.0 ) ;
first = 0 ;
}
glLineWidth ( BOUNDARY_WIDTH ) ;
y = - h ;
while ( y < YMAX )
{
draw_line ( XMIN , y , XMAX , y ) ;
y + = hh ;
}
y = - h ;
while ( y > YMIN )
{
draw_line ( XMIN , y , XMAX , y ) ;
y - = hh ;
}
x = - 0.5 * LAMBDA ;
y = - h ;
while ( x < 1.5 * XMAX )
{
draw_line ( x - 10.0 , y - 10.0 * sqr3 , x + 10.0 , y + 10.0 * sqr3 ) ;
draw_line ( x - 10.0 , y + 10.0 * sqr3 , x + 10.0 , y - 10.0 * sqr3 ) ;
x + = LAMBDA ;
}
x = - 0.5 * LAMBDA ;
while ( x > 1.5 * XMIN )
{
draw_line ( x - 10.0 , y - 10.0 * sqr3 , x + 10.0 , y + 10.0 * sqr3 ) ;
draw_line ( x - 10.0 , y + 10.0 * sqr3 , x + 10.0 , y - 10.0 * sqr3 ) ;
x - = LAMBDA ;
}
break ;
}
case ( D_HEX_TILES ) :
{
ntiles = ( int ) ( XMAX / LAMBDA ) + 1 ;
for ( i = - ntiles ; i < ntiles ; i + + )
for ( j = - ntiles ; j < ntiles ; j + + )
{
x0 = 3.0 * LAMBDA * ( double ) i ;
y0 = 3.0 * LAMBDA * ( double ) j ;
hex_transfo ( x0 , y0 + LAMBDA , & x , & y ) ;
hex_transfo ( x0 , y0 + 2.0 * LAMBDA , & x1 , & y1 ) ;
draw_line ( x , y , x1 , y1 ) ;
hex_transfo ( x0 + LAMBDA , y0 + 2.0 * LAMBDA , & x2 , & y2 ) ;
draw_line ( x1 , y1 , x2 , y2 ) ;
hex_transfo ( x0 + LAMBDA , y0 + 3.0 * LAMBDA , & x1 , & y1 ) ;
draw_line ( x1 , y1 , x2 , y2 ) ;
hex_transfo ( x0 + 2.0 * LAMBDA , y0 + LAMBDA , & x1 , & y1 ) ;
draw_line ( x1 , y1 , x2 , y2 ) ;
hex_transfo ( x0 + 3.0 * LAMBDA , y0 + LAMBDA , & x2 , & y2 ) ;
draw_line ( x1 , y1 , x2 , y2 ) ;
hex_transfo ( x0 + 2.0 * LAMBDA , y0 , & x2 , & y2 ) ;
draw_line ( x1 , y1 , x2 , y2 ) ;
hex_transfo ( x0 + LAMBDA , y0 , & x1 , & y1 ) ;
draw_line ( x1 , y1 , x2 , y2 ) ;
draw_line ( x1 , y1 , x , y ) ;
hex_transfo ( x0 + 2.0 * LAMBDA , y0 + 3.0 * LAMBDA , & x , & y ) ;
hex_transfo ( x0 + 3.0 * LAMBDA , y0 + 2.0 * LAMBDA , & x1 , & y1 ) ;
draw_line ( x , y , x1 , y1 ) ;
}
break ;
}
2023-01-22 16:49:04 +01:00
case ( D_FUNNELS ) :
{
if ( LAMBDA < 3.0 )
{
xmax = sqrt ( 3.0 - LAMBDA ) ;
for ( j = - 2 ; j < 2 ; j + + )
for ( k = - 1 ; k < = 1 ; k + = 2 )
{
for ( i = 0 ; i < = NSEG ; i + + )
{
x = - xmax + ( 2.0 * xmax ) * ( double ) i / ( double ) NSEG ;
y = ( double ) j * YMAX + MU * x + 0.5 * YMAX * ( 1.0 + 0.25 * ( double ) k * ( 1.0 + LAMBDA + x * x ) ) ;
if ( i > 0 ) draw_line ( x1 , y1 , x , y ) ;
x1 = x ;
y1 = y ;
}
}
}
break ;
}
case ( D_ONE_FUNNEL ) :
{
for ( k = - 1 ; k < 2 ; k + = 2 )
{
x1 = XMIN ;
y1 = ( double ) k * ( MU + LAMBDA * x1 * x1 ) ;
for ( i = 0 ; i < = NSEG ; i + + )
{
x = XMIN + ( XMAX - XMIN ) * ( double ) i / ( double ) NSEG ;
y = ( double ) k * ( MU + LAMBDA * x * x ) ;
draw_line ( x1 , y1 , x , y ) ;
x1 = x ;
y1 = y ;
}
}
break ;
}
case ( D_LENSES_RING ) :
{
if ( first )
{
salpha = DPI / ( double ) NPOLY ;
h = LAMBDA * tan ( PI / ( double ) NPOLY ) ;
if ( h < MU ) ll = sqrt ( MU * MU - h * h ) ;
else ll = 0.0 ;
arcangle = atan ( h / ll ) ;
first = 0 ;
}
for ( i = 0 ; i < NPOLY ; i + + )
{
ca = cos ( ( double ) i * salpha + APOLY * PID ) ;
sa = sin ( ( double ) i * salpha + APOLY * PID ) ;
x = ca * ( LAMBDA - ll ) ;
y = sa * ( LAMBDA - ll ) ;
draw_circle_arc ( x , y , MU , - arcangle + APOLY * PID + ( double ) i * salpha , 2.0 * arcangle , NSEG ) ;
x = ca * ( LAMBDA + ll ) ;
y = sa * ( LAMBDA + ll ) ;
draw_circle_arc ( x , y , MU , PI - arcangle + APOLY * PID + ( double ) i * salpha , 2.0 * arcangle , NSEG ) ;
}
break ;
}
2021-06-20 23:31:23 +02:00
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 ;
}
2021-07-18 15:06:59 +02:00
case ( D_JULIA_INT ) :
2021-06-20 23:31:23 +02:00
{
/* Do nothing */
break ;
}
2021-07-18 15:06:59 +02:00
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 ;
}
2021-06-20 23:31:23 +02:00
case ( D_ANNULUS_HEATED ) :
{
2021-08-15 11:49:37 +02:00
draw_circle ( MU , 0.0 , LAMBDA , NSEG ) ;
draw_circle ( 0.0 , 0.0 , 1.0 , NSEG ) ;
2021-06-20 23:31:23 +02:00
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 ;
}
2021-11-12 16:22:24 +01:00
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 ;
}
2022-06-25 15:49:37 +02:00
case ( D_NOTHING ) :
{
break ;
}
default :
2021-05-29 16:50:49 +02:00
{
printf ( " Function draw_billiard not defined for this billiard \n " ) ;
}
}
}
2021-11-12 16:22:24 +01:00
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 ;
2023-01-22 16:49:04 +01:00
double y , dy , dy_e , rgb [ 3 ] , value , lum , amp , dy_phase ;
2021-11-12 16:22:24 +01:00
xy_to_ij ( x1 , y1 , ij_botleft ) ;
xy_to_ij ( x2 , y2 , ij_topright ) ;
2022-02-05 18:44:39 +01:00
rgb [ 0 ] = 0.0 ; rgb [ 1 ] = 0.0 ; rgb [ 2 ] = 0.0 ;
erase_area_rgb ( 0.5 * ( x1 + x2 ) , x2 - x1 , 0.5 * ( y1 + y2 ) , y2 - y1 , rgb ) ;
2021-11-12 16:22:24 +01:00
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 ) ) ;
2023-01-22 16:49:04 +01:00
dy_phase = 1.0 / ( ( double ) ( jmax - jmin ) ) ;
2021-11-12 16:22:24 +01:00
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 ;
}
2021-12-28 15:42:56 +01:00
case ( P_LOG_ENERGY ) :
{
2022-02-05 18:44:39 +01:00
value = LOG_SHIFT + LOG_SCALE * log ( dy_e * ( double ) ( j - jmin ) * 100.0 / E_SCALE ) ;
// if (value <= 0.0) value = 0.0;
2021-12-28 15:42:56 +01:00
color_scheme ( COLOR_SCHEME , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_LOG_MEAN_ENERGY ) :
{
2022-02-05 18:44:39 +01:00
value = LOG_SHIFT + LOG_SCALE * log ( dy_e * ( double ) ( j - jmin ) * 100.0 / E_SCALE ) ;
// if (value <= 0.0) value = 0.0;
2021-12-28 15:42:56 +01:00
color_scheme ( COLOR_SCHEME , value , 1.0 , 1 , rgb ) ;
break ;
}
2022-11-20 23:17:39 +01:00
case ( P_ENERGY_FLUX ) :
{
value = dy_e * ( double ) ( j - jmin ) * 100.0 / E_SCALE ;
if ( COLOR_PALETTE > = COL_TURBO ) color_scheme_asym_palette ( COLOR_SCHEME , COLOR_PALETTE , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , COLOR_PALETTE , value , 1.0 , 1 , rgb ) ;
// value = min + 1.0*dy*(double)(j - jmin);
// amp = 0.7*color_amplitude_linear(value, 1.0, 1);
// while (amp > 1.0) amp -= 2.0;
// while (amp < -1.0) amp += 2.0;
// amp_to_rgb(0.5*(1.0 + amp), rgb);
break ;
}
case ( P_TOTAL_ENERGY_FLUX ) :
{
2023-01-22 16:49:04 +01:00
// value = min + 1.0*dy*(double)(j - jmin);
// amp = 0.7*color_amplitude_linear(value, 1.0, 1);
// while (amp > 1.0) amp -= 2.0;
// while (amp < -1.0) amp += 2.0;
// amp_to_rgb(0.5*(1.0 + amp), rgb);
value = dy_phase * ( double ) ( j - jmin ) ;
color_scheme_palette ( C_ONEDIM_LINEAR , COLOR_PALETTE , value , 1.0 , 1 , rgb ) ;
2022-11-20 23:17:39 +01:00
break ;
}
2021-11-12 16:22:24 +01:00
case ( P_PHASE ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
2022-02-05 18:44:39 +01:00
// lum = (color_amplitude(value, 1.0, 1))*0.5;
// if (lum < 0.0) lum = 0.0;
2022-03-13 15:29:50 +01:00
// hsl_to_rgb(value*360.0, 0.9, 0.5, rgb);
// color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
// amp = color_amplitude_linear(value, 1.0, 1);
amp = 0.5 * color_amplitude_linear ( value , 1.0 , 1 ) ;
while ( amp > 1.0 ) amp - = 2.0 ;
while ( amp < - 1.0 ) amp + = 2.0 ;
amp_to_rgb ( 0.5 * ( 1.0 + amp ) , 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 ) ;
}
void draw_color_scheme_palette ( double x1 , double y1 , double x2 , double y2 , int plot , double min , double max , int palette )
{
int j , k , ij_botleft [ 2 ] , ij_topright [ 2 ] , imin , imax , jmin , jmax ;
2023-01-22 16:49:04 +01:00
double y , dy , dy_e , rgb [ 3 ] , value , lum , amp , dy_phase ;
2022-03-13 15:29:50 +01:00
xy_to_ij ( x1 , y1 , ij_botleft ) ;
xy_to_ij ( x2 , y2 , ij_topright ) ;
rgb [ 0 ] = 0.0 ; rgb [ 1 ] = 0.0 ; rgb [ 2 ] = 0.0 ;
2022-08-20 16:02:07 +02:00
// erase_area_rgb(0.5*(x1 + x2), x2 - x1, 0.5*(y1 + y2), y2 - y1, rgb);
2022-03-13 15:29:50 +01:00
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 ) ) ;
2023-01-22 16:49:04 +01:00
dy_phase = 1.0 / ( ( double ) ( jmax - jmin ) ) ;
2022-03-13 15:29:50 +01:00
for ( j = jmin ; j < jmax ; j + + )
{
switch ( plot ) {
case ( P_AMPLITUDE ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 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_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , palette , 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_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_LOG_ENERGY ) :
{
2023-03-25 19:56:19 +01:00
value = LOG_SCALE * log ( dy_e * ( double ) ( j - jmin ) * 100.0 / E_SCALE ) ;
2022-03-13 15:29:50 +01:00
// if (value <= 0.0) value = 0.0;
color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_LOG_MEAN_ENERGY ) :
{
value = LOG_SHIFT + LOG_SCALE * log ( dy_e * ( double ) ( j - jmin ) * 100.0 / E_SCALE ) ;
// if (value <= 0.0) value = 0.0;
color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
2022-11-20 23:17:39 +01:00
case ( P_ENERGY_FLUX ) :
{
value = dy_e * ( double ) ( j - jmin ) * 100.0 / E_SCALE ;
if ( COLOR_PALETTE > = COL_TURBO ) color_scheme_asym_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
// value = min + 1.0*dy*(double)(j - jmin);
// amp = 0.7*color_amplitude_linear(value, 1.0, 1);
// while (amp > 1.0) amp -= 2.0;
// while (amp < -1.0) amp += 2.0;
// amp_to_rgb(0.5*(1.0 + amp), rgb);
break ;
}
case ( P_TOTAL_ENERGY_FLUX ) :
{
2023-01-22 16:49:04 +01:00
// value = min + 1.0*dy*(double)(j - jmin);
// amp = 0.7*color_amplitude_linear(value, 1.0, 1);
// while (amp > 1.0) amp -= 2.0;
// while (amp < -1.0) amp += 2.0;
// amp_to_rgb(0.5*(1.0 + amp), rgb);
value = dy_phase * ( double ) ( j - jmin ) ;
color_scheme_palette ( C_ONEDIM_LINEAR , palette , value , 1.0 , 1 , rgb ) ;
2022-11-20 23:17:39 +01:00
break ;
}
2022-03-13 15:29:50 +01:00
case ( P_PHASE ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
// lum = (color_amplitude(value, 1.0, 1))*0.5;
// if (lum < 0.0) lum = 0.0;
2022-02-05 18:44:39 +01:00
// hsl_to_rgb(value*360.0, 0.9, 0.5, rgb);
// color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
// amp = color_amplitude_linear(value, 1.0, 1);
amp = 0.5 * color_amplitude_linear ( value , 1.0 , 1 ) ;
while ( amp > 1.0 ) amp - = 2.0 ;
while ( amp < - 1.0 ) amp + = 2.0 ;
amp_to_rgb ( 0.5 * ( 1.0 + amp ) , rgb ) ;
2021-11-12 16:22:24 +01:00
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 ) ;
}
2022-06-25 15:49:37 +02:00
void draw_color_scheme_palette_fade ( double x1 , double y1 , double x2 , double y2 , int plot , double min , double max , int palette , int fade , double fade_value )
{
int j , k , ij_botleft [ 2 ] , ij_topright [ 2 ] , imin , imax , jmin , jmax ;
2023-01-22 16:49:04 +01:00
double y , dy , dy_e , rgb [ 3 ] , value , lum , amp , dy_phase ;
2022-06-25 15:49:37 +02:00
xy_to_ij ( x1 , y1 , ij_botleft ) ;
xy_to_ij ( x2 , y2 , ij_topright ) ;
rgb [ 0 ] = 0.0 ; rgb [ 1 ] = 0.0 ; rgb [ 2 ] = 0.0 ;
2022-08-20 16:02:07 +02:00
// erase_area_rgb(0.5*(x1 + x2), x2 - x1, 0.5*(y1 + y2), y2 - y1, rgb);
2022-06-25 15:49:37 +02:00
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 ) ) ;
2023-01-22 16:49:04 +01:00
dy_phase = 1.0 / ( ( double ) ( jmax - jmin ) ) ;
2022-06-25 15:49:37 +02:00
for ( j = jmin ; j < jmax ; j + + )
{
switch ( plot ) {
case ( P_AMPLITUDE ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 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_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , palette , 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_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_LOG_ENERGY ) :
{
2023-03-25 19:56:19 +01:00
value = LOG_SCALE * log ( dy_e * ( double ) ( j - jmin ) * 100.0 / E_SCALE ) ;
2022-11-20 23:17:39 +01:00
// printf("value = %.2lg\n", value);
2022-06-25 15:49:37 +02:00
// if (value <= 0.0) value = 0.0;
color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_LOG_MEAN_ENERGY ) :
{
value = LOG_SHIFT + LOG_SCALE * log ( dy_e * ( double ) ( j - jmin ) * 100.0 / E_SCALE ) ;
// if (value <= 0.0) value = 0.0;
color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
2022-11-20 23:17:39 +01:00
case ( P_ENERGY_FLUX ) :
{
value = dy_e * ( double ) ( j - jmin ) ;
if ( COLOR_PALETTE > = COL_TURBO ) color_scheme_asym_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
// value = min + 1.0*dy*(double)(j - jmin);
// amp = 0.7*color_amplitude_linear(value, 1.0, 1);
// while (amp > 1.0) amp -= 2.0;
// while (amp < -1.0) amp += 2.0;
// amp_to_rgb(0.5*(1.0 + amp), rgb);
break ;
}
case ( P_TOTAL_ENERGY_FLUX ) :
{
2023-01-22 16:49:04 +01:00
// value = min + 1.0*dy*(double)(j - jmin);
// amp = 0.7*color_amplitude_linear(value, 1.0, 1);
// while (amp > 1.0) amp -= 2.0;
// while (amp < -1.0) amp += 2.0;
// amp_to_rgb(0.5*(1.0 + amp), rgb);
value = dy_phase * ( double ) ( j - jmin ) ;
color_scheme_palette ( C_ONEDIM_LINEAR , palette , value , 1.0 , 1 , rgb ) ;
2022-11-20 23:17:39 +01:00
break ;
}
2022-06-25 15:49:37 +02:00
case ( P_PHASE ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
// lum = (color_amplitude(value, 1.0, 1))*0.5;
// if (lum < 0.0) lum = 0.0;
// hsl_to_rgb(value*360.0, 0.9, 0.5, rgb);
// color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
// amp = color_amplitude_linear(value, 1.0, 1);
amp = 0.5 * color_amplitude_linear ( value , 1.0 , 1 ) ;
while ( amp > 1.0 ) amp - = 2.0 ;
while ( amp < - 1.0 ) amp + = 2.0 ;
amp_to_rgb ( 0.5 * ( 1.0 + amp ) , rgb ) ;
break ;
}
2023-01-22 16:49:04 +01:00
case ( Z_EULER_VORTICITY ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_LOG_VORTICITY ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_VORTICITY_ASYM ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_LPRESSURE ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_PRESSURE ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_DENSITY ) :
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_SPEED ) :
2022-10-18 23:28:20 +02:00
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
2023-01-22 16:49:04 +01:00
case ( Z_EULERC_VORTICITY ) :
2022-10-18 23:28:20 +02:00
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
2023-01-22 16:49:04 +01:00
default :
2022-10-18 23:28:20 +02:00
{
value = min + 1.0 * dy * ( double ) ( j - jmin ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
2022-06-25 15:49:37 +02:00
}
if ( fade ) for ( k = 0 ; k < 3 ; k + + ) rgb [ k ] * = fade_value ;
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 ( ) ;
if ( fade ) glColor3f ( fade_value , fade_value , fade_value ) ;
else glColor3f ( 1.0 , 1.0 , 1.0 ) ;
glLineWidth ( BOUNDARY_WIDTH ) ;
draw_rectangle ( x1 , y1 , x2 , y2 ) ;
}
2021-11-12 16:22:24 +01:00
2022-08-20 16:02:07 +02:00
2023-07-08 23:28:23 +02:00
void draw_circular_color_scheme_palette_fade ( double x1 , double y1 , double radius , int plot , double min , double max , int palette , int fade , double fade_value )
{
int j , k ;
double x , y , dy , dy_e , dy_phase , rgb [ 3 ] , value , lum , amp , dphi , pos [ 2 ] , phi , xy [ 2 ] ;
glBegin ( GL_TRIANGLE_FAN ) ;
xy_to_pos ( x1 , y1 , xy ) ;
glVertex2d ( xy [ 0 ] , xy [ 1 ] ) ;
dy = ( max - min ) / 360.0 ;
dy_e = max / 360.0 ;
dy_phase = 1.0 / 360.0 ;
dphi = DPI / 360.0 ;
for ( j = 0 ; j < = 360 ; j + + )
{
switch ( plot ) {
case ( P_AMPLITUDE ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_ENERGY ) :
{
value = dy_e * ( double ) ( j ) * 100.0 / E_SCALE ;
if ( COLOR_PALETTE > = COL_TURBO ) color_scheme_asym_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_MEAN_ENERGY ) :
{
value = dy_e * ( double ) ( j ) * 100.0 / E_SCALE ;
if ( COLOR_PALETTE > = COL_TURBO ) color_scheme_asym_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_LOG_ENERGY ) :
{
value = LOG_SCALE * log ( dy_e * ( double ) ( j ) * 100.0 / E_SCALE ) ;
color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_LOG_MEAN_ENERGY ) :
{
value = LOG_SHIFT + LOG_SCALE * log ( dy_e * ( double ) ( j ) * 100.0 / E_SCALE ) ;
color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_ENERGY_FLUX ) :
{
value = dy_e * ( double ) ( j ) ;
if ( COLOR_PALETTE > = COL_TURBO ) color_scheme_asym_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
else color_scheme_palette ( COLOR_SCHEME , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_TOTAL_ENERGY_FLUX ) :
{
value = dy_phase * ( double ) ( j ) ;
color_scheme_palette ( C_ONEDIM_LINEAR , palette , value , 1.0 , 1 , rgb ) ;
break ;
}
case ( P_PHASE ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
amp = 0.5 * color_amplitude_linear ( value , 1.0 , 1 ) ;
while ( amp > 1.0 ) amp - = 2.0 ;
while ( amp < - 1.0 ) amp + = 2.0 ;
amp_to_rgb ( 0.5 * ( 1.0 + amp ) , rgb ) ;
break ;
}
case ( Z_EULER_VORTICITY ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_LOG_VORTICITY ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_VORTICITY_ASYM ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_LPRESSURE ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_PRESSURE ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_DENSITY ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULER_SPEED ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
case ( Z_EULERC_VORTICITY ) :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
default :
{
value = min + 1.0 * dy * ( double ) ( j ) ;
color_scheme_palette ( COLOR_SCHEME , palette , 0.7 * value , 1.0 , 0 , rgb ) ;
break ;
}
}
if ( fade ) for ( k = 0 ; k < 3 ; k + + ) rgb [ k ] * = fade_value ;
glColor3f ( rgb [ 0 ] , rgb [ 1 ] , rgb [ 2 ] ) ;
xy_to_pos ( x1 + radius * cos ( dphi * ( double ) j ) , y1 + radius * sin ( dphi * ( double ) j ) , xy ) ;
glVertex2d ( xy [ 0 ] , xy [ 1 ] ) ;
}
xy_to_pos ( x1 + radius * cos ( dphi ) , y1 + radius * sin ( dphi ) , xy ) ;
glVertex2d ( xy [ 0 ] , xy [ 1 ] ) ;
glEnd ( ) ;
if ( fade ) glColor3f ( fade_value , fade_value , fade_value ) ;
else glColor3f ( 1.0 , 1.0 , 1.0 ) ;
glLineWidth ( BOUNDARY_WIDTH * 3 / 2 ) ;
glEnable ( GL_LINE_SMOOTH ) ;
dphi = DPI / ( double ) NSEG ;
glBegin ( GL_LINE_LOOP ) ;
for ( j = 0 ; j < NSEG ; j + + )
{
xy_to_pos ( x1 + radius * cos ( dphi * ( double ) j ) , y1 + radius * sin ( dphi * ( double ) j ) , xy ) ;
glVertex2d ( xy [ 0 ] , xy [ 1 ] ) ;
glVertex2d ( xy [ 0 ] , xy [ 1 ] ) ;
}
glEnd ( ) ;
}
2022-08-20 16:02:07 +02:00
void print_speed ( double speed , int fade , double fade_value )
{
char message [ 100 ] ;
double y = YMAX - 0.1 , pos [ 2 ] ;
static double xleftbox , xlefttext ;
static int first = 1 ;
if ( first )
{
xleftbox = XMIN + 0.3 ;
xlefttext = xleftbox - 0.45 ;
first = 0 ;
}
erase_area_hsl ( xleftbox , y + 0.025 , 0.22 , 0.05 , 0.0 , 0.9 , 0.0 ) ;
if ( fade ) glColor3f ( fade_value , fade_value , fade_value ) ;
else glColor3f ( 1.0 , 1.0 , 1.0 ) ;
xy_to_pos ( xlefttext + 0.28 , y , pos ) ;
sprintf ( message , " Mach %.3lg " , speed ) ;
write_text ( pos [ 0 ] , pos [ 1 ] , message ) ;
}
2023-04-30 17:01:39 +02:00
void print_frequency ( double phase_shift , int fade , double fade_value )
{
char message [ 100 ] ;
double y = YMAX - 0.1 , pos [ 2 ] ;
static double xleftbox , xlefttext ;
static int first = 1 ;
if ( first )
{
xleftbox = XMIN + 0.3 ;
xlefttext = xleftbox - 0.45 ;
first = 0 ;
}
erase_area_hsl ( xleftbox , y + 0.025 , 0.22 , 0.05 , 0.0 , 0.9 , 0.0 ) ;
if ( fade ) glColor3f ( fade_value , fade_value , fade_value ) ;
else glColor3f ( 1.0 , 1.0 , 1.0 ) ;
xy_to_pos ( xlefttext + 0.28 , y , pos ) ;
sprintf ( message , " Frequency %.2f " , 25.0 * phase_shift ) ;
write_text ( pos [ 0 ] , pos [ 1 ] , message ) ;
}
2022-08-20 16:02:07 +02:00
void init_laplacian_coords ( t_laplacian laplace [ NX * NY ] , double phi [ NX * NY ] )
/* compute coordinates of neighbours to compute Laplacian */
{
int i , j , iplus , iminus , i1 , i2 , i3 , j1 , j2 , j3 , ij [ 2 ] ; ;
printf ( " Initialising Laplacian table \n " ) ;
/* Laplacian in the bulk */
# pragma omp parallel for private(i,j)
for ( i = 1 ; i < NX - 1 ; i + + ) {
for ( j = 1 ; j < NY - 1 ; j + + ) {
laplace [ i * NY + j ] . nneighb = 4 ;
laplace [ i * NY + j ] . nghb [ 0 ] = & phi [ ( i + 1 ) * NY + j ] ;
laplace [ i * NY + j ] . nghb [ 1 ] = & phi [ ( i - 1 ) * NY + j ] ;
laplace [ i * NY + j ] . nghb [ 2 ] = & phi [ i * NY + j + 1 ] ;
laplace [ i * NY + j ] . nghb [ 3 ] = & phi [ i * NY + j - 1 ] ;
}
}
switch ( B_COND ) {
case ( BC_DIRICHLET ) :
{
/* left boundary */
# pragma omp parallel for private(j)
for ( j = 1 ; j < NY - 1 ; j + + )
{
laplace [ j ] . nneighb = 3 ;
laplace [ j ] . nghb [ 0 ] = & phi [ NY + j ] ;
laplace [ j ] . nghb [ 1 ] = & phi [ j + 1 ] ;
laplace [ j ] . nghb [ 2 ] = & phi [ j - 1 ] ;
}
/* right boundary */
# pragma omp parallel for private(j)
for ( j = 1 ; j < NY - 1 ; j + + )
{
laplace [ ( NX - 1 ) * NY + j ] . nneighb = 3 ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 0 ] = & phi [ ( NX - 2 ) * NY + j ] ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 1 ] = & phi [ ( NX - 1 ) * NY + j + 1 ] ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 2 ] = & phi [ ( NX - 1 ) * NY + j - 1 ] ;
}
/* top boundary */
# pragma omp parallel for private(i,iplus,iminus)
for ( i = 0 ; i < NX ; i + + )
{
iplus = i + 1 ; if ( iplus = = NX ) iplus = NX - 1 ;
iminus = i - 1 ; if ( iminus = = - 1 ) iminus = 0 ;
laplace [ i * NY + NY - 1 ] . nneighb = 3 ;
laplace [ i * NY + NY - 1 ] . nghb [ 0 ] = & phi [ iplus * NY + NY - 1 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 1 ] = & phi [ iminus * NY + NY - 1 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 2 ] = & phi [ i * NY + NY - 2 ] ;
}
/* bottom boundary */
# pragma omp parallel for private(i,iplus,iminus)
for ( i = 0 ; i < NX ; i + + )
{
iplus = i + 1 ; if ( iplus = = NX ) iplus = NX - 1 ;
iminus = i - 1 ; if ( iminus = = - 1 ) iminus = 0 ;
laplace [ i * NY ] . nneighb = 3 ;
laplace [ i * NY ] . nghb [ 0 ] = & phi [ iplus * NY ] ;
laplace [ i * NY ] . nghb [ 1 ] = & phi [ iminus * NY ] ;
laplace [ i * NY ] . nghb [ 2 ] = & phi [ i * NY + 1 ] ;
}
break ;
}
case ( BC_PERIODIC ) :
{
/* left boundary */
# pragma omp parallel for private(j)
for ( j = 1 ; j < NY - 1 ; j + + )
{
laplace [ j ] . nneighb = 4 ;
laplace [ j ] . nghb [ 0 ] = & phi [ NY + j ] ;
laplace [ j ] . nghb [ 1 ] = & phi [ ( NX - 1 ) * NY + j ] ;
laplace [ j ] . nghb [ 2 ] = & phi [ j + 1 ] ;
laplace [ j ] . nghb [ 3 ] = & phi [ j - 1 ] ;
}
/* right boundary */
# pragma omp parallel for private(j)
for ( j = 1 ; j < NY - 1 ; j + + )
{
laplace [ ( NX - 1 ) * NY + j ] . nneighb = 4 ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 0 ] = & phi [ ( NX - 2 ) * NY + j ] ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 1 ] = & phi [ j ] ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 2 ] = & phi [ ( NX - 1 ) * NY + j + 1 ] ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 3 ] = & phi [ ( NX - 1 ) * NY + j - 1 ] ;
}
/* top boundary */
# pragma omp parallel for private(i,iplus,iminus)
for ( i = 0 ; i < NX ; i + + )
{
iplus = ( i + 1 ) % NX ;
iminus = ( i - 1 ) % NX ;
if ( iminus < 0 ) iminus + = NX ;
laplace [ i * NY + NY - 1 ] . nneighb = 4 ;
laplace [ i * NY + NY - 1 ] . nghb [ 0 ] = & phi [ iplus * NY + NY - 1 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 1 ] = & phi [ iminus * NY + NY - 1 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 2 ] = & phi [ i * NY + NY - 2 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 3 ] = & phi [ i * NY ] ;
}
/* bottom boundary */
# pragma omp parallel for private(i,iplus,iminus)
for ( i = 0 ; i < NX ; i + + )
{
iplus = ( i + 1 ) % NX ;
iminus = ( i - 1 ) % NX ;
if ( iminus < 0 ) iminus + = NX ;
laplace [ i * NY ] . nneighb = 4 ;
laplace [ i * NY ] . nghb [ 0 ] = & phi [ iplus * NY ] ;
laplace [ i * NY ] . nghb [ 1 ] = & phi [ iminus * NY ] ;
laplace [ i * NY ] . nghb [ 2 ] = & phi [ i * NY + 1 ] ;
laplace [ i * NY ] . nghb [ 3 ] = & phi [ i * NY + NY - 1 ] ;
}
break ;
}
case ( BC_ABSORBING ) :
{
/* left boundary */
# pragma omp parallel for private(j)
for ( j = 1 ; j < NY - 1 ; j + + )
{
laplace [ j ] . nneighb = 3 ;
laplace [ j ] . nghb [ 0 ] = & phi [ NY + j ] ;
laplace [ j ] . nghb [ 1 ] = & phi [ j + 1 ] ;
laplace [ j ] . nghb [ 2 ] = & phi [ j - 1 ] ;
}
/* right boundary */
# pragma omp parallel for private(j)
for ( j = 1 ; j < NY - 1 ; j + + )
{
laplace [ ( NX - 1 ) * NY + j ] . nneighb = 3 ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 0 ] = & phi [ ( NX - 2 ) * NY + j ] ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 1 ] = & phi [ ( NX - 1 ) * NY + j + 1 ] ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 2 ] = & phi [ ( NX - 1 ) * NY + j - 1 ] ;
}
/* top boundary */
# pragma omp parallel for private(i,iplus,iminus)
for ( i = 0 ; i < NX ; i + + )
{
iplus = ( i + 1 ) ; if ( iplus = = NX ) iplus = NX - 1 ;
iminus = ( i - 1 ) ; if ( iminus = = - 1 ) iminus = 0 ;
laplace [ i * NY + NY - 1 ] . nneighb = 3 ;
laplace [ i * NY + NY - 1 ] . nghb [ 0 ] = & phi [ iplus * NY + NY - 1 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 1 ] = & phi [ iminus * NY + NY - 1 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 2 ] = & phi [ i * NY + NY - 2 ] ;
}
/* bottom boundary */
# pragma omp parallel for private(i,iplus,iminus)
for ( i = 0 ; i < NX ; i + + )
{
iplus = ( i + 1 ) ; if ( iplus = = NX ) iplus = NX - 1 ;
iminus = ( i - 1 ) ; if ( iminus = = - 1 ) iminus = 0 ;
laplace [ i * NY ] . nneighb = 3 ;
laplace [ i * NY ] . nghb [ 0 ] = & phi [ iplus * NY ] ;
laplace [ i * NY ] . nghb [ 1 ] = & phi [ iminus * NY ] ;
laplace [ i * NY ] . nghb [ 2 ] = & phi [ i * NY + 1 ] ;
}
break ;
}
case ( BC_VPER_HABS ) :
{
/* left boundary */
# pragma omp parallel for private(j)
for ( j = 1 ; j < NY - 1 ; j + + )
{
laplace [ j ] . nneighb = 3 ;
laplace [ j ] . nghb [ 0 ] = & phi [ NY + j ] ;
laplace [ j ] . nghb [ 1 ] = & phi [ j + 1 ] ;
laplace [ j ] . nghb [ 2 ] = & phi [ j - 1 ] ;
}
/* right boundary */
# pragma omp parallel for private(j)
for ( j = 1 ; j < NY - 1 ; j + + )
{
laplace [ ( NX - 1 ) * NY + j ] . nneighb = 3 ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 0 ] = & phi [ ( NX - 2 ) * NY + j ] ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 1 ] = & phi [ ( NX - 1 ) * NY + j + 1 ] ;
laplace [ ( NX - 1 ) * NY + j ] . nghb [ 2 ] = & phi [ ( NX - 1 ) * NY + j - 1 ] ;
}
/* top boundary */
# pragma omp parallel for private(i,iplus,iminus)
for ( i = 0 ; i < NX ; i + + )
{
iplus = ( i + 1 ) ; if ( iplus = = NX ) iplus = NX - 1 ;
iminus = ( i - 1 ) ; if ( iminus = = - 1 ) iminus = 0 ;
laplace [ i * NY + NY - 1 ] . nneighb = 4 ;
laplace [ i * NY + NY - 1 ] . nghb [ 0 ] = & phi [ iplus * NY + NY - 1 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 1 ] = & phi [ iminus * NY + NY - 1 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 2 ] = & phi [ i * NY + NY - 2 ] ;
laplace [ i * NY + NY - 1 ] . nghb [ 3 ] = & phi [ i * NY ] ;
}
/* bottom boundary */
# pragma omp parallel for private(i,iplus,iminus)
for ( i = 0 ; i < NX ; i + + )
{
iplus = ( i + 1 ) ; if ( iplus = = NX ) iplus = NX - 1 ;
iminus = ( i - 1 ) ; if ( iminus = = - 1 ) iminus = 0 ;
laplace [ i * NY ] . nneighb = 4 ;
laplace [ i * NY ] . nghb [ 0 ] = & phi [ iplus * NY ] ;
laplace [ i * NY ] . nghb [ 1 ] = & phi [ iminus * NY ] ;
laplace [ i * NY ] . nghb [ 2 ] = & phi [ i * NY + 1 ] ;
laplace [ i * NY ] . nghb [ 3 ] = & phi [ i * NY + NY - 1 ] ;
}
break ;
}
case ( BC_LSHAPE ) :
{
/* boundaries */
xy_to_ij ( - LAMBDA , - 1.0 , ij ) ;
i1 = ij [ 0 ] + 1 ; j1 = ij [ 1 ] + 1 ;
xy_to_ij ( 0.0 , 0.0 , ij ) ;
i2 = ij [ 0 ] - 1 ; j2 = ij [ 1 ] - 1 ;
xy_to_ij ( LAMBDA , 1.0 , ij ) ;
i3 = ij [ 0 ] - 1 ; j3 = ij [ 1 ] - 1 ;
printf ( " L shape corners (%i,%i), (%i,%i), (%i,%i) \n " , i1 , j1 , i2 , j2 , i3 , j3 ) ;
/* left boundary */
# pragma omp parallel for private(j)
for ( j = j1 + 1 ; j < j2 ; j + + )
{
laplace [ i1 * NY + j ] . nneighb = 4 ;
laplace [ i1 * NY + j ] . nghb [ 0 ] = & phi [ ( i1 + 1 ) * NY + j ] ;
laplace [ i1 * NY + j ] . nghb [ 1 ] = & phi [ ( i3 ) * NY + j ] ;
laplace [ i1 * NY + j ] . nghb [ 2 ] = & phi [ i1 * NY + j + 1 ] ;
laplace [ i1 * NY + j ] . nghb [ 3 ] = & phi [ i1 * NY + j - 1 ] ;
}
# pragma omp parallel for private(j)
for ( j = j2 ; j < j3 - 1 ; j + + )
{
laplace [ i1 * NY + j ] . nneighb = 4 ;
laplace [ i1 * NY + j ] . nghb [ 0 ] = & phi [ ( i1 + 1 ) * NY + j ] ;
laplace [ i1 * NY + j ] . nghb [ 1 ] = & phi [ ( i2 - 1 ) * NY + j ] ;
laplace [ i1 * NY + j ] . nghb [ 2 ] = & phi [ i1 * NY + j + 1 ] ;
laplace [ i1 * NY + j ] . nghb [ 3 ] = & phi [ i1 * NY + j - 1 ] ;
}
/* right boundary */
# pragma omp parallel for private(j)
for ( j = j1 + 1 ; j < j2 ; j + + )
{
laplace [ ( i3 ) * NY + j ] . nneighb = 4 ;
laplace [ ( i3 ) * NY + j ] . nghb [ 0 ] = & phi [ i1 * NY + j ] ;
laplace [ ( i3 ) * NY + j ] . nghb [ 1 ] = & phi [ ( i3 - 1 ) * NY + j ] ;
laplace [ ( i3 ) * NY + j ] . nghb [ 2 ] = & phi [ ( i3 ) * NY + j + 1 ] ;
laplace [ ( i3 ) * NY + j ] . nghb [ 3 ] = & phi [ ( i3 ) * NY + j - 1 ] ;
}
# pragma omp parallel for private(j)
for ( j = j2 ; j < j3 - 1 ; j + + )
{
laplace [ ( i2 ) * NY + j ] . nneighb = 4 ;
laplace [ ( i2 ) * NY + j ] . nghb [ 0 ] = & phi [ i1 * NY + j ] ;
laplace [ ( i2 ) * NY + j ] . nghb [ 1 ] = & phi [ ( i2 - 1 ) * NY + j ] ;
laplace [ ( i2 ) * NY + j ] . nghb [ 2 ] = & phi [ ( i2 ) * NY + j + 1 ] ;
laplace [ ( i2 ) * NY + j ] . nghb [ 3 ] = & phi [ ( i2 ) * NY + j - 1 ] ;
}
/* top boundary */
# pragma omp parallel for private(i)
for ( i = i1 ; i < i2 ; i + + )
{
laplace [ i * NY + j3 ] . nneighb = 4 ;
laplace [ i * NY + j3 ] . nghb [ 0 ] = & phi [ ( i + 1 ) * NY + j3 ] ;
laplace [ i * NY + j3 ] . nghb [ 1 ] = & phi [ ( i - 1 ) * NY + j3 ] ;
laplace [ i * NY + j3 ] . nghb [ 2 ] = & phi [ i * NY + j1 ] ;
laplace [ i * NY + j3 ] . nghb [ 3 ] = & phi [ i * NY + j3 - 1 ] ;
}
# pragma omp parallel for private(i)
for ( i = i2 ; i < i3 ; i + + )
{
laplace [ i * NY + j2 ] . nneighb = 4 ;
laplace [ i * NY + j2 ] . nghb [ 0 ] = & phi [ ( i + 1 ) * NY + j2 ] ;
laplace [ i * NY + j2 ] . nghb [ 1 ] = & phi [ ( i - 1 ) * NY + j2 ] ;
laplace [ i * NY + j2 ] . nghb [ 2 ] = & phi [ i * NY + j1 ] ;
laplace [ i * NY + j2 ] . nghb [ 3 ] = & phi [ i * NY + j2 - 1 ] ;
}
/* bottom boundary */
# pragma omp parallel for private(i)
for ( i = i1 ; i < i2 ; i + + )
{
laplace [ i * NY + j1 ] . nneighb = 4 ;
laplace [ i * NY + j1 ] . nghb [ 0 ] = & phi [ ( i + 1 ) * NY + j1 ] ;
laplace [ i * NY + j1 ] . nghb [ 1 ] = & phi [ ( i - 1 ) * NY + j1 ] ;
laplace [ i * NY + j1 ] . nghb [ 2 ] = & phi [ i * NY + j1 + 1 ] ;
laplace [ i * NY + j1 ] . nghb [ 3 ] = & phi [ i * NY + j3 ] ;
}
# pragma omp parallel for private(i)
for ( i = i2 ; i < i3 ; i + + )
{
laplace [ i * NY + j1 ] . nneighb = 4 ;
laplace [ i * NY + j1 ] . nghb [ 0 ] = & phi [ ( i + 1 ) * NY + j1 ] ;
laplace [ i * NY + j1 ] . nghb [ 1 ] = & phi [ ( i - 1 ) * NY + j1 ] ;
laplace [ i * NY + j1 ] . nghb [ 2 ] = & phi [ i * NY + j1 + 1 ] ;
laplace [ i * NY + j1 ] . nghb [ 3 ] = & phi [ i * NY + j2 ] ;
}
/* corners */
laplace [ i1 * NY + j1 ] . nneighb = 4 ;
laplace [ i1 * NY + j1 ] . nghb [ 0 ] = & phi [ ( i1 + 1 ) * NY + j1 ] ;
laplace [ i1 * NY + j1 ] . nghb [ 1 ] = & phi [ ( i3 - 1 ) * NY + j1 ] ;
laplace [ i1 * NY + j1 ] . nghb [ 2 ] = & phi [ i1 * NY + j1 + 1 ] ;
laplace [ i1 * NY + j1 ] . nghb [ 3 ] = & phi [ i1 * NY + j3 - 1 ] ;
laplace [ ( i3 ) * NY + j1 ] . nneighb = 4 ;
laplace [ ( i3 ) * NY + j1 ] . nghb [ 0 ] = & phi [ i1 * NY + j1 ] ;
laplace [ ( i3 ) * NY + j1 ] . nghb [ 1 ] = & phi [ ( i3 - 1 ) * NY + j1 ] ;
laplace [ ( i3 ) * NY + j1 ] . nghb [ 2 ] = & phi [ ( i3 ) * NY + j1 + 1 ] ;
laplace [ ( i3 ) * NY + j1 ] . nghb [ 3 ] = & phi [ ( i3 ) * NY + j3 ] ;
laplace [ i1 * NY + j3 ] . nneighb = 4 ;
laplace [ i1 * NY + j3 ] . nghb [ 0 ] = & phi [ ( i1 + 1 ) * NY + j3 ] ;
laplace [ i1 * NY + j3 ] . nghb [ 1 ] = & phi [ ( i3 ) * NY + j3 ] ;
laplace [ i1 * NY + j3 ] . nghb [ 2 ] = & phi [ i1 * NY + j1 ] ;
laplace [ i1 * NY + j3 ] . nghb [ 3 ] = & phi [ i1 * NY + j3 - 1 ] ;
break ;
}
}
}
void compute_laplacian ( double phi [ NX * NY ] , t_laplacian laplace [ NX * NY ] , double delta [ NX * NY ] , short int xy_in [ NX * NY ] )
/* compute the discretized Laplacian of phi */
{
int i , j , k , n ;
/* in the bulk */
if ( B_COND = = BC_LSHAPE )
{
# pragma omp parallel for private(i,j,k)
for ( i = 1 ; i < NX - 1 ; i + + )
for ( j = 1 ; j < NY - 1 ; j + + )
if ( xy_in [ i * NY + j ] )
{
delta [ i * NY + j ] = - 4.0 * phi [ i * NY + j ] ;
for ( k = 0 ; k < 4 ; k + + )
delta [ i * NY + j ] + = * ( laplace [ i * NY + j ] . nghb [ k ] ) ;
}
}
else
{
# pragma omp parallel for private(i,j,k)
for ( i = 1 ; i < NX - 1 ; i + + )
for ( j = 1 ; j < NY - 1 ; j + + )
if ( xy_in [ i * NY + j ] )
{
delta [ i * NY + j ] = phi [ ( i + 1 ) * NY + j ] + phi [ ( i - 1 ) * NY + j ] + phi [ i * NY + j + 1 ] + phi [ i * NY + j - 1 ] - 4.0 * phi [ i * NY + j ] ;
}
}
/* top and bottom boundaries */
# pragma omp parallel for private(i,k,n)
for ( i = 0 ; i < NX ; i + + )
{
if ( xy_in [ i * NY ] )
{
n = laplace [ i * NY ] . nneighb ;
delta [ i * NY ] = - ( double ) n * phi [ i * NY ] ;
for ( k = 0 ; k < n ; k + + )
delta [ i * NY ] + = * ( laplace [ i * NY ] . nghb [ k ] ) ;
}
if ( xy_in [ i * NY + NY - 1 ] )
{
n = laplace [ i * NY + NY - 1 ] . nneighb ;
delta [ i * NY + NY - 1 ] = - ( double ) n * phi [ i * NY + NY - 1 ] ;
for ( k = 0 ; k < n ; k + + )
delta [ i * NY + NY - 1 ] + = * ( laplace [ i * NY + NY - 1 ] . nghb [ k ] ) ;
}
}
/* left and right boundaries */
# pragma omp parallel for private(j,k,n)
for ( j = 1 ; j < NY - 1 ; j + + )
{
if ( xy_in [ j ] )
{
n = laplace [ j ] . nneighb ;
delta [ j ] = - ( double ) n * phi [ j ] ;
for ( k = 0 ; k < n ; k + + )
delta [ j ] + = * ( laplace [ j ] . nghb [ k ] ) ;
}
if ( xy_in [ ( NX - 1 ) * NY + j ] )
{
n = laplace [ ( NX - 1 ) * NY + j ] . nneighb ;
delta [ ( NX - 1 ) * NY + j ] = - ( double ) n * phi [ ( NX - 1 ) * NY + j ] ;
for ( k = 0 ; k < n ; k + + )
delta [ ( NX - 1 ) * NY + j ] + = * ( laplace [ ( NX - 1 ) * NY + j ] . nghb [ k ] ) ;
}
}
}
2023-09-02 11:36:15 +02:00
double oscillating_bc ( int time , int j )
2022-08-20 16:02:07 +02:00
{
double t , phase , a , envelope , omega ;
switch ( OSCILLATION_SCHEDULE )
{
case ( OSC_PERIODIC ) :
{
2023-09-02 11:36:15 +02:00
if ( OSCIL_LEFT_YSHIFT > 0.0 )
t = ( double ) time * OMEGA - ( double ) j * OSCIL_LEFT_YSHIFT / ( double ) NY ;
else
t = ( double ) time * OMEGA + ( double ) ( NY - j ) * OSCIL_LEFT_YSHIFT / ( double ) NY ;
if ( t < 0.0 ) return ( 0.0 ) ;
else return ( AMPLITUDE * cos ( t ) * exp ( - ( double ) t * DAMPING ) ) ;
2022-08-20 16:02:07 +02:00
}
case ( OSC_SLOWING ) :
{
a = 0.0025 ;
t = ( double ) time * OMEGA ;
phase = t - a * t * t ;
// if (time%1000 == 0) printf("time = %i, phase = %.4lg\n", time, phase);
return ( AMPLITUDE * cos ( phase ) * exp ( - phase * DAMPING ) ) ;
}
case ( OSC_WAVE_PACKET ) :
{
t = ( double ) time * OMEGA ;
// a = 10.0;
a = 0.02 / OMEGA ;
phase = AMPLITUDE * cos ( t ) ;
envelope = exp ( - ( t - 0.2 ) * ( t - 0.2 ) / ( a * a ) ) * sqrt ( DPI / a ) ;
return ( phase * envelope ) ;
}
case ( OSC_CHIRP ) :
{
// a = 0.25;
t = ( double ) time * OMEGA ;
phase = t + ACHIRP * t * t ;
return ( AMPLITUDE * sin ( phase ) * exp ( - phase * DAMPING ) ) ;
}
}
}
2023-03-25 19:56:19 +01:00
void init_ior_2d ( short int * xy_in [ NX ] , double * tcc_table [ NX ] , double ior_angle )
/* compute variable index of refraction */
/* should be at some point merged with 3D version in suv_wave_3d.c */
{
2023-07-08 23:28:23 +02:00
int i , j , k , n , inlens , ncircles ;
2023-03-25 19:56:19 +01:00
double courant2 = COURANT * COURANT , courantb2 = COURANTB * COURANTB , lambda1 , mu1 ;
double u , v , u1 , x , y , xy [ 2 ] , norm2 , speed , r2 , c , salpha , h , ll , ca , sa , x1 , y1 , dx , dy , sum , sigma , x0 , y0 , rgb [ 3 ] ;
double xc [ NGRIDX * NGRIDY ] , yc [ NGRIDX * NGRIDY ] , height [ NGRIDX * NGRIDY ] ;
static double xc_stat [ NGRIDX * NGRIDY ] , yc_stat [ NGRIDX * NGRIDY ] , sigma_stat ;
static int first = 1 ;
2023-07-08 23:28:23 +02:00
t_circle circles [ NMAXCIRCLES ] ;
2023-03-25 19:56:19 +01:00
rgb [ 0 ] = 1.0 ;
rgb [ 1 ] = 1.0 ;
rgb [ 2 ] = 1.0 ;
if ( VARIABLE_IOR )
{
switch ( IOR ) {
case ( IOR_MANDELBROT ) :
{
# pragma omp parallel for private(i,j)
for ( i = 0 ; i < NX ; i + + ) {
for ( j = 0 ; j < NY ; j + + ) {
ij_to_xy ( i , j , xy ) ;
x = xy [ 0 ] ;
y = xy [ 1 ] ;
u = 0.0 ;
v = 0.0 ;
k = 0 ;
while ( ( k < MANDELLEVEL ) & & ( u * u + v * v < 1000.0 * MANDELLIMIT ) )
{
u1 = u * u - v * v + x ;
v = 2.0 * u * v + y ;
u = u1 ;
k + + ;
}
norm2 = u * u + v * v ;
if ( norm2 < MANDELLIMIT )
{
// tc[i*NY+j] = COURANT;
tcc_table [ i ] [ j ] = courant2 ;
// tgamma[i*NY+j] = GAMMA;
}
else
{
speed = 1.0 + MANDEL_IOR_SCALE * log ( 1.0 + norm2 / MANDELLIMIT ) ;
if ( speed < 0.01 ) speed = 0.01 ;
tcc_table [ i ] [ j ] = courant2 * speed ;
// tc[i*NY+j] = COURANT*sqrt(speed);
// tgamma[i*NY+j] = GAMMA;
}
}
}
break ;
}
case ( IOR_MANDELBROT_LIN ) :
{
# pragma omp parallel for private(i,j)
for ( i = 0 ; i < NX ; i + + ) {
for ( j = 0 ; j < NY ; j + + ) {
ij_to_xy ( i , j , xy ) ;
x = xy [ 0 ] ;
y = xy [ 1 ] ;
u = 0.0 ;
v = 0.0 ;
k = 0 ;
while ( ( k < MANDELLEVEL ) & & ( u * u + v * v < 1000.0 * MANDELLIMIT ) )
{
u1 = u * u - v * v + x ;
v = 2.0 * u * v + y ;
u = u1 ;
k + + ;
}
if ( k > = MANDELLEVEL )
{
// tc[i*NY+j] = COURANT;
tcc_table [ i ] [ j ] = courant2 ;
// tgamma[i*NY+j] = GAMMA;
}
else
{
speed = ( double ) k / ( double ) MANDELLEVEL ;
if ( speed < 1.0e-10 ) speed = 1.0e-10 ;
else if ( speed > 10.0 ) speed = 10.0 ;
tcc_table [ i ] [ j ] = courant2 * speed ;
// tc[i*NY+j] = COURANT*sqrt(speed);
// tgamma[i*NY+j] = GAMMA;
}
}
}
break ;
}
case ( IOR_EARTH ) :
{
for ( i = 0 ; i < NX ; i + + ) {
for ( j = 0 ; j < NY ; j + + ) {
ij_to_xy ( i , j , xy ) ;
r2 = xy [ 0 ] * xy [ 0 ] + xy [ 1 ] * xy [ 1 ] ;
if ( r2 > 1.0 ) c = 0.0 ;
else if ( r2 < 0.25 * 0.25 ) c = 0.8 * COURANT ;
else if ( r2 < 0.58 * 0.58 ) c = COURANT * ( 0.68 - 0.55 * r2 ) ;
else c = COURANT * ( 1.3 - 0.9 * r2 ) ;
// tc[i*NY+j] = c;
tcc_table [ i ] [ j ] = c ;
// tgamma[i*NY+j] = GAMMA;
}
}
break ;
}
case ( IOR_EXPLO_LENSING ) :
{
salpha = DPI / ( double ) NPOLY ;
// lambda1 = LAMBDA;
// mu1 = LAMBDA;
lambda1 = 0.5 * LAMBDA ;
mu1 = 0.5 * LAMBDA ;
h = lambda1 * tan ( PI / ( double ) NPOLY ) ;
if ( h < mu1 ) ll = sqrt ( mu1 * mu1 - h * h ) ;
else ll = 0.0 ;
// #pragma omp parallel for private(i,j)
for ( i = 0 ; i < NX ; i + + ) {
for ( j = 0 ; j < NY ; j + + ) if ( xy_in [ i * NY + j ] ) {
ij_to_xy ( i , j , xy ) ;
x = xy [ 0 ] ;
y = xy [ 1 ] ;
inlens = 0 ;
for ( k = 0 ; k < NPOLY ; k + + )
{
ca = cos ( ( ( double ) k + 0.5 ) * salpha + APOLY * PID ) ;
sa = sin ( ( ( double ) k + 0.5 ) * salpha + APOLY * PID ) ;
x1 = x * ca + y * sa ;
y1 = - x * sa + y * ca ;
if ( ( module2 ( x1 - lambda1 - ll , y1 ) < mu1 ) & & ( module2 ( x1 - lambda1 + ll , y1 ) < mu1 ) ) inlens = 1 ;
}
if ( inlens ) c = COURANTB ;
else c = COURANT ;
// tc[i*NY+j] = c;
tcc_table [ i ] [ j ] = c * c ;
// tgamma[i*NY+j] = GAMMA;
}
else
{
// tc[i*NY+j] = 0.0;
tcc_table [ i ] [ j ] = 0.0 ;
// tgamma[i*NY+j] = 0.0;
}
}
break ;
}
case ( IOR_PERIODIC_WELLS ) :
{
dx = ( XMAX - XMIN ) / ( double ) NGRIDX ;
dy = ( YMAX - YMIN ) / ( double ) NGRIDY ;
sigma = 0.2 * dx * dx ;
for ( i = 0 ; i < NGRIDX ; i + + )
for ( j = 0 ; j < NGRIDY ; j + + )
{
n = j * NGRIDX + i ;
xc [ n ] = XMIN + dx * ( ( double ) i + 0.5 ) ;
yc [ n ] = YMIN + dy * ( ( double ) j + 0.5 ) ;
if ( j % 2 = = 1 ) yc [ n ] + = 0.5 * dx ;
}
// #pragma omp parallel for private(i,j)
for ( i = 0 ; i < NX ; i + + ) {
for ( j = 0 ; j < NY ; j + + ) {
ij_to_xy ( i , j , xy ) ;
x = xy [ 0 ] ;
y = xy [ 1 ] ;
sum = 0.0 ;
for ( n = 0 ; n < NGRIDX * NGRIDY ; n + + )
{
r2 = ( x - xc [ n ] ) * ( x - xc [ n ] ) + ( y - yc [ n ] ) * ( y - yc [ n ] ) ;
sum + = exp ( - r2 / ( sigma ) ) ;
}
// sum = tanh(sum);
// printf("%.3lg\n", sum);
tcc_table [ i ] [ j ] = COURANT * sum + COURANTB * ( 1.0 - sum ) ;
}
}
break ;
}
case ( IOR_RANDOM_WELLS ) :
{
dx = ( XMAX - XMIN ) / ( double ) NGRIDX ;
dy = ( YMAX - YMIN ) / ( double ) NGRIDY ;
sigma = 0.2 * dx * dx ;
for ( i = 0 ; i < NGRIDX ; i + + )
for ( j = 0 ; j < NGRIDY ; j + + )
{
n = j * NGRIDX + i ;
xc [ n ] = XMIN + dx * ( ( double ) i + 0.5 + 0.1 * gaussian ( ) ) ;
yc [ n ] = YMIN + dy * ( ( double ) j + 0.5 + 0.1 * gaussian ( ) ) ;
// if (j%2 == 1) yc[n] += 0.5*dx;
height [ n ] = 0.5 + 0.5 * gaussian ( ) ;
if ( height [ n ] > 1.0 ) height [ n ] = 1.0 ;
if ( height [ n ] < 0.0 ) height [ n ] = 0.0 ;
}
// #pragma omp parallel for private(i,j)
2023-07-08 23:28:23 +02:00
for ( i = 0 ; i < NX ; i + + )
{
if ( i % 100 = = 0 ) printf ( " Computing potential for column %i of %i \n " , i , NX ) ;
2023-03-25 19:56:19 +01:00
for ( j = 0 ; j < NY ; j + + ) {
ij_to_xy ( i , j , xy ) ;
x = xy [ 0 ] ;
y = xy [ 1 ] ;
sum = 0.0 ;
for ( n = 0 ; n < NGRIDX * NGRIDY ; n + + )
{
r2 = ( x - xc [ n ] ) * ( x - xc [ n ] ) + ( y - yc [ n ] ) * ( y - yc [ n ] ) ;
sum + = exp ( - r2 / ( sigma ) ) * height [ n ] ;
}
sum = tanh ( sum ) ;
// printf("%.3lg\n", sum);
tcc_table [ i ] [ j ] = COURANT * sum + COURANTB * ( 1.0 - sum ) ;
}
}
break ;
}
case ( IOR_PERIODIC_WELLS_ROTATING ) :
{
if ( first )
{
dx = ( XMAX - XMIN ) / ( double ) NGRIDX ;
dy = ( YMAX - YMIN ) / ( double ) NGRIDY ;
sigma_stat = 0.2 * dx * dx ;
for ( i = 0 ; i < NGRIDX ; i + + )
for ( j = 0 ; j < NGRIDY ; j + + )
{
n = j * NGRIDX + i ;
xc_stat [ n ] = XMIN + dx * ( ( double ) i + 0.5 ) ;
yc_stat [ n ] = YMIN + dy * ( ( double ) j + 0.5 ) ;
if ( j % 2 = = 1 ) yc_stat [ n ] + = 0.5 * dx ;
}
first = 0 ;
}
ca = cos ( ior_angle ) ;
sa = sin ( ior_angle ) ;
for ( n = 0 ; n < NGRIDX * NGRIDY ; n + + )
{
xc [ n ] = xc_stat [ n ] * ca + yc_stat [ n ] * sa ;
yc [ n ] = - xc_stat [ n ] * sa + yc_stat [ n ] * ca ;
// printf("center[%i] at (%.5lg, %.5lg)\n", n, xc[n], yc[n]);
// draw_colored_circle(xc[n], yc[n], 0.05, 10, rgb);
}
// #pragma omp parallel for private(i,j)
for ( i = 0 ; i < NX ; i + + ) {
// if (i%100 == 0) printf("initializing column %i of %i\n", i, NX);
for ( j = 0 ; j < NY ; j + + ) {
ij_to_xy ( i , j , xy ) ;
x = xy [ 0 ] ;
y = xy [ 1 ] ;
sum = 0.0 ;
for ( n = 0 ; n < NGRIDX * NGRIDY ; n + + )
{
r2 = ( x - xc [ n ] ) * ( x - xc [ n ] ) + ( y - yc [ n ] ) * ( y - yc [ n ] ) ;
sum + = exp ( - r2 / ( sigma_stat ) ) ;
}
// sum = tanh(sum);
// printf("%.3lg\n", sum);
tcc_table [ i ] [ j ] = COURANT * sum + COURANTB * ( 1.0 - sum ) ;
}
}
break ;
}
case ( IOR_PERIODIC_WELLS_ROTATING_LARGE ) :
{
if ( first )
{
dx = ( 1.5 * XMAX - 1.5 * XMIN ) / ( double ) NGRIDX ;
dy = ( 1.5 * YMAX - 1.5 * YMIN ) / ( double ) NGRIDY ;
sigma_stat = 0.2 * dx * dx ;
for ( i = 0 ; i < NGRIDX ; i + + )
for ( j = 0 ; j < NGRIDY ; j + + )
{
n = j * NGRIDX + i ;
xc_stat [ n ] = 1.5 * XMIN + dx * ( ( double ) i + 0.5 ) ;
yc_stat [ n ] = 1.5 * YMIN + dy * ( ( double ) j + 0.5 ) ;
if ( j % 2 = = 1 ) yc_stat [ n ] + = 0.5 * dx ;
}
first = 0 ;
}
ca = cos ( ior_angle ) ;
sa = sin ( ior_angle ) ;
for ( n = 0 ; n < NGRIDX * NGRIDY ; n + + )
{
xc [ n ] = xc_stat [ n ] * ca + yc_stat [ n ] * sa ;
yc [ n ] = - xc_stat [ n ] * sa + yc_stat [ n ] * ca ;
}
// #pragma omp parallel for private(i,j)
for ( i = 0 ; i < NX ; i + + ) {
// if (i%100 == 0) printf("initializing column %i of %i\n", i, NX);
for ( j = 0 ; j < NY ; j + + ) {
ij_to_xy ( i , j , xy ) ;
x = xy [ 0 ] ;
y = xy [ 1 ] ;
sum = 0.0 ;
for ( n = 0 ; n < NGRIDX * NGRIDY ; n + + )
{
r2 = ( x - xc [ n ] ) * ( x - xc [ n ] ) + ( y - yc [ n ] ) * ( y - yc [ n ] ) ;
sum + = exp ( - r2 / ( sigma_stat ) ) ;
}
tcc_table [ i ] [ j ] = COURANT * sum + COURANTB * ( 1.0 - sum ) ;
}
}
break ;
}
2023-07-08 23:28:23 +02:00
case ( IOR_POISSON_WELLS ) :
{
ncircles = init_circle_config_pattern ( circles , C_POISSON_DISC ) ;
for ( n = 0 ; n < ncircles ; n + + )
{
height [ n ] = 0.5 + 0.5 * gaussian ( ) ;
if ( height [ n ] > 1.0 ) height [ n ] = 1.0 ;
if ( height [ n ] < 0.0 ) height [ n ] = 0.0 ;
}
for ( n = 0 ; n < ncircles ; n + + ) printf ( " Circle %i at (%.3lg, %.3lg) height %.3lg \n " , n , circles [ n ] . xc , circles [ n ] . yc , height [ n ] ) ;
sigma = 0.2 * ( XMAX - XMIN ) * ( YMAX - YMIN ) / ( double ) ncircles ;
// sigma = MU*MU;
for ( i = 0 ; i < NX ; i + + )
{
if ( i % 100 = = 0 ) printf ( " Computing potential for column %i of %i \n " , i , NX ) ;
for ( j = 0 ; j < NY ; j + + ) {
ij_to_xy ( i , j , xy ) ;
x = xy [ 0 ] ;
y = xy [ 1 ] ;
sum = 0.0 ;
for ( n = 0 ; n < ncircles ; n + + )
{
r2 = ( x - circles [ n ] . xc ) * ( x - circles [ n ] . xc ) + ( y - circles [ n ] . yc ) * ( y - circles [ n ] . yc ) ;
sum + = exp ( - r2 / ( sigma ) ) * height [ n ] ;
}
sum = tanh ( sum ) ;
// printf("%.3lg\n", sum);
tcc_table [ i ] [ j ] = COURANT * sum + COURANTB * ( 1.0 - sum ) ;
}
}
break ;
}
case ( IOR_PPP_WELLS ) :
{
ncircles = init_circle_config_pattern ( circles , C_RAND_POISSON ) ;
for ( n = 0 ; n < ncircles ; n + + )
{
height [ n ] = 0.5 + 0.5 * gaussian ( ) ;
if ( height [ n ] > 1.0 ) height [ n ] = 1.0 ;
if ( height [ n ] < 0.0 ) height [ n ] = 0.0 ;
}
for ( n = 0 ; n < ncircles ; n + + ) printf ( " Circle %i at (%.3lg, %.3lg) height %.3lg \n " , n , circles [ n ] . xc , circles [ n ] . yc , height [ n ] ) ;
sigma = 0.2 * ( XMAX - XMIN ) * ( YMAX - YMIN ) / ( double ) ncircles ;
// sigma = MU*MU;
for ( i = 0 ; i < NX ; i + + )
{
if ( i % 100 = = 0 ) printf ( " Computing potential for column %i of %i \n " , i , NX ) ;
for ( j = 0 ; j < NY ; j + + ) {
ij_to_xy ( i , j , xy ) ;
x = xy [ 0 ] ;
y = xy [ 1 ] ;
sum = 0.0 ;
for ( n = 0 ; n < ncircles ; n + + )
{
r2 = ( x - circles [ n ] . xc ) * ( x - circles [ n ] . xc ) + ( y - circles [ n ] . yc ) * ( y - circles [ n ] . yc ) ;
sum + = exp ( - r2 / ( sigma ) ) * height [ n ] ;
}
sum = tanh ( sum ) ;
// printf("%.3lg\n", sum);
tcc_table [ i ] [ j ] = COURANT * sum + COURANTB * ( 1.0 - sum ) ;
}
}
break ;
} default :
2023-03-25 19:56:19 +01:00
{
for ( i = 0 ; i < NX ; i + + ) {
for ( j = 0 ; j < NY ; j + + ) {
// tc[i*NY+j] = COURANT;
tcc_table [ i ] [ j ] = COURANT ;
// tgamma[i*NY+j] = GAMMA;
}
}
}
}
}
else
{
# pragma omp parallel for private(i,j)
for ( i = 0 ; i < NX ; i + + ) {
for ( j = 0 ; j < NY ; j + + ) {
if ( xy_in [ i * NY + j ] ! = 0 )
{
// tc[i*NY+j] = COURANT;
tcc_table [ i ] [ j ] = courant2 ;
// if (xy_in[i*NY+j] == 1) tgamma[i*NY+j] = GAMMA;
// else tgamma[i*NY+j] = GAMMAB;
}
else if ( TWOSPEEDS )
{
// tc[i*NY+j] = COURANTB;
tcc_table [ i ] [ j ] = courantb2 ;
// tgamma[i*NY+j] = GAMMAB;
}
}
}
}
}
double ior_angle_schedule ( int i )
/* angle of rotation for variable index of refraction IOR_PERIODIC_WELLS_ROTATING */
{
return ( IOR_TOTAL_TURNS * DPI * ( double ) i / ( double ) NSTEPS ) ;
}
int phased_array_schedule ( int i )
/* returns time-dependent dephasing in phased array */
{
int phase ;
phase = i * 11 / NSTEPS ;
switch ( phase ) {
case ( 0 ) : return ( 4 ) ;
case ( 1 ) : return ( 3 ) ;
case ( 2 ) : return ( 2 ) ;
case ( 3 ) : return ( - 2 ) ;
case ( 4 ) : return ( - 3 ) ;
case ( 5 ) : return ( - 4 ) ;
case ( 6 ) : return ( - 3 ) ;
case ( 7 ) : return ( - 2 ) ;
case ( 8 ) : return ( 2 ) ;
case ( 9 ) : return ( 3 ) ;
case ( 10 ) : return ( 4 ) ;
default : return ( 4 ) ;
}
}
void init_wave_packets ( t_wave_packet * packet , int radius )
/* initialise table of wave packets */
{
int i , j , k , ij [ 2 ] , nx , ny ;
double dx , dy ;
printf ( " Initialising wave packets \n " ) ;
switch ( WAVE_PACKET_SOURCE_TYPE ) {
case ( 0 ) :
{
nx = ( int ) sqrt ( ( double ) N_WAVE_PACKETS ) ;
ny = N_WAVE_PACKETS / nx ;
dx = 0.2 * ( XMAX - XMIN ) / ( double ) nx ;
dy = 0.4 * ( YMAX - YMIN ) / ( double ) ny ;
for ( i = 0 ; i < N_WAVE_PACKETS ; i + + )
{
j = i / nx ;
k = i % nx ;
packet [ i ] . xc = XMIN + ( double ) ( j + 1 ) * dx + 0.5 * dx * ( double ) rand ( ) / RAND_MAX ;
packet [ i ] . yc = ( double ) ( k - ny / 2 ) * dy + 0.5 * dy * ( double ) rand ( ) / RAND_MAX ;
packet [ i ] . period = 20.0 * ( 1.0 + 0.5 * ( double ) rand ( ) / RAND_MAX ) ;
packet [ i ] . amp = INITIAL_AMP ;
packet [ i ] . phase = DPI * ( double ) rand ( ) / RAND_MAX ;
packet [ i ] . var_envelope = 5.0e5 ;
packet [ i ] . time_shift = 10 + rand ( ) % 200 ;
xy_to_ij ( packet [ i ] . xc , packet [ i ] . yc , ij ) ;
if ( ij [ 0 ] < = radius ) ij [ 0 ] = radius + 1 ;
packet [ i ] . ix = ij [ 0 ] ;
packet [ i ] . iy = ij [ 1 ] ;
}
break ;
}
case ( 1 ) :
{
for ( i = 0 ; i < N_WAVE_PACKETS ; i + + )
{
// j = i/nx;
// k = i%nx;
packet [ i ] . xc = XMIN + 0.15 * ( XMAX - XMIN ) * ( double ) rand ( ) / RAND_MAX ;
packet [ i ] . yc = 0.4 * ( YMAX - YMIN ) * ( ( double ) rand ( ) / RAND_MAX - 0.5 ) ;
// packet[i].period = 30.0*(1.0 + 0.5*(double)rand()/RAND_MAX);
packet [ i ] . period = 50.0 * ( 1.0 + 0.5 * ( double ) rand ( ) / RAND_MAX ) ;
packet [ i ] . amp = INITIAL_AMP ;
packet [ i ] . phase = DPI * ( double ) rand ( ) / RAND_MAX ;
packet [ i ] . var_envelope = 1500.0 + 500.0 * ( double ) rand ( ) / RAND_MAX ;
packet [ i ] . time_shift = 10 + rand ( ) % 200 ;
xy_to_ij ( packet [ i ] . xc , packet [ i ] . yc , ij ) ;
if ( ij [ 0 ] < = radius ) ij [ 0 ] = radius + 1 ;
packet [ i ] . ix = ij [ 0 ] ;
packet [ i ] . iy = ij [ 1 ] ;
}
break ;
}
}
}
double wave_packet_height ( double t , t_wave_packet packet , int type_envelope )
/* determines height of wave packet at time t */
{
double cwave , envelope ;
cwave = packet . amp * cos ( DPI * t / packet . period + packet . phase ) ;
switch ( type_envelope ) {
case ( 0 ) :
{
envelope = 0.1 + sin ( DPI * t / packet . var_envelope ) ;
envelope = envelope * envelope ;
break ;
}
case ( 1 ) :
{
if ( t < ( double ) packet . var_envelope ) envelope = 1.0 ;
else envelope = 0.0 ;
break ;
}
}
return ( cwave * envelope ) ;
}
void add_wave_packets_locally ( double * phi [ NX ] , double * psi [ NX ] , t_wave_packet * packet , int time , int radius , int add_period , int type_envelope )
/* add some wave packet sources - this local version leads to numerical artifacts */
{
int i , ij [ 2 ] , t , j , k , envelope , irad2 , rmin2 , rmax2 ;
double cwave , wave_height , wave_height1 , r2 , variance ;
variance = ( double ) ( radius * radius ) ;
rmin2 = radius * radius / 2 ;
rmax2 = radius * radius + 1 ;
if ( time % add_period = = 0 ) for ( i = 0 ; i < N_WAVE_PACKETS ; i + + )
{
t = ( double ) ( time - packet [ i ] . time_shift ) ;
wave_height = wave_packet_height ( t , packet [ i ] , type_envelope ) ;
for ( j = 0 ; j < radius + 1 ; j + + )
for ( k = 0 ; k < radius + 1 ; k + + )
{
irad2 = j * j + k * k ;
if ( ( irad2 < rmax2 ) & & ( irad2 > rmin2 ) )
{
r2 = ( double ) ( irad2 ) ;
wave_height1 = wave_height * exp ( - r2 / variance ) ;
phi [ packet [ i ] . ix + j ] [ packet [ i ] . iy + k ] = wave_height1 ;
phi [ packet [ i ] . ix - j ] [ packet [ i ] . iy + k ] = wave_height1 ;
phi [ packet [ i ] . ix + j ] [ packet [ i ] . iy - k ] = wave_height1 ;
phi [ packet [ i ] . ix - j ] [ packet [ i ] . iy - k ] = wave_height1 ;
}
else if ( irad2 < = rmin2 )
{
phi [ packet [ i ] . ix + j ] [ packet [ i ] . iy + k ] = 0.0 ;
phi [ packet [ i ] . ix - j ] [ packet [ i ] . iy + k ] = 0.0 ;
phi [ packet [ i ] . ix + j ] [ packet [ i ] . iy - k ] = 0.0 ;
phi [ packet [ i ] . ix - j ] [ packet [ i ] . iy - k ] = 0.0 ;
}
}
// printf("Adding wave packet %i with value %.3lg\n", i, wave_height);
// if (add==0)
{
// t -= 1.0/(double)NVID;
t - = 0.1 / ( double ) NVID ;
wave_height = wave_packet_height ( t , packet [ i ] , type_envelope ) ;
for ( j = 0 ; j < radius + 1 ; j + + )
for ( k = 0 ; k < radius + 1 ; k + + )
{
irad2 = j * j + k * k ;
if ( ( irad2 < rmax2 ) & & ( irad2 > rmin2 ) )
{
r2 = ( double ) ( irad2 ) ;
wave_height1 = wave_height * exp ( - r2 / variance ) ;
psi [ packet [ i ] . ix + j ] [ packet [ i ] . iy + k ] = wave_height1 ;
psi [ packet [ i ] . ix - j ] [ packet [ i ] . iy + k ] = wave_height1 ;
psi [ packet [ i ] . ix + j ] [ packet [ i ] . iy - k ] = wave_height1 ;
psi [ packet [ i ] . ix - j ] [ packet [ i ] . iy - k ] = wave_height1 ;
}
else if ( irad2 < = rmin2 )
{
psi [ packet [ i ] . ix + j ] [ packet [ i ] . iy + k ] = 0.0 ;
psi [ packet [ i ] . ix - j ] [ packet [ i ] . iy + k ] = 0.0 ;
psi [ packet [ i ] . ix + j ] [ packet [ i ] . iy - k ] = 0.0 ;
psi [ packet [ i ] . ix - j ] [ packet [ i ] . iy - k ] = 0.0 ;
}
}
}
}
}
void add_circular_wave_loc ( double factor , double x , double y , double * phi [ NX ] , double * psi [ NX ] , short int * xy_in [ NX ] , int xmin , int xmax , int ymin , int ymax )
/* add drop at (x,y) to the field with given prefactor */
{
int i , j ;
double xy [ 2 ] , dist2 ;
// for (i=0; i<NX; i++)
// for (j=0; j<NY; j++)
# pragma omp parallel for private(i,j,xy,dist2)
for ( i = xmin ; i < xmax ; i + + )
for ( j = ymin ; j < ymax ; j + + )
{
ij_to_xy ( i , j , xy ) ;
dist2 = ( xy [ 0 ] - x ) * ( xy [ 0 ] - x ) + ( xy [ 1 ] - y ) * ( xy [ 1 ] - y ) ;
if ( ( xy_in [ i ] [ j ] ) | | ( TWOSPEEDS ) )
phi [ i ] [ j ] + = INITIAL_AMP * factor * exp ( - dist2 / INITIAL_VARIANCE ) * cos ( - sqrt ( dist2 ) / INITIAL_WAVELENGTH ) ;
}
}
void add_wave_packets_globally ( double * phi [ NX ] , double * psi [ NX ] , short int * xy_in [ NX ] , t_wave_packet * packet , int time )
/* add some wave packet sources */
{
int i , ij [ 2 ] ;
double amp , t , omega ;
static int xmin , xmax , ymin , ymax , first = 1 ;
if ( first )
{
xy_to_ij ( XMIN , - 0.2 * ( YMAX - YMIN ) , ij ) ;
xmin = ij [ 0 ] ;
ymin = ij [ 1 ] ;
xy_to_ij ( XMIN + 0.15 * ( XMAX - XMIN ) , 0.2 * ( YMAX - YMIN ) , ij ) ;
xmax = ij [ 0 ] ;
ymax = ij [ 1 ] ;
first = 0 ;
}
for ( i = 0 ; i < N_WAVE_PACKETS ; i + + )
{
t = ( double ) ( time - packet [ i ] . time_shift ) ;
omega = DPI / packet [ i ] . period ;
amp = packet [ i ] . amp * omega * sin ( omega * t + packet [ i ] . phase ) ;
if ( t > ( double ) packet [ i ] . var_envelope ) amp * = exp ( - 0.1 * ( t - ( double ) packet [ i ] . var_envelope ) ) ;
if ( t < ( double ) packet [ i ] . var_envelope + 100.0 )
add_circular_wave_loc ( amp , packet [ i ] . xc , packet [ i ] . yc , phi , psi , xy_in , xmin , xmax , ymin , ymax ) ;
}
}
void add_wave_packets ( double * phi [ NX ] , double * psi [ NX ] , short int * xy_in [ NX ] , t_wave_packet * packet , int time , int radius , int local , int add_period , int type_envelope )
/* add some wave packet sources */
{
if ( local ) add_wave_packets_locally ( phi , psi , packet , time , radius , add_period , type_envelope ) ;
else add_wave_packets_globally ( phi , psi , xy_in , packet , time ) ;
}