문제

I am doing this assignment for fun.

http://groups.csail.mit.edu/graphics/classes/6.837/F04/assignments/assignment0/

There are sample outputs at site if you want to see how it is supposed to look. It involves iterated function systems, whose algorithm according the the assignment is:

              for "lots" of random points (x0, y0)
                   for k=0 to num_iters 
                       pick a random transform fi
                       (xk+1, yk+1) = fi(xk, yk)
                   display a dot at (xk, yk)

I am running into trouble with my implementation, which is:

                void IFS::render(Image& img, int numPoints, int numIterations){

                    Vec3f color(0,1,0);

                    float x,y;
                    float u,v;
                    Vec2f myVector;
                    for(int i = 0; i < numPoints; i++){

                        x = (float)(rand()%img.Width())/img.Width();
                        y = (float)(rand()%img.Height())/img.Height();
                        myVector.Set(x,y);

                        for(int j = 0; j < numIterations;j++){

                            float randomPercent = (float)(rand()%100)/100;

                            for(int k = 0; k < num_transforms; k++){
                                if(randomPercent < range[k]){
                                    matrices[k].Transform(myVector);
                                }
                            }
                        }
                        u = myVector.x()*img.Width();
                        v = myVector.y()*img.Height();  

                        img.SetPixel(u,v,color);

                    }
                }

This is how my pick a random transform from the input matrices:

                        fscanf(input,"%d",&num_transforms);

                        matrices = new Matrix[num_transforms];  
                        probablility = new float[num_transforms];
                        range = new float[num_transforms+1];

                        for (int i = 0; i < num_transforms; i++) { 
                            fscanf (input,"%f",&probablility[i]);
                            matrices[i].Read3x3(input);

                            if(i == 0) range[i] = probablility[i];
                            else range[i] = probablility[i] + range[i-1];

                        }

My output shows only the beginnings of a Sierpinski triangle (1000 points, 1000 iterations):

sierpinski

My dragon is better, but still needs some work (1000 points, 1000 iterations):

dragon

도움이 되었습니까?

해결책

If you have RAND_MAX=4 and picture width 3, an evenly distributed sequence like [0,1,2,3,4] from rand() will be mapped to [0,1,2,0,1] by your modulo code, i.e. some numbers will occur more often. You need to cut off those numbers that are above the highest multiple of the target range that is below RAND_MAX, i.e. above ((RAND_MAX / 3) * 3). Just check for this limit and call rand() again.

Since you have to fix that error in several places, consider writing a utility function. Then, reduce the scope of your variables. The u,v declaration makes it hard to see that these two are just used in three lines of code. Declare them as "unsigned const u = ..." to make this clear and additionally get the compiler to check that you don't accidentally modify them afterwards.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top