Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
90
Task/Mandelbrot-set/C/mandelbrot-set-1.c
Normal file
90
Task/Mandelbrot-set/C/mandelbrot-set-1.c
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
c program:
|
||||
--------------------------------
|
||||
1. draws Mandelbrot set for Fc(z)=z*z +c
|
||||
using Mandelbrot algorithm ( boolean escape time )
|
||||
-------------------------------
|
||||
2. technique of creating ppm file is based on the code of Claudio Rocchini
|
||||
http://en.wikipedia.org/wiki/Image:Color_complex_plot.jpg
|
||||
create 24 bit color graphic file , portable pixmap file = PPM
|
||||
see http://en.wikipedia.org/wiki/Portable_pixmap
|
||||
to see the file use external application ( graphic viewer)
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
int main()
|
||||
{
|
||||
/* screen ( integer) coordinate */
|
||||
int iX,iY;
|
||||
const int iXmax = 800;
|
||||
const int iYmax = 800;
|
||||
/* world ( double) coordinate = parameter plane*/
|
||||
double Cx,Cy;
|
||||
const double CxMin=-2.5;
|
||||
const double CxMax=1.5;
|
||||
const double CyMin=-2.0;
|
||||
const double CyMax=2.0;
|
||||
/* */
|
||||
double PixelWidth=(CxMax-CxMin)/iXmax;
|
||||
double PixelHeight=(CyMax-CyMin)/iYmax;
|
||||
/* color component ( R or G or B) is coded from 0 to 255 */
|
||||
/* it is 24 bit color RGB file */
|
||||
const int MaxColorComponentValue=255;
|
||||
FILE * fp;
|
||||
char *filename="new1.ppm";
|
||||
char *comment="# ";/* comment should start with # */
|
||||
static unsigned char color[3];
|
||||
/* Z=Zx+Zy*i ; Z0 = 0 */
|
||||
double Zx, Zy;
|
||||
double Zx2, Zy2; /* Zx2=Zx*Zx; Zy2=Zy*Zy */
|
||||
/* */
|
||||
int Iteration;
|
||||
const int IterationMax=200;
|
||||
/* bail-out value , radius of circle ; */
|
||||
const double EscapeRadius=2;
|
||||
double ER2=EscapeRadius*EscapeRadius;
|
||||
/*create new file,give it a name and open it in binary mode */
|
||||
fp= fopen(filename,"wb"); /* b - binary mode */
|
||||
/*write ASCII header to the file*/
|
||||
fprintf(fp,"P6\n %s\n %d\n %d\n %d\n",comment,iXmax,iYmax,MaxColorComponentValue);
|
||||
/* compute and write image data bytes to the file*/
|
||||
for(iY=0;iY<iYmax;iY++)
|
||||
{
|
||||
Cy=CyMin + iY*PixelHeight;
|
||||
if (fabs(Cy)< PixelHeight/2) Cy=0.0; /* Main antenna */
|
||||
for(iX=0;iX<iXmax;iX++)
|
||||
{
|
||||
Cx=CxMin + iX*PixelWidth;
|
||||
/* initial value of orbit = critical point Z= 0 */
|
||||
Zx=0.0;
|
||||
Zy=0.0;
|
||||
Zx2=Zx*Zx;
|
||||
Zy2=Zy*Zy;
|
||||
/* */
|
||||
for (Iteration=0;Iteration<IterationMax && ((Zx2+Zy2)<ER2);Iteration++)
|
||||
{
|
||||
Zy=2*Zx*Zy + Cy;
|
||||
Zx=Zx2-Zy2 +Cx;
|
||||
Zx2=Zx*Zx;
|
||||
Zy2=Zy*Zy;
|
||||
};
|
||||
/* compute pixel color (24 bit = 3 bytes) */
|
||||
if (Iteration==IterationMax)
|
||||
{ /* interior of Mandelbrot set = black */
|
||||
color[0]=0;
|
||||
color[1]=0;
|
||||
color[2]=0;
|
||||
}
|
||||
else
|
||||
{ /* exterior of Mandelbrot set = white */
|
||||
color[0]=255; /* Red*/
|
||||
color[1]=255; /* Green */
|
||||
color[2]=255;/* Blue */
|
||||
};
|
||||
/*write color to the file*/
|
||||
fwrite(color,1,3,fp);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
240
Task/Mandelbrot-set/C/mandelbrot-set-2.c
Normal file
240
Task/Mandelbrot-set/C/mandelbrot-set-2.c
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
|
||||
void set_texture();
|
||||
|
||||
typedef struct {unsigned char r, g, b;} rgb_t;
|
||||
rgb_t **tex = 0;
|
||||
int gwin;
|
||||
GLuint texture;
|
||||
int width, height;
|
||||
int tex_w, tex_h;
|
||||
double scale = 1./256;
|
||||
double cx = -.6, cy = 0;
|
||||
int color_rotate = 0;
|
||||
int saturation = 1;
|
||||
int invert = 0;
|
||||
int max_iter = 256;
|
||||
|
||||
void render()
|
||||
{
|
||||
double x = (double)width /tex_w,
|
||||
y = (double)height/tex_h;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0, 0); glVertex2i(0, 0);
|
||||
glTexCoord2f(x, 0); glVertex2i(width, 0);
|
||||
glTexCoord2f(x, y); glVertex2i(width, height);
|
||||
glTexCoord2f(0, y); glVertex2i(0, height);
|
||||
|
||||
glEnd();
|
||||
|
||||
glFlush();
|
||||
glFinish();
|
||||
}
|
||||
|
||||
int dump = 1;
|
||||
void screen_dump()
|
||||
{
|
||||
char fn[100];
|
||||
int i;
|
||||
sprintf(fn, "screen%03d.ppm", dump++);
|
||||
FILE *fp = fopen(fn, "w");
|
||||
fprintf(fp, "P6\n%d %d\n255\n", width, height);
|
||||
for (i = height - 1; i >= 0; i--)
|
||||
fwrite(tex[i], 1, width * 3, fp);
|
||||
fclose(fp);
|
||||
printf("%s written\n", fn);
|
||||
}
|
||||
|
||||
void keypress(unsigned char key, int x, int y)
|
||||
{
|
||||
switch(key) {
|
||||
case 'q': glFinish();
|
||||
glutDestroyWindow(gwin);
|
||||
return;
|
||||
case 27: scale = 1./256; cx = -.6; cy = 0; break;
|
||||
|
||||
case 'r': color_rotate = (color_rotate + 1) % 6;
|
||||
break;
|
||||
|
||||
case '>': case '.':
|
||||
max_iter += 128;
|
||||
if (max_iter > 1 << 15) max_iter = 1 << 15;
|
||||
printf("max iter: %d\n", max_iter);
|
||||
break;
|
||||
|
||||
case '<': case ',':
|
||||
max_iter -= 128;
|
||||
if (max_iter < 128) max_iter = 128;
|
||||
printf("max iter: %d\n", max_iter);
|
||||
break;
|
||||
|
||||
case 'c': saturation = 1 - saturation;
|
||||
break;
|
||||
|
||||
case 's': screen_dump(); return;
|
||||
case 'z': max_iter = 4096; break;
|
||||
case 'x': max_iter = 128; break;
|
||||
case ' ': invert = !invert;
|
||||
}
|
||||
set_texture();
|
||||
}
|
||||
|
||||
void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
|
||||
{
|
||||
if (min == max) max = min + 1;
|
||||
if (invert) hue = max - (hue - min);
|
||||
if (!saturation) {
|
||||
p->r = p->g = p->b = 255 * (max - hue) / (max - min);
|
||||
return;
|
||||
}
|
||||
double h = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
|
||||
# define VAL 255
|
||||
double c = VAL * saturation;
|
||||
double X = c * (1 - fabs(fmod(h, 2) - 1));
|
||||
|
||||
p->r = p->g = p->b = 0;
|
||||
|
||||
switch((int)h) {
|
||||
case 0: p->r = c; p->g = X; return;
|
||||
case 1: p->r = X; p->g = c; return;
|
||||
case 2: p->g = c; p->b = X; return;
|
||||
case 3: p->g = X; p->b = c; return;
|
||||
case 4: p->r = X; p->b = c; return;
|
||||
default:p->r = c; p->b = X;
|
||||
}
|
||||
}
|
||||
|
||||
void calc_mandel()
|
||||
{
|
||||
int i, j, iter, min, max;
|
||||
rgb_t *px;
|
||||
double x, y, zx, zy, zx2, zy2;
|
||||
min = max_iter; max = 0;
|
||||
for (i = 0; i < height; i++) {
|
||||
px = tex[i];
|
||||
y = (i - height/2) * scale + cy;
|
||||
for (j = 0; j < width; j++, px++) {
|
||||
x = (j - width/2) * scale + cx;
|
||||
iter = 0;
|
||||
|
||||
zx = hypot(x - .25, y);
|
||||
if (x < zx - 2 * zx * zx + .25) iter = max_iter;
|
||||
if ((x + 1)*(x + 1) + y * y < 1/16) iter = max_iter;
|
||||
|
||||
zx = zy = zx2 = zy2 = 0;
|
||||
for (; iter < max_iter && zx2 + zy2 < 4; iter++) {
|
||||
zy = 2 * zx * zy + y;
|
||||
zx = zx2 - zy2 + x;
|
||||
zx2 = zx * zx;
|
||||
zy2 = zy * zy;
|
||||
}
|
||||
if (iter < min) min = iter;
|
||||
if (iter > max) max = iter;
|
||||
*(unsigned short *)px = iter;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
for (j = 0, px = tex[i]; j < width; j++, px++)
|
||||
hsv_to_rgb(*(unsigned short*)px, min, max, px);
|
||||
}
|
||||
|
||||
void alloc_tex()
|
||||
{
|
||||
int i, ow = tex_w, oh = tex_h;
|
||||
|
||||
for (tex_w = 1; tex_w < width; tex_w <<= 1);
|
||||
for (tex_h = 1; tex_h < height; tex_h <<= 1);
|
||||
|
||||
if (tex_h != oh || tex_w != ow)
|
||||
tex = realloc(tex, tex_h * tex_w * 3 + tex_h * sizeof(rgb_t*));
|
||||
|
||||
for (tex[0] = (rgb_t *)(tex + tex_h), i = 1; i < tex_h; i++)
|
||||
tex[i] = tex[i - 1] + tex_w;
|
||||
}
|
||||
|
||||
void set_texture()
|
||||
{
|
||||
alloc_tex();
|
||||
calc_mandel();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_w, tex_h,
|
||||
0, GL_RGB, GL_UNSIGNED_BYTE, tex[0]);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
render();
|
||||
}
|
||||
|
||||
void mouseclick(int button, int state, int x, int y)
|
||||
{
|
||||
if (state != GLUT_UP) return;
|
||||
|
||||
cx += (x - width / 2) * scale;
|
||||
cy -= (y - height/ 2) * scale;
|
||||
|
||||
switch(button) {
|
||||
case GLUT_LEFT_BUTTON: /* zoom in */
|
||||
if (scale > fabs(x) * 1e-16 && scale > fabs(y) * 1e-16)
|
||||
scale /= 2;
|
||||
break;
|
||||
case GLUT_RIGHT_BUTTON: /* zoom out */
|
||||
scale *= 2;
|
||||
break;
|
||||
/* any other button recenters */
|
||||
}
|
||||
set_texture();
|
||||
}
|
||||
|
||||
|
||||
void resize(int w, int h)
|
||||
{
|
||||
printf("resize %d %d\n", w, h);
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
glOrtho(0, w, 0, h, -1, 1);
|
||||
|
||||
set_texture();
|
||||
}
|
||||
|
||||
void init_gfx(int *c, char **v)
|
||||
{
|
||||
glutInit(c, v);
|
||||
glutInitDisplayMode(GLUT_RGB);
|
||||
glutInitWindowSize(640, 480);
|
||||
|
||||
gwin = glutCreateWindow("Mandelbrot");
|
||||
glutDisplayFunc(render);
|
||||
|
||||
glutKeyboardFunc(keypress);
|
||||
glutMouseFunc(mouseclick);
|
||||
glutReshapeFunc(resize);
|
||||
glGenTextures(1, &texture);
|
||||
set_texture();
|
||||
}
|
||||
|
||||
int main(int c, char **v)
|
||||
{
|
||||
init_gfx(&c, v);
|
||||
printf("keys:\n\tr: color rotation\n\tc: monochrome\n\ts: screen dump\n\t"
|
||||
"<, >: decrease/increase max iteration\n\tq: quit\n\tmouse buttons to zoom\n");
|
||||
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
340
Task/Mandelbrot-set/C/mandelbrot-set-3.c
Normal file
340
Task/Mandelbrot-set/C/mandelbrot-set-3.c
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
|
||||
void set_texture();
|
||||
|
||||
unsigned char *tex;
|
||||
int gwin;
|
||||
GLuint texture;
|
||||
int width, height;
|
||||
int old_width, old_height;
|
||||
double scale = 1. / 256;
|
||||
double cx = -.6, cy = 0;
|
||||
int color_rotate = 0;
|
||||
int saturation = 1;
|
||||
int invert = 0;
|
||||
int max_iter = 256;
|
||||
|
||||
void render()
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2d(0, 0);
|
||||
glVertex2i(0, 0);
|
||||
glTexCoord2d(1, 0);
|
||||
glVertex2i(width, 0);
|
||||
glTexCoord2d(1, 1);
|
||||
glVertex2i(width, height);
|
||||
glTexCoord2d(0, 1);
|
||||
glVertex2i(0, height);
|
||||
|
||||
glEnd();
|
||||
|
||||
glFlush();
|
||||
glFinish();
|
||||
}
|
||||
|
||||
int dump = 1;
|
||||
void screen_dump()
|
||||
{
|
||||
char fn[100];
|
||||
sprintf(fn, "screen%03d.ppm", dump++);
|
||||
FILE *fp = fopen(fn, "w");
|
||||
fprintf(fp, "P6\n%d %d\n255\n", width, height);
|
||||
for (int i = height - 1; i >= 0; i -= 1) {
|
||||
for (int j = 0; j < width; j += 1) {
|
||||
fwrite(&tex[((i * width) + j) * 4], 1, 3, fp);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
printf("%s written\n", fn);
|
||||
}
|
||||
|
||||
void keypress(unsigned char key,[[maybe_unused]]
|
||||
int x,[[maybe_unused]]
|
||||
int y)
|
||||
{
|
||||
switch (key) {
|
||||
case 'q':
|
||||
glFinish();
|
||||
glutDestroyWindow(gwin);
|
||||
break;
|
||||
|
||||
case 27:
|
||||
scale = 1. / 256;
|
||||
cx = -.6;
|
||||
cy = 0;
|
||||
set_texture();
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
color_rotate = (color_rotate + 1) % 6;
|
||||
set_texture();
|
||||
break;
|
||||
|
||||
case '>':
|
||||
case '.':
|
||||
max_iter += 128;
|
||||
if (max_iter > 1 << 15)
|
||||
max_iter = 1 << 15;
|
||||
printf("max iter: %d\n", max_iter);
|
||||
set_texture();
|
||||
break;
|
||||
|
||||
case '<':
|
||||
case ',':
|
||||
max_iter -= 128;
|
||||
if (max_iter < 128)
|
||||
max_iter = 128;
|
||||
printf("max iter: %d\n", max_iter);
|
||||
set_texture();
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
saturation = 1 - saturation;
|
||||
set_texture();
|
||||
break;
|
||||
|
||||
case 's':
|
||||
screen_dump();
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
max_iter = 4096;
|
||||
set_texture();
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
max_iter = 128;
|
||||
set_texture();
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
invert = !invert;
|
||||
set_texture();
|
||||
break;
|
||||
|
||||
default:
|
||||
set_texture();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define VAL 255
|
||||
|
||||
void hsv_to_rgba(int hue, int min, int max, unsigned char *px)
|
||||
{
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
|
||||
if (min == max)
|
||||
max = min + 1;
|
||||
if (invert)
|
||||
hue = max - (hue - min);
|
||||
if (!saturation) {
|
||||
r = 255 * (max - hue) / (max - min);
|
||||
g = r;
|
||||
b = r;
|
||||
} else {
|
||||
double h =
|
||||
fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
|
||||
double c = VAL * saturation;
|
||||
double X = c * (1 - fabs(fmod(h, 2) - 1));
|
||||
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
|
||||
switch ((int) h) {
|
||||
case 0:
|
||||
r = c;
|
||||
g = X;
|
||||
break;
|
||||
case 1:
|
||||
r = X;
|
||||
g = c;
|
||||
break;
|
||||
case 2:
|
||||
g = c;
|
||||
b = X;
|
||||
break;
|
||||
case 3:
|
||||
g = X;
|
||||
b = c;
|
||||
break;
|
||||
case 4:
|
||||
r = X;
|
||||
b = c;
|
||||
break;
|
||||
default:
|
||||
r = c;
|
||||
b = X;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Using an alpha channel neatly solves the problem of aligning
|
||||
* rows on 4-byte boundaries (at the expense of memory, of
|
||||
* course). */
|
||||
px[0] = r;
|
||||
px[1] = g;
|
||||
px[2] = b;
|
||||
px[3] = 255; /* Alpha channel. */
|
||||
}
|
||||
|
||||
void calc_mandel()
|
||||
{
|
||||
int i, j, iter, min, max;
|
||||
double x, y, zx, zy, zx2, zy2;
|
||||
unsigned short *hsv = malloc(width * height * sizeof(unsigned short));
|
||||
|
||||
min = max_iter;
|
||||
max = 0;
|
||||
for (i = 0; i < height; i++) {
|
||||
y = (i - height / 2) * scale + cy;
|
||||
for (j = 0; j < width; j++) {
|
||||
x = (j - width / 2) * scale + cx;
|
||||
iter = 0;
|
||||
|
||||
zx = hypot(x - .25, y);
|
||||
if (x < zx - 2 * zx * zx + .25)
|
||||
iter = max_iter;
|
||||
if ((x + 1) * (x + 1) + y * y < 1 / 16)
|
||||
iter = max_iter;
|
||||
|
||||
zx = 0;
|
||||
zy = 0;
|
||||
zx2 = 0;
|
||||
zy2 = 0;
|
||||
while (iter < max_iter && zx2 + zy2 < 4) {
|
||||
zy = 2 * zx * zy + y;
|
||||
zx = zx2 - zy2 + x;
|
||||
zx2 = zx * zx;
|
||||
zy2 = zy * zy;
|
||||
iter += 1;
|
||||
}
|
||||
if (iter < min)
|
||||
min = iter;
|
||||
if (iter > max)
|
||||
max = iter;
|
||||
hsv[(i * width) + j] = iter;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < height; i += 1) {
|
||||
for (j = 0; j < width; j += 1) {
|
||||
unsigned char *px = tex + (((i * width) + j) * 4);
|
||||
hsv_to_rgba(hsv[(i * width) + j], min, max, px);
|
||||
}
|
||||
}
|
||||
|
||||
free(hsv);
|
||||
}
|
||||
|
||||
void alloc_tex()
|
||||
{
|
||||
if (tex == NULL || width != old_width || height != old_height) {
|
||||
free(tex);
|
||||
tex = malloc(height * width * 4 * sizeof(unsigned char));
|
||||
memset(tex, 0, height * width * 4 * sizeof(unsigned char));
|
||||
old_width = width;
|
||||
old_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
void set_texture()
|
||||
{
|
||||
alloc_tex();
|
||||
calc_mandel();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, tex);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
void mouseclick(int button, int state, int x, int y)
|
||||
{
|
||||
if (state != GLUT_UP)
|
||||
return;
|
||||
|
||||
cx += (x - width / 2) * scale;
|
||||
cy -= (y - height / 2) * scale;
|
||||
|
||||
switch (button) {
|
||||
case GLUT_LEFT_BUTTON: /* zoom in */
|
||||
if (scale > fabs((double) x) * 1e-16
|
||||
&& scale > fabs((double) y) * 1e-16)
|
||||
scale /= 2;
|
||||
break;
|
||||
case GLUT_RIGHT_BUTTON: /* zoom out */
|
||||
scale *= 2;
|
||||
break;
|
||||
/* any other button recenters */
|
||||
}
|
||||
set_texture();
|
||||
}
|
||||
|
||||
|
||||
void resize(int w, int h)
|
||||
{
|
||||
printf("resize %d %d\n", w, h);
|
||||
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
glOrtho(0, w, 0, h, -1, 1);
|
||||
|
||||
set_texture();
|
||||
}
|
||||
|
||||
void init_gfx(int *c, char **v)
|
||||
{
|
||||
glutInit(c, v);
|
||||
glutInitDisplayMode(GLUT_RGBA);
|
||||
glutInitWindowSize(640, 480);
|
||||
|
||||
gwin = glutCreateWindow("Mandelbrot");
|
||||
glutDisplayFunc(render);
|
||||
|
||||
glutKeyboardFunc(keypress);
|
||||
glutMouseFunc(mouseclick);
|
||||
glutReshapeFunc(resize);
|
||||
glGenTextures(1, &texture);
|
||||
set_texture();
|
||||
}
|
||||
|
||||
int main(int c, char **v)
|
||||
{
|
||||
tex = NULL;
|
||||
|
||||
init_gfx(&c, v);
|
||||
printf
|
||||
("keys:\n\tr: color rotation\n\tc: monochrome\n\ts: screen dump\n\t"
|
||||
"<, >: decrease/increase max iteration\n\tq: quit\n\tmouse buttons to zoom\n");
|
||||
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// local variables:
|
||||
// mode: C
|
||||
// c-file-style: "k&r"
|
||||
// c-basic-offset: 4
|
||||
// end:
|
||||
3
Task/Mandelbrot-set/C/mandelbrot-set-4.c
Normal file
3
Task/Mandelbrot-set/C/mandelbrot-set-4.c
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
main(k){float i,j,r,x,y=-16;while(puts(""),y++<15)for(x
|
||||
=0;x++<84;putchar(" .:-;!/>)|&IH%*#"[k&15]))for(i=k=r=0;
|
||||
j=r*r-i*i-2+x/25,i=2*r*i+y/10,j*j+i*i<11&&k++<111;r=j);}
|
||||
100
Task/Mandelbrot-set/C/mandelbrot-set-5.c
Normal file
100
Task/Mandelbrot-set/C/mandelbrot-set-5.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
ascii Mandelbrot using 16 bits of fixed point integer maths with a selectable fractional precision in bits.
|
||||
|
||||
This is still only 16 bits mathc and allocating more than 6 bits of fractional precision leads to an overflow that adds noise to the plot..
|
||||
|
||||
This code frequently casts to short to ensure we're not accidentally benefitting from GCC promotion from short 16 bits to int.
|
||||
|
||||
gcc fixedPoint.c -lm
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
short s(short i);
|
||||
short toPrec(double f, int bitsPrecision);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// chosen to match https://www.youtube.com/watch?v=DC5wi6iv9io
|
||||
int width = 32; // basic width of a zx81
|
||||
int height = 22; // basic width of a zx81
|
||||
int zoom=3; // bigger with finer detail ie a smaller step size - leave at 1 for 32x22
|
||||
|
||||
// params
|
||||
short bitsPrecision = 6;
|
||||
printf("PRECISION=%d\n", bitsPrecision);
|
||||
|
||||
short X1 = toPrec(3.5,bitsPrecision) / zoom;
|
||||
short X2 = toPrec(2.25,bitsPrecision) ;
|
||||
short Y1 = toPrec(3,bitsPrecision)/zoom ; // horiz pos
|
||||
short Y2 = toPrec(1.5,bitsPrecision) ; // vert pos
|
||||
short LIMIT = toPrec(4,bitsPrecision);
|
||||
|
||||
|
||||
// fractal
|
||||
//char * chr = ".:-=X$#@.";
|
||||
char * chr = "abcdefghijklmnopqr ";
|
||||
//char * chr = ".,'~=+:;[/<&?oxOX#.";
|
||||
short maxIters = strlen(chr);
|
||||
|
||||
short py=0;
|
||||
while (py < height*zoom) {
|
||||
short px=0;
|
||||
while (px < width*zoom) {
|
||||
|
||||
short x0 = s(s(px*X1) / width) - X2;
|
||||
short y0 = s(s(py*Y1) / height) - Y2;
|
||||
|
||||
short x=0;
|
||||
short y=0;
|
||||
|
||||
short i=0;
|
||||
|
||||
short xSqr;
|
||||
short ySqr;
|
||||
while (i < maxIters) {
|
||||
xSqr = s(x * x) >> bitsPrecision;
|
||||
ySqr = s(y * y) >> bitsPrecision;
|
||||
|
||||
// Breakout if sum is > the limit OR breakout also if sum is negative which indicates overflow of the addition has occurred
|
||||
// The overflow check is only needed for precisions of over 6 bits because for 7 and above the sums come out overflowed and negative therefore we always run to maxIters and we see nothing.
|
||||
// By including the overflow break out we can see the fractal again though with noise.
|
||||
if ((xSqr + ySqr) >= LIMIT || (xSqr+ySqr) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
short xt = xSqr - ySqr + x0;
|
||||
y = s(s(s(x * y) >> bitsPrecision) * 2) + y0;
|
||||
x=xt;
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
i = i - 1;
|
||||
|
||||
printf("%c", chr[i]);
|
||||
|
||||
px = px + 1;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
py = py + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// convert decimal value to a fixed point value in the given precision
|
||||
short toPrec(double f, int bitsPrecision) {
|
||||
short whole = ((short)floor(f) << (bitsPrecision));
|
||||
short part = (f-floor(f))*(pow(2,bitsPrecision));
|
||||
short ret = whole + part;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// convenient casting
|
||||
short s(short i) {
|
||||
return i;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue