葵花分型大法

Posted on 2013-02-13 21:57  SnakeHunt2012  阅读(225)  评论(0)    收藏  举报

本文始作于2011年12月13日,刊登于人人网,与2013年2月13日迁移至此

今天总算是把分形大作业给做出来了:

 

 

 

这是开始的画面Mandelbrot集合,前两天做出来的。在上面用鼠标点中任意区域就会以该点为参数,画出对应的Julia集

 

分出来的Julia集是这样的,我贴几张:

 

 

 

 

 

代码试着样的:

/******************************************************************
 * 用复迭代方法程序设计实现不同参数条件下的Mandelbrot集绘制       *
 * 并通过鼠标选择Mandelbrot集上的指定的点来画出相应的Julia集图形  *
 ******************************************************************/
#include <stdio.h>
#include <GL/glut.h>

#define MAX 900
#define M 1024 * 1024 * 1024
#define N 255

int red[MAX][MAX];
int green[MAX][MAX];
int blue[MAX][MAX];
int r[MAX][MAX];
int g[MAX][MAX];
int b[MAX][MAX];

void display(void);
void compute(void);
void julia(int , int);
void mouse(int, int, int, int);
void set(int, int, int);

/****************************************
 *                                      *
 *  计数单位:                           *
 *           i from 0 to MAX            *
 *           j from 0 to MAX            *
 *                                      *
 *  画布坐标:                           *
 *           x = -1 + i / (MAX / 2)     *
 *           y = 1 - j / (MAX / 2)      *
 *                                      *
 *  复平面坐标:                         *
 *           a = -2.25 + i / (MAX / 3)  *
 *           b = 1.5 - j / (MAX / 3)    *
 *                                      *
 ****************************************/
main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(10, 10);
    glutInitWindowSize(MAX, MAX);
    glutCreateWindow("OpenGL");
    compute();
    glutDisplayFunc(&display);
    glutMouseFunc(&mouse);
    glutMainLoop();
    return 0;
}

/* display:  显示 */
void display(void)
{
    int i, j;
    double x, y;
    glClear(GL_COLOR_BUFFER_BIT);
    for (i = 0; i < MAX; ++i)
        for (j = 0; j < MAX; ++j) {
            x = -1 + (double)i / (MAX / 2);
            y = 1 - (double)j / (MAX / 2);
            glBegin(GL_POINTS);
                glColor3ub(red[i][j], green[i][j], blue[i][j]);
                glVertex2d(x, y);
            glEnd();
        }
    glFlush();
}

/* compute:  计算逃逸次数k ,并将其传递给set函数写入颜色索引 */
void compute(void)
{
    int i, j, k;
    double a, b, real, imag, real2, imag2;

    for (i = 0; i < MAX; ++i)
        for (j = 0; j < MAX; ++j) {
            /* 一个 c 对应一个屏幕上一个点; step = 3 / (MAX - 1) */
            a = -2.25 + (double)i / ((MAX - 1) / 3);
            b = 1.5 - (double)j / ((MAX - 1) / 3);
            real = 0;
            imag = 0;
            for (k = 0; k < N; ++k) {
                real2 = real * real - imag * imag + a;
                imag2 = 2 * real * imag + b;
                real = real2;
                imag = imag2;
                if (real * real + imag * imag > M) {
                    set(i, j, k);
                    break;
                }
            }
        }
    return;
}

/* set:  set color at red[] green[] blue[] */
void set(int i, int j, int k)
{
    red[i][j] = (k + 100);
    blue[i][j] = (k - 100) / 2;
    green[i][j] = (k / 2) + 50;
    return;
}

/* mouse:  display the 坐标 you clicked */
void mouse(int button, int state, int x, int y)
{
    printf("x:%d  y:%d\n  button:%d  state:%d", x, y, button, state);
    julia(x, y);
    return;
}

/* julia: compute the julia set based on the point you have clicked */
void julia(int a, int b)
{
    int i, j, k;
    double p, q, d, x, y, x2, y2, xy2;

    p = -2.25 + (double)a / (MAX / 3);
    q = 1.5 - (double)b / (MAX / 3);
    for (i = 0; i < MAX; ++i)
        for (j = 0; j < MAX; ++j) {
            red[i][j] = 0;
            green[i][j] = 0;
            blue[i][j] = 0;
        }

    for (i = 0; i < MAX; ++i)
        for (j = 0; j < MAX; ++j) {
            /* 一个初始值对应屏幕上一个点; step = d */
            d = 3.0 / (MAX - 1);
            x = -1.5 + (double)i * d;
            y = -1.5 + (double)j * d;
            for (k = 0; k < N; ++k) {
                x2 = x * x;
                y2 = y * y;
                xy2 = x * y * 2;
                x = x2 - y2 + p;
                y = xy2 + q;
                if (x2 + y2 > M) {
                    set(i, j, k);
                    break;
                }
            }
        }
    display();
    return;
}