Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View 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;
}

View 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;
}

View 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:

View 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);}

View 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;
}