使用C编程和OpenGL设置Mandelbrot分形。这是我的代码。它现在只在中心显示一个点。我无法弄清楚我哪里出错了。我很确定我的数学是正确的。也许我有错误的循环?
This picture is what Im trying to get
到目前为止,这是我的代码:
#include <GLUT/glut.h>
#include <math.h>
void init(void);
void display(void);
const int screenWidth = 640;
const int screenHeight = 480;
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(screenWidth, screenHeight);
glutInitWindowPosition(0, 0);
glutCreateWindow("Mandelbrot");
// glViewport(-320, -320, 320, 320);
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void init(void) {
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-500.0, screenWidth, -500.0, screenHeight);
// A = screenWidth / 4.0;
// B = 0.0;
// C = D = screenHeight / 2.0;
}
void display(void) {
GLdouble x, f, y, xtemp, y0, x0, iteration, maxInteration;
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(1);
glColor3f(0.0, 0.0, 0.0);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (y0 = - 1; y0 < 1.1; y0 = y0 + 0.0025) {
for (x0 = -2.5; x0 < 1.1; x0 = x0 + 0.0025) {
x = 0;
y = 0;
iteration = 0;
maxInteration = 1000;
while (((x * x) + (y * y) < (2 * 2)) && iteration < maxInteration) {
xtemp = (x * x) - (y * y) + x0;
y = (2 * x * y) + y0;
x = xtemp;
iteration = iteration + 1;
if (y <= 2) {
glBegin(GL_POINTS);
glVertex2d(x / 750, y / 750);
glEnd();
}
}
}
}
glFlush();
}
这是我在评论中修复建议后更新的代码..它导致上面的图像..但是,现在我试图创建对象周围的灰色圆圈???我试图通过最后的其他方式做到这一点......任何想法?
#include <GLUT/glut.h>
#include <math.h>
void init(void);
void display(void);
const int screenWidth = 640;
const int screenHeight = 640;
GLdouble A, B, C, D;
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(screenWidth, screenHeight);
glutInitWindowPosition(0, 0);
glutCreateWindow("Mandelbrot");
glViewport(-1, 1, -1, 1);
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void init(void) {
//glMatrixMode(GL_PROJECTION);
gluOrtho2D(-3.0, 3.0, -3.0, 3.0);
A = screenWidth / 4.0;
B = 0.0;
C = D = screenHeight / 2.0;
}
void display(void)
{
GLdouble x, f, y, xtemp, y0, x0, iteration, maxInteration;
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(1);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for(y0 = -1; y0< 1.1; y0 = y0 + 0.0025){
for (x0 = -2.5; x0 < 1.1; x0 = x0 + 0.0025) {
x = 0;
y = 0;
iteration = 0;
maxInteration = 200;
while(((x*x) + (y*y) <(2*2)) && iteration <maxInteration){
xtemp = (x*x) - (y*y) + x0;
y = (2*x*y) +y0;
x = xtemp;
iteration = iteration + 1;
}
if(iteration >= maxInteration){
glBegin(GL_POINTS);
glVertex2d(x0 , y0);
glColor3f(0.0, 0.0, 0.0);
glEnd();
}
else{
????
}
}
}
glFlush();
}
答案 0 :(得分:1)
首先,这里有关于您的代码的一些建议:
这是我的意思的一个小例子:
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
const int screen_width = 640;
const int screen_height = 480;
float c[4];
float z[4];
float clamp(float x, float vmin, float vmax) {
if (x < vmin) {
return vmin;
} else if (x > vmax) {
return vmax;
}
return x;
}
void dc_add(float *a, float *b, float *res) {
res[0] = a[0] + b[0];
res[1] = a[1] + b[1];
res[2] = a[2] + b[2];
res[3] = a[3] + b[3];
}
void dc_mul(float *a, float *b, float *res) {
res[0] = a[0] * b[0] - a[1] * b[1];
res[1] = a[0] * b[1] + a[1] * b[0];
res[2] = a[0] * b[2] + a[2] * b[0] - a[1] * b[3] - a[3] * b[1];
res[3] = a[0] * b[3] + a[3] * b[0] + a[2] * b[1] + a[1] * b[2];
}
void dc_sqr(float *a, float *res) {
res[0] = a[0] * a[0] - a[1] * a[1];
res[1] = 2.0f * a[0] * a[1];
res[2] = 2.0f * (a[0] * a[2] - a[1] * a[3]);
res[3] = 2.0f * (a[0] * a[3] + a[1] * a[2]);
}
float dot(float x, float y) { return x * x + y * y; }
void init(void) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, screen_width, 0, screen_height);
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
for (int y = 0; y < screen_height; y++) {
for (int x = 0; x < screen_width; x++) {
float px = -1.0f + 2.0f * (float)x / (float)screen_width;
float py = -1.0f + 2.0f * (float)y / (float)screen_height;
px *= (float)screen_width / (float)screen_height;
float tz = 0.5f;
float zo = powf(1.2f, 1.2f);
float m2 = 0.0f;
float co = 0.0f;
float temp[4];
c[0] = px * zo; c[1] = py * zo; c[2] = 1.0; c[3] = 0.0;
z[0] = 0.0f; z[1] = 0.0f; z[2] = 0.0f; z[3] = 0.0f;
for (int i = 0; i < 256; i++) {
if (m2 > 1024.0f) continue;
dc_sqr(z, temp);
dc_add(temp, c, z);
m2 = dot(z[0], z[1]);
co += 1.0f;
}
float d = 0.0f;
if (co < 256.0f) {
d = sqrtf((dot(z[0], z[1]) / dot(z[2], z[3]))) *
logf(dot(z[0], z[1]));
}
d = clamp(4.0f * d / zo, 0.0f, 1.0f);
d = powf(d, 0.25f);
glColor3f(d, d, d);
glBegin(GL_POINTS);
glVertex2d(x, y);
glEnd();
}
}
glFlush();
glutSwapBuffers();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(screen_width, screen_height);
glutInitWindowPosition(0, 0);
glutCreateWindow("Mandelbrot");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
这是输出:
以上示例的数学基于this shadertoy。
上面的代码是非常低效和缓慢的,但它的主要目的是证明你你不应该编码一个合适的mandelbrot。
快乐的编码。
答案 1 :(得分:0)
代码中存在一个简单的问题:使用除法而不是乘法来计算像素坐标:将glVertex2d(x / 750, y / 750);
更改为
glVertex2d(x * 750, y * 750);
但是,这不是计算Mandelbrot集的正确方法。您应该计算平方模块的迭代次数,使其超过4.0,然后将(x0 * 300,y0 * 300)处的像素颜色设置为该数字作为调色板条目或灰度级。