Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <bmpfile.h>
- #define PI 3.141592653589793
- #define PI2 (PI * 2.0)
- #define RAND_MOD(mp_mod) (rand() % (mp_mod))
- #define RAND_FLOAT() (rand() / (RAND_MAX - 0.0))
- #define RGBA(mp_r, mp_g, mp_b, mp_a) { (mp_b), (mp_g), (mp_r), (mp_a) }
- #define RGB(mp_r, mp_g, mp_b) RGBA(mp_r, mp_g, mp_b, 255)
- struct point2d
- {
- double x;
- double y;
- };
- struct point2d
- point2d_get_scaled(
- struct point2d p0,
- struct point2d p1,
- double scale
- ){
- struct point2d spt = {
- p0.x + (p1.x - p0.x) * scale,
- p0.y + (p1.y - p0.y) * scale
- };
- return spt;
- }
- struct cgame_bmp
- {
- bmpfile_t* bmp;
- struct point2d* points;
- size_t points_max;
- unsigned int width;
- unsigned int height;
- };
- int
- cgame_bmp_create(
- struct cgame_bmp* const self,
- unsigned int width,
- unsigned int height,
- size_t points_max
- ){
- if ((self->bmp = bmp_create(width, height, 24)))
- {
- if ((self->points = malloc(sizeof(*self->points) * points_max)))
- {
- // Set background to black
- for (unsigned int y = 0; y < height; ++y)
- {
- for (unsigned int x = 0; x < width; ++x)
- {
- bmp_set_pixel(self->bmp, x, y, (rgb_pixel_t)RGB(0, 0, 0));
- }
- }
- // Create vertices
- {
- double astep = PI2 / points_max;
- for (size_t i = 0; i < points_max; ++i)
- {
- double angle = astep * i;
- self->points[i].x = cos(angle) * fabs(cos(angle));
- self->points[i].y = sin(angle) * fabs(sin(angle));
- printf("[%u]:(%lf, %lf)\n", i, self->points[i].x, self->points[i].y);
- }
- }
- // Fill in the rest
- self->points_max = points_max;
- self->width = width;
- self->height = height;
- return 1;
- }
- bmp_destroy(self->bmp);
- }
- return 0;
- }
- void
- cgame_bmp_destroy(
- struct cgame_bmp const* const self
- ){
- free(self->points);
- bmp_destroy(self->bmp);
- }
- void
- cgame_bmp_plot(
- struct cgame_bmp const* const self,
- double scale,
- unsigned int imax
- ){
- // An offset to allow things to settle into the attractor.
- size_t const plot_offset = 100;
- // Get a scaled radius based on height of the bitmap
- double radius = self->height / 2.0 - 2.0;
- // Get a random point
- struct point2d z = {
- -1.0 + RAND_FLOAT() * 2.0,
- -1.0 + RAND_FLOAT() * 2.0
- };
- // Play the game
- for (unsigned int i = 0; i < imax + plot_offset; ++i)
- {
- // Get a random point
- struct point2d* rpt = &self->points[RAND_MOD(self->points_max)];
- // Get the mid point between z and rpt
- struct point2d mpt = point2d_get_scaled(z, *rpt, scale);
- // Map the mid point to the bitmap via radius
- // This is centered...
- struct point2d mbpt = {
- floor(mpt.x * radius + self->width / 2.0),
- floor(mpt.y * radius + self->height / 2.0)
- };
- // Skip the first couple of iterations
- if (i >= plot_offset)
- {
- // Plot the point in white on the bitmap plane
- bmp_set_pixel(
- self->bmp,
- (unsigned int)mbpt.x,
- (unsigned int)mbpt.y,
- (rgb_pixel_t)RGB(255, 0, 0)
- );
- }
- // Update z to be the new point
- z = mpt;
- // Update the console
- printf("computing iteration: %u or %u\r", i, imax + plot_offset);
- }
- }
- int main_app()
- {
- struct cgame_bmp cgame;
- if (cgame_bmp_create(&cgame, 640, 640, 8))
- {
- cgame_bmp_plot(&cgame, 0.66666, 100000);
- // Save the bitmap to a file
- bmp_save(cgame.bmp, "output.bmp");
- cgame_bmp_destroy(&cgame);
- return 1;
- }
- return 0;
- }
- int main(void)
- {
- if (main_app())
- {
- puts("\n\nThe Chaos Game Worked!");
- }
- else
- {
- puts("\n\nThe Chaos Game Did NOT Work!! ;^o");
- }
- // Open the bitmap...
- //system("mspaint output.bmp");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment