C create a txt.ppm file from a safed textfile - c

PPM1
Textfile
I tried create a C code, that can create a ppm, like on the picture 1 from a textfile like on picture 3. When somemone can help, it where great. I am a new Programmer, i tried do do that Code for 6h. I tried to scan in the data from the textfile and put it in a array and try to make withe that a ppm, but my code is unusable:/.

The path forward is to split the task into smaller sub-tasks, solve and test each one of them separately, and only after they all work, combine them into a single program.
Because the OP has not posted any code, I will not post any directly useful code either. If OP is truly blocked due to not getting any forward progress even after trying, this should actually be of practical use. If OP is just looking for someone to do their homework, this should annoy them immensely. Both work for me. :)
First sub-task is to read the input in an array. There are several examples on the web, and related questions here. You'll want to put this in a separate function, so merging into the complete project later on is easier. Since you are a beginner programmer, you could go for a function like
int read_numbers(double data[], int max);
so that the caller declares the maximum number of data points, and the function returns the number of data points read; or negative if an error occurs. Your main() for testing that function should be trivial, say
#define MAX_NUMBERS 500
int main(void)
{
double x[MAX_NUMBERS];
int i, n;
n = read_numbers(x, MAX_NUMBERS, stdin);
if (n <= 0) {
fprintf(stderr, "Error reading numbers from standard input.\n");
return EXIT_FAILURE;
}
printf("Read %d numbers:\n", n);
for (i = 0; i < n; i++)
printf("%.6f\n", x[i]);
return EXIT_SUCCESS;
}
The second sub-task is to generate a PPM image. PPM is actually a group of closely related image formats, also called Netpbm formats. The example image is a bitmap image -- black and white only; no colors, no shades of gray --, so the PBM format (or variant of PPM) is suitable for this.
I suspect it is easiest to attack this sub-task by using a two-dimensional array, sized for the largest image you can generate (i.e. unsigned char bitmap[HEIGHT_MAX][WIDTH_MAX];), but note that you can also just use a part of it. (You could also generate the image on the fly, without any array, but that is much more error prone, and not as universally applicable as using an array to store the image is.)
You'll probably need to decide the width of the bitmap based on the maximum data value, and the height of the bitmap based on the number of data points.
For testing, just fill the array with some simple patterns, or maybe just a diagonal line from top left corner to bottom right corner.
Then, consider writing a function that sets a rectangular area to a given value (0 or 1). Based on the image, you'll also need a function that draws vertical dotted lines, changing (exclusive-OR'ing) the state of each bit. For example,
#define WIDTH_MAX 1024
#define HEIGHT_MAX 768
unsigned char bitmap[HEIGHT_MAX][WIDTH_MAX];
int width = 0;
int height = 0;
void write_pbm(FILE *out); /* Or perhaps (const char *filename)? */
void fill_rect(int x, int y, int w, int h, unsigned char v);
void vline_xor(int x, int y, int h);
At this point, you should have realized that the write_pbm() function, the one that saves the PBM image, should be written and tested first. Then, you can use the fill_rect() function to not just draw filled rectangles, but also to initialize the image -- the portion of the array you are going to use -- to a background color (0 or 1). All of the three functions above you can, and should, do in separate sub-steps, so that at any point you can rely on that the code you've written earlier is correct and tested. That way, you only need to look at bugs in the code you have written since the last successful testing! It might sound like a slow way to progress, but it actually turns out to be the fastest way to get code working. You very quickly start to love the confidence the testing gives you, and the fact that you only need to focus and worry about one thing at a time.
The third sub-task is to find out a way to draw the rectangles and vertical dotted lines, for various inputs.
(I cheated a bit, above, and included the fill_rect() and vline_xor() functions in the previous sub-task, because I could tell those are needed to draw the example picture.)
The vertical dotted lines are easiest to draw afterwards, using a function that draws a vertical line, leaving every other pixel untouched, but exclusive-ors every other pixel. (Hint: for (y = y0; y < y0 + height; y += 2) bitmap[y][x] ^= 1;)
That leaves the filled rectangles. Their height is obviously constant, and they have a bit of vertical space in between, and they start at the left edge; so, the only thing, is to calculate how wide each rectangle needs to be. (And, how wide the entire bitmap should be, and how tall, as previously mentioned; the largest data value, and the number of data values, dictates those.)
Rather than writing one C source file, and adding to it every step, I recommend you write a separate program for each of the sub-steps. That is, after every time you get a sub-part working, you save that as a separate file, and keep it for reference -- a back-up, if you will. If you lose your way completely, or decide on another path for solving some problem, you only need to revert back to your last reference version, rather than start from scratch.
That kind of work-flow is known to be reliable, efficient, and scalable: it does not matter how large the project is, the above approach works. Of course, there are tools to help us do this in an easy, structured manner (with comments on each commit -- completed unit of code, if you will); and git is a popular, free, but very powerful one. Just do a web search for git for beginners if you are interested in it.
If you bothered to read all through the above wall of text, and grasped the work flow it describes, you won't have much trouble learning how to use tools like git to help you with the workflow. You'll also love how much typing tools like make (and the Makefiles containing the make recipes) help, and how easy it is to make and maintain projects that not only work, but also look professional. Yet, don't try to grasp all of it at once: take it one small step at a time, and verify you have a solid footing, before going onwards. That way, when you stumble, you won't hurt yourself; just learn.
Have fun!

Related

How is frame data stored in libav?

I am trying to learn to use libav. I have followed the very first tutorial on dranger.com, but I got a little confused at one point.
// Write pixel data
for(y=0; y<height; y++)
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
This code clearly works, but I don't quite understand why, particulalry I don't understand how the frame data in pFrame->data stored, whether or not it depends on the format/codec in use, why pFrame->data and pFrame->linesize is always referenced at index 0, and why we are adding y to pFrame->data[0].
In the tutorial it says
We're going to be kind of sketchy on the PPM format itself; trust us, it works.
I am not sure if writing it to the ppm format is what is causing this process to seem so strange to me. Any clarification on why this code is the way it is and how libav stores frame data would be very helpful. I am not very familiar with media encoding/decoding in general, thus why I am trying to learn.
particularly I don't understand how the frame data in pFrame->data stored, whether or not it depends on the format/codec in use
Yes, It depends on the pix_fmt value. Some formats are planar and others are not.
why pFrame->data and pFrame->linesize is always referenced at index 0,
If you look at the struct, you will see that data is an array of pointers/a pointer to a pointer. So pFrame->data[0] is a pointer to the data in the first "plane". Some formats, like RGB have a singe plane, where all data is stored in one buffer. Other formats like YUV, use a separate buffer for each plane. e.g. Y = pFrame->data[0], U = pFrame->data[1], pFrame->data[3] Audio may use one plane per channel, etc.
and why we are adding y to pFrame->data[0].
Because the example is looping over an image line by line, top to bottom.
To get the pointer to the fist pixel of any line, you multiply the linesize by the line number then add it to the pointer.

Stuck in a lab Task (image processing)

Hi everyone I am new to programming and I am first year in university cs.
my question Is that I am writing a program that screens simple images looking
for anomalies (indicated by excessive patterns of red). The program should load a
file and then print out whether or not the image contains more than a certain percentage
of intensive red pixels.
so far I have the following code:
#include <stdio.h>
#include "scc110img.h"
int main()
{
unsigned char* imageArray = LoadImage("red.bmp");
int imageSize =GetSizeOfImage();
int image;
for (image = 0; image<imageSize; image++);
printf("%d\n, imageArray[image]");
}
my question is how can I modify the program o that it prints out the amount of blue, green and red.
something like;
blue value is 0, green value is 0, red value is 0.
You have a byte array (unsigned char) that represents the bytes of your image. Currently you are printing them out one byte at a time.
So to know how to get the individual rgb values you need to know how they were stored.
Its as easy as that, but don't expect someone here to do it for you.
This code is really incomplete. We don't know what your LoadImage() or GetSizeOfImage() function does but one thing is sure is that the way you are representing image in you C program is definitely not the way it is represented. A 'bmp' image has several parts and you should find out the correct way to represent it as a struct. Then you can traverse through it pixel by pixel.
I would suggest using a library pre-written such as 'libbmp' to make your task easy.

Image-processing basics

I have to do some image processing but I don't know where to start. My problem is as follows :-
I have a 2D fiber image (attached with this post), in which the fiber edges are denoted by white color and the inside of the fiber is black. I want to choose any black pixel inside the fiber, and travel from it along the length of the fiber. This will involve comparing the contrast with the surrounding pixels and then travelling in the desired direction. My main aim is to find the length of the fiber
So can someone please tell me atleast where to start? I have made a rough algorithm in my mind on how to approach my problem but I don't know even which software/library to use.
Regards
Adi
EDIT1 - Instead of OpenCV, I started using MATLAB since I found it much easier. I applied the Hough Transform and then Houghpeaks function with max no. of peaks = 100 so that all fibers are included. After that I got the following image. How do I find the length now?
EDIT2 - I found a research article on how to calculate length using Hough Transform but I'm not able to implement it in MATLAB. Someone please help
If your images are all as clean as the one you posted, it's quite an easy problem.
The very first technique I'd try is using a Hough Transform to estimate the line parameters, and there is a good implementation of the algorithm in OpenCV. After you have them, you can estimate their length any way you want, based on whatever other constraints you have.
Problem is two-fold as I see it:
1) locate start and end point from your starting position.
2) decide length between start and end points
Since I don't know your input data I assume it's pixel data with a 0..1 data on each pixel representing it's "whiteness".
In order to find end points I would do some kind of WALKER/AI that tries to walk in different locations, knowing original pos and last traversed direction then continuing along that route until "forward arc" is all white. This assumes fiber is somewhat straight (is it?).
Once you got start and end points you can input these into a a* path finding algorithm and give black pixels a low value and white very high. Then find shortest distance between start and end point, that is the length of the fiber.
Kinda hard to give more detail since I have no idea what techniques you gonna use and some example input data.
Assumptions:
-This image can be considered a binary image where there are only 0s(black) and 1s(white).
-all the fibers are straight and their starting and ending points are on borders.
-we can come up with a limit for thickness in fiber(thickness of white lines).
Under these assumptions:
start scanning the image border(start from wherever you want in whichever direction you want...just be consistent) until you encounter with the first white pixel.At this point your program will understand that this is definitely a starting point. By knowing this, you will gather all the white pixels until you reach a certain limit(or a threshold). The idea here is, if there is a fiber,you will get the angle between the fiber and the border the starting point is on...of course the more pixels you get(the inner you get)the surer you will be in the end. This is the trickiest part. after somehow ending up with a line...you need to calculate the angle(basic trigonometry). Since you know the starting point, the width/height of the image and the angle(or cos/sin of those) you will have the exact coordinate of the end point. Be advised...the exactness here is not really what you might have understood because we may(the thing is we will) have calculation errors in cos/sin values. So you need to hold the threshold as long as possible. So your end point will not be a point actually but rather an area indicating possibility that the ending point is somewhere inside that area. The rest is just simple maths.
Obviously you can put too much detail in this method like checking the both white lines that makes the fiber and deciding which one is longer or you can allow some margin for error since those lines will not be straight properly...this is where a conceptual thickness comes to the stage etc.
Programming:
C# has nice stuff and easy for you to use...I'll put some code here...
newBitmap = new Bitmap(openFileDialog1.FileName);
for (int x = 0; x < newBitmap.Width; x++)
{
for (int y = 0; y < newBitmap.Height; y++)
{
Color originalColor = newBitmap.GetPixel(x, y);//gets the pixel value...
//things go here...
}
}
you'll get the image from a openfiledialog and bitmap the image. inside the nested for loop this code scans the image left-to-right however you can change this...
Since you know C++ and C, I would recommend OpenCV
. It is open-source so if you don't trust anyone like me, you won't have a problem ;). Also if you want to use C# like #VictorS. Mentioned I would use EmguCV which is the C# equivilant of OpenCV. Tutorials for OpenCV are included and for EmguCV can be found on their website. Hope this helps!
Download and install the latest version of 3Dslicer,
Load your data and go the the package>EM segmenter without Atlas>
Choose your anatomical tree in 2 different labels, the back one which is your purpose, the white edges.
The choose the whole 2D image as your ROI and click on segment.
Here is the result, I labeled the edges in green and the black area in white
You can modify your tree and change the structures you define.
You can give more samples to your segmentation to make it more accurate.

Understanding this C function

I'm trying to understand how this function works, I have studied several algorithms to generate sudoku puzzles and found out this one.
Tested the function and it does generates a valid 9x9 Latin Square (Sudoku) Grid.
My problem is that I can't understand how the function works, i do know the struct is formed by to ints, p and b , p will hold the number for the cell in the table, But after that I don't understand why it creates more arrays (tab 1 and tab2) and how it checks for a latin square =/ etc , summarizing , I'm completely lost.
I'm not asking for a line by line explanation, the general concept behind this function.
would help me a lot !
Thanks again <3
int sudoku(struct sudoku tabla[9][9],int x,int y)
{
int tab[9] = {1,1,1,1,1,1,1,1,1};
int i,j;
for(i=0;i<y;++i)
{
tab[tabla[x][i].p-1]=0;
for(i=0;i<x;++i)
{
tab[tabla[i][y].p-1]=0;
}
for(i=(3*(x/3));i<(3*(x/3)+3);++i)
{
for(j=(3*(y/3));j<y;++j)
{
tab[tabla[i][j].p-1]=0;
}
}
int n=0;
for(i=0;i<9;++i)
{
n=n+tab[i];
}
int *tab2;
tab2=(int*)malloc(sizeof(int)*n);
j=0;
for(i=0;i<9;++i)
{ if(tab[i]==1)
{
tab2[j]=i+1;
j++;
}
}
int ny, nx;
if(x==8)
{
ny=y+1;
nx=0;
}
else
{
ny=y;
nx=x+1;
}
while(n>0)
{
int los=rand()%n;
tabla[x][y].p=tab2[los];
tab2[los]=tab2[n-1];
n--;
if(x==8 && y==8)
{
return 1;
}
if (sudoku(tabla,nx,ny)==1)
{
return 1;
}
}
return 0;
}
EDIT
Great, I now understand the structure, thanks lijie's answer. What I still don't understand is the part that tries out the values in random order). I don't understand how it checks if the random value placement is valid without calling the part of the code that checks if the movement is legal, also, after placing the random numbers is it necessary to check if the grid is valid again? –
Basically, the an invocation of the function fills in the positions at and "after" (x, y) in the table tabla, and the function assumes that the positions "prior" to (x, y) are filled, and returns whether a legal "filling in" of the values is possible.
The board is linearized via increasing x, then y.
The first part of the function finds out the values that are legal at (x, y), and the second part tries out the values in a random order, and attempts fills out the rest of the board via a recursive call.
There isn't actually a point in having tab2 because tab can be reused for that purpose, and the function leaks memory (since it is never freed, but aside from these, it works).
Does this make sense to you?
EDIT
The only tricky area in the part that checks for legal number is the third loop (checking the 3x3 box). The condition for j is j < y because those values where j == y are already checked by the second loop.
EDIT2
I nitpick, but the part that counts n and fills tab2 with the legal values should really be
int n = 0;
for (i = 0; i < 9; ++i) if (tab[i]) tab[n++] = i+1;
hence omitting the need for tab2 (the later code can just use tab and n instead of tab2). The memory leak is thusly eliminated.
EDIT
Note that the randomness is only applied to valid values (the order of trying the values is randomized, not the values themselves).
The code follows a standard exhaustive search pattern: try each possible candidate value, immediately returning if the search succeeds, and backtracking with failure if all the candidate values fail.
Try to solve sudoku yourself, and you'll see that there is inherent recursion in finding a solution to it. So, you have function that calls itself until whole board is solved.
As for code, it can be significantly simplified, but it will be for the best if you try to write one yourself.
EDIT:
Here is one from java, maybe it will be similar to what you are trying to do.
A quick description of the principles - ignoring the example you posted. Hopefully with the idea, you can tie it to the example yourself.
The basic approach is something that was the basis of a lot of "Artificial Intelligence", at least as it was seen until about the end of the 80s. The most general solution to many puzzles is basically to try all possible solutions.
So, first you try all possible solutions with a 1 in the top-left corner, then all possible solutions with a 2 in the top-left corner and so on. You recurse to try the options for the second position, third position and so on. This is called exhaustive search - or "brute force".
Trouble is it takes pretty much forever - but you can short-cut a lot of pointless searching.
For example, having placed a 1 in the top-left corner, you recurse. You place a 1 in the next position and recurse again - but now you detect that you've violated two rules (two ones in a row, two ones in a 3x3 block) even without filling in the rest of the board. So you "backtrack" - ie exit the recursion to the previous level and advance to putting a 2 in that second position.
This avoids a lot of searching, and makes things practical. There are further optimisations, as well, if you keep track of the digits still unused in each row, column and block - think about the intersection of those sets.
What I described is actually a solution algorithm (if you allow for some cells already being filled in). Generating a random solved sudoku is the same thing but, for each digit position, you have to try the digits in random order. This also leaves the problem of deciding which cells to leave blank while ensuring the puzzle can still be solved and (much harder) designing puzzles with a level-of-difficulty setting. But in a way, the basic approach to those problems is already here - you can test whether a particular set of left-blank spaces is valid by running the solution algorithm and finding if (and how many) solutions you get, for example, so you can design a search for a valid set of cells left blank.
The level-of-difficulty thing is difficult because it depends on a human perception of difficulty. Hmmm - can I fit "difficult" in there again somewhere...
One approach - design a more sophisticated search algorithm which uses typical human rules-of-thumb in preference to recursive searching, and which judges difficulty as the deepest level of recursion needed. Some rules of thumb might also be judged more advanced than others, so that using them more counts towards difficulty. Obviously difficulty is subjective, so there's no one right answer to how precisely the scoring should be done.
That gives you a measure of difficulty for a particular puzzle. Designing a puzzle directly for a level of difficulty will be hard - but when trying different selections of cells to leave blank, you can try multiple options, keep track of all the difficulty scores, and at the end select the one that was nearest to your target difficulty level.

How to program a fractal?

I do not have any experience with programming fractals. Of course I've seen the famous Mandelbrot images and such.
Can you provide me with simple algorithms for fractals.
Programming language doesn't matter really, but I'm most familiar with actionscript, C#, Java.
I know that if I google fractals, I get a lot of (complicated) information but I would like to start with a simple algorithm and play with it.
Suggestions to improve on the basic algorithm are also welcome, like how to make them in those lovely colors and such.
Programming the Mandelbrot is easy.
My quick-n-dirty code is below (not guaranteed to be bug-free, but a good outline).
Here's the outline:
The Mandelbrot-set lies in the Complex-grid completely within a circle with radius 2.
So, start by scanning every point in that rectangular area.
Each point represents a Complex number (x + yi).
Iterate that complex number:
[new value] = [old-value]^2 + [original-value] while keeping track of two things:
1.) the number of iterations
2.) the distance of [new-value] from the origin.
If you reach the Maximum number of iterations, you're done.
If the distance from the origin is greater than 2, you're done.
When done, color the original pixel depending on the number of iterations you've done.
Then move on to the next pixel.
public void MBrot()
{
float epsilon = 0.0001; // The step size across the X and Y axis
float x;
float y;
int maxIterations = 10; // increasing this will give you a more detailed fractal
int maxColors = 256; // Change as appropriate for your display.
Complex Z;
Complex C;
int iterations;
for(x=-2; x<=2; x+= epsilon)
{
for(y=-2; y<=2; y+= epsilon)
{
iterations = 0;
C = new Complex(x, y);
Z = new Complex(0,0);
while(Complex.Abs(Z) < 2 && iterations < maxIterations)
{
Z = Z*Z + C;
iterations++;
}
Screen.Plot(x,y, iterations % maxColors); //depending on the number of iterations, color a pixel.
}
}
}
Some details left out are:
1.) Learn exactly what the Square of a Complex number is and how to calculate it.
2.) Figure out how to translate the (-2,2) rectangular region to screen coordinates.
You should indeed start with the Mandelbrot set, and understand what it really is.
The idea behind it is relatively simple. You start with a function of complex variable
f(z) = z2 + C
where z is a complex variable and C is a complex constant. Now you iterate it starting from z = 0, i.e. you compute z1 = f(0), z2 = f(z1), z3 = f(z2) and so on. The set of those constants C for which the sequence z1, z2, z3, ... is bounded, i.e. it does not go to infinity, is the Mandelbrot set (the black set in the figure on the Wikipedia page).
In practice, to draw the Mandelbrot set you should:
Choose a rectangle in the complex plane (say, from point -2-2i to point 2+2i).
Cover the rectangle with a suitable rectangular grid of points (say, 400x400 points), which will be mapped to pixels on your monitor.
For each point/pixel, let C be that point, compute, say, 20 terms of the corresponding iterated sequence z1, z2, z3, ... and check whether it "goes to infinity". In practice you can check, while iterating, if the absolute value of one of the 20 terms is greater than 2 (if one of the terms does, the subsequent terms are guaranteed to be unbounded). If some z_k does, the sequence "goes to infinity"; otherwise, you can consider it as bounded.
If the sequence corresponding to a certain point C is bounded, draw the corresponding pixel on the picture in black (for it belongs to the Mandelbrot set). Otherwise, draw it in another color. If you want to have fun and produce pretty plots, draw it in different colors depending on the magnitude of abs(20th term).
The astounding fact about fractals is how we can obtain a tremendously complex set (in particular, the frontier of the Mandelbrot set) from easy and apparently innocuous requirements.
Enjoy!
If complex numbers give you a headache, there is a broad range of fractals that can be formulated using an L-system. This requires a couple of layers interacting, but each is interesting in it own right.
First you need a turtle. Forward, Back, Left, Right, Pen-up, Pen-down. There are lots of fun shapes to be made with turtle graphics using turtle geometry even without an L-system driving it. Search for "LOGO graphics" or "Turtle graphics". A full LOGO system is in fact a Lisp programming environment using an unparenthesized Cambridge Polish syntax. But you don't have to go nearly that far to get some pretty pictures using the turtle concept.
Then you need a layer to execute an L-system. L-systems are related to Post-systems and Semi-Thue systems, and like virii, they straddle the border of Turing Completeness. The concept is string-rewriting. It can be implemented as a macro-expansion or a procedure set with extra controls to bound the recursion. If using macro-expansion (as in the example below), you will still need a procedure set to map symbols to turtle commands and a procedure to iterate through the string or array to run the encoded turtle program. For a bounded-recursion procedure set (eg.), you embed the turtle commands in the procedures and either add recursion-level checks to each procedure or factor it out to a handler function.
Here's an example of a Pythagoras' Tree in postscript using macro-expansion and a very abbreviated set of turtle commands. For some examples in python and mathematica, see my code golf challenge.
There is a great book called Chaos and Fractals that has simple example code at the end of each chapter that implements some fractal or other example. A long time ago when I read that book, I converted each sample program (in some Basic dialect) into a Java applet that runs on a web page. The applets are here: http://hewgill.com/chaos-and-fractals/
One of the samples is a simple Mandelbrot implementation.
Another excellent fractal to learn is the Sierpinski Triangle Fractal.
Basically, draw three corners of a triangle (an equilateral is preferred, but any triangle will work), then start a point P at one of those corners. Move P halfway to any of the 3 corners at random, and draw a point there. Again move P halfway towards any random corner, draw, and repeat.
You'd think the random motion would create a random result, but it really doesn't.
Reference: http://en.wikipedia.org/wiki/Sierpinski_triangle
The Sierpinski triangle and the Koch curve are special types of flame fractals. Flame fractals are a very generalized type of Iterated function system, since it uses non-linear functions.
An algorithm for IFS:es are as follows:
Start with a random point.
Repeat the following many times (a million at least, depending on final image size):
Apply one of N predefined transformations (matrix transformations or similar) to the point. An example would be that multiply each coordinate with 0.5.
Plot the new point on the screen.
If the point is outside the screen, choose randomly a new one inside the screen instead.
If you want nice colors, let the color depend on the last used transformation.
I would start with something simple, like a Koch Snowflake. It's a simple process of taking a line and transforming it, then repeating the process recursively until it looks neat-o.
Something super simple like taking 2 points (a line) and adding a 3rd point (making a corner), then repeating on each new section that's created.
fractal(p0, p1){
Pmid = midpoint(p0,p1) + moved some distance perpendicular to p0 or p1;
fractal(p0,Pmid);
fractal(Pmid, p1);
}
I think you might not see fractals as an algorithm or something to program. Fractals is a concept! It is a mathematical concept of detailed pattern repeating itself.
Therefore you can create a fractal in many ways, using different approaches, as shown in the image below.
Choose an approach and then investigate how to implement it. These four examples were implemented using Marvin Framework. The source codes are available here
Here is a codepen that I wrote for the Mandelbrot fractal using plain javascript and HTML.
Hopefully it is easy to understand the code.
The most complicated part is scale and translate the coordinate systems. Also complicated is making the rainbow palette.
function mandel(x,y) {
var a=0; var b=0;
for (i = 0; i<250; ++i) {
// Complex z = z^2 + c
var t = a*a - b*b;
b = 2*a*b;
a = t;
a = a + x;
b = b + y;
var m = a*a + b*b;
if (m > 10) return i;
}
return 250;
}
The mandelbrot set is generated by repeatedly evaluating a function until it overflows (some defined limit), then checking how long it took you to overflow.
Pseudocode:
MAX_COUNT = 64 // if we haven't escaped to infinity after 64 iterations,
// then we're inside the mandelbrot set!!!
foreach (x-pixel)
foreach (y-pixel)
calculate x,y as mathematical coordinates from your pixel coordinates
value = (x, y)
count = 0
while value.absolutevalue < 1 billion and count < MAX_COUNT
value = value * value + (x, y)
count = count + 1
// the following should really be one statement, but I split it for clarity
if count == MAX_COUNT
pixel_at (x-pixel, y-pixel) = BLACK
else
pixel_at (x-pixel, y-pixel) = colors[count] // some color map.
Notes:
value is a complex number. a complex number (a+bi) is squared to give (aa-b*b+2*abi). You'll have to use a complex type, or include that calculation in your loop.
Sometimes I program fractals for fun and as a challenge. You can find them here. The code is written in Javascript using the P5.js library and can be read directly from the HTML source code.
For those I have seen the algorithms are quite simple, just find the core element and then repeat it over and over. I do it with recursive functions, but can be done differently.
People above are using finding midpoints for sierpinski and Koch, I'd much more recommend copying shapes, scaling them, and then translating them to achieve the "fractal" effect.
Pseudo-code in Java for sierpinski would look something like this:
public ShapeObject transform(ShapeObject originalCurve)
{
Make a copy of the original curve
Scale x and y to half of the original
make a copy of the copied shape, and translate it to the right so it touches the first copied shape
make a third shape that is a copy of the first copy, and translate it halfway between the first and second shape,and translate it up
Group the 3 new shapes into one
return the new shape
}

Resources