🎉 Initial commit
This commit is contained in:
commit
0be3c70181
10 changed files with 428 additions and 0 deletions
4
.gitignore
vendored
Executable file
4
.gitignore
vendored
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
/bin
|
||||||
|
/obj
|
||||||
|
/output
|
||||||
|
/tmp
|
44
makefile
Executable file
44
makefile
Executable file
|
@ -0,0 +1,44 @@
|
||||||
|
OS := $(shell uname)
|
||||||
|
|
||||||
|
NAME=$(shell pwd | sed "s/.*\///g")
|
||||||
|
|
||||||
|
ifeq (${OS},Darwin)
|
||||||
|
CC=clang++
|
||||||
|
FLAGS=-std=c++11 -stdlib=libc++
|
||||||
|
RUN=${NAME}
|
||||||
|
else ifeq (${OS},Linux)
|
||||||
|
CC=g++
|
||||||
|
FLAGS=-std=c++11 -pthread
|
||||||
|
RUN=${NAME}
|
||||||
|
FILES=$(shell find -name *.cpp)
|
||||||
|
else
|
||||||
|
CC=g++
|
||||||
|
FLAGS=-std=c++11
|
||||||
|
RUN=${NAME}.exe
|
||||||
|
FILES=$(shell find -name *.cpp)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
all: clean build run images video play
|
||||||
|
|
||||||
|
build:
|
||||||
|
${CC} ${FILES} ${FLAGS} -o bin/${RUN}
|
||||||
|
|
||||||
|
run:
|
||||||
|
bin/./${RUN}
|
||||||
|
|
||||||
|
video:
|
||||||
|
ffmpeg -i output/frames/image_%05d.png -c:v libx264 -vf fps=25 -pix_fmt yuv420p output/video.mp4
|
||||||
|
|
||||||
|
play:
|
||||||
|
vlc -L output/video.mp4
|
||||||
|
|
||||||
|
images:
|
||||||
|
mogrify -verbose -format png output/frames/*.ppm
|
||||||
|
rm $(shell find output/frames -name "*.ppm")
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f -r bin/*
|
||||||
|
rm -f -r output/frames/*
|
||||||
|
rm -f output/video.mp4
|
1
src/fractal/buddhabulb.cpp
Executable file
1
src/fractal/buddhabulb.cpp
Executable file
|
@ -0,0 +1 @@
|
||||||
|
#include "buddhabulb.h"
|
6
src/fractal/buddhabulb.h
Executable file
6
src/fractal/buddhabulb.h
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef BUDDHABULB_H_
|
||||||
|
#define BUDDHABULB_H_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
191
src/fractal/buffer.cpp
Executable file
191
src/fractal/buffer.cpp
Executable file
|
@ -0,0 +1,191 @@
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////
|
||||||
|
///////// Buffer Functions
|
||||||
|
/////////
|
||||||
|
|
||||||
|
Buffer::Buffer(int _width, int _height){
|
||||||
|
width = _width;
|
||||||
|
height = _height;
|
||||||
|
|
||||||
|
itterations = 255;
|
||||||
|
samples = 4;
|
||||||
|
contrast = 2;
|
||||||
|
fractal = 1;
|
||||||
|
ratio = (float)width/(float)height;
|
||||||
|
|
||||||
|
setCursor(0, 0, 1, 0);
|
||||||
|
setStart(0, 0, 1, 0);
|
||||||
|
setEnd(0, 0, 1, 0);
|
||||||
|
|
||||||
|
buffer.resize(width, std::vector<int>(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::clear(){
|
||||||
|
maxValue = 0;
|
||||||
|
for(int x=0; x<width; x++){
|
||||||
|
for(int y=0; y<height; y++){
|
||||||
|
buffer[x][y] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::save(std::string _filename){
|
||||||
|
FILE *f = fopen( _filename.c_str(), "w" ); // Write image to PPM file.
|
||||||
|
fprintf(f, "P3\n%d %d\n%d\n", width, height, 255);
|
||||||
|
for(int y=0; y<height; y++){
|
||||||
|
for(int x=0; x<width; x++){
|
||||||
|
|
||||||
|
float bright = map((float)buffer[x][y], 0, (float)maxValue, 0, 1.0);
|
||||||
|
int value = (int)map(pow(bright, 1.0/contrast), 0, 1, 0, 255);
|
||||||
|
|
||||||
|
fprintf(f,"%d %d %d ", value, value, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////
|
||||||
|
///////// Buffer Settings
|
||||||
|
/////////
|
||||||
|
|
||||||
|
int Buffer::getMax(){
|
||||||
|
return maxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::setItterations(int _itterations){
|
||||||
|
itterations = _itterations;
|
||||||
|
}
|
||||||
|
void Buffer::setSamples(int _samples){
|
||||||
|
samples = _samples;
|
||||||
|
}
|
||||||
|
void Buffer::setContrast(float _contrast){
|
||||||
|
contrast = _contrast;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::setFractal(unsigned char _fractal){
|
||||||
|
fractal = _fractal;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Buffer::stats(){
|
||||||
|
std::ostringstream output;
|
||||||
|
output << "Buffer: " << width << "x" << height;
|
||||||
|
output << " Samples: " << samples << " Itterations: " << itterations;
|
||||||
|
output << " Contrast: " << contrast;
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////
|
||||||
|
///////// Translate Coordinates
|
||||||
|
/////////
|
||||||
|
|
||||||
|
void Buffer::setCursor(float _x, float _y, float _s, float _r){
|
||||||
|
cur.x = _x;
|
||||||
|
cur.y = _y;
|
||||||
|
cur.s = _s;
|
||||||
|
cur.r = _r;
|
||||||
|
}
|
||||||
|
void Buffer::setStart(float _x, float _y, float _s, float _r){
|
||||||
|
start.x = _x;
|
||||||
|
start.y = _y;
|
||||||
|
start.s = _s;
|
||||||
|
start.r = _r;
|
||||||
|
}
|
||||||
|
void Buffer::setEnd(float _x, float _y, float _s, float _r){
|
||||||
|
end.x = _x;
|
||||||
|
end.y = _y;
|
||||||
|
end.s = _s;
|
||||||
|
end.r = _r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::cursorUpdate(float _f){
|
||||||
|
cur.x = start.x + (end.x-start.x)*_f;
|
||||||
|
cur.y = start.y + (end.y-start.y)*_f;
|
||||||
|
cur.s = start.s + (end.s-start.s)*_f;
|
||||||
|
cur.r = start.r + (end.r-start.r)*_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Buffer::map(float _v, float _a1, float _a2, float _b1, float _b2){
|
||||||
|
return _b1 + (_v-_a1)*(_b2-_b1)/(_a2-_a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Coords Buffer::translate(int _x, int _y){
|
||||||
|
|
||||||
|
|
||||||
|
float angle = -cur.r * M_PI / 180.0;
|
||||||
|
|
||||||
|
float rx = (float)rand()/(float)RAND_MAX;
|
||||||
|
float ry = (float)rand()/(float)RAND_MAX;
|
||||||
|
|
||||||
|
Coords org; // origin point
|
||||||
|
org.x = ((((float)_x+rx) / (float)width * 2) - 1) * ratio; // X Origin
|
||||||
|
org.y = (((float)_y+ry) / (float)height * 2) - 1; // Y Origin
|
||||||
|
|
||||||
|
float x = cos(angle)*org.x*cur.s - sin(angle)*org.y*cur.s + cur.x; // New X
|
||||||
|
float y = sin(angle)*org.x*cur.s + cos(angle)*org.y*cur.s + cur.y; // New Y
|
||||||
|
|
||||||
|
Coords tmpCords = {x, y};
|
||||||
|
return tmpCords;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pixel Buffer::translate(float _x, float _y){
|
||||||
|
|
||||||
|
float angle = cur.r * M_PI / 180.0;
|
||||||
|
|
||||||
|
Coords org; // origin point
|
||||||
|
org.x = cos(angle)*(_x-cur.x)/cur.s - sin(angle)*(_y-cur.y)/cur.s;
|
||||||
|
org.y = sin(angle)*(_x-cur.x)/cur.s + cos(angle)*(_y-cur.y)/cur.s;
|
||||||
|
|
||||||
|
float x = (org.x/ratio + 1) / 2 * width; // New X
|
||||||
|
float y = (org.y + 1) / 2 * height; // New Y
|
||||||
|
|
||||||
|
Pixel tmpPix = {(int)x, (int)y};
|
||||||
|
return tmpPix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////
|
||||||
|
///////// Render Fractal
|
||||||
|
/////////
|
||||||
|
|
||||||
|
void Buffer::render(int _x, int _y){
|
||||||
|
Coords c = translate(_x, _y);
|
||||||
|
|
||||||
|
float a = c.x;
|
||||||
|
float b = c.y;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
float z = 0;
|
||||||
|
while(n<=itterations){
|
||||||
|
float aa = a*a - b*b;
|
||||||
|
float bb = 2.0 * a * b;
|
||||||
|
a = aa + c.x;
|
||||||
|
b = bb + c.y;
|
||||||
|
if(abs(a + b) > 4){ break; }
|
||||||
|
|
||||||
|
if(fractal==2 || fractal==0){
|
||||||
|
Pixel p = translate(a, b);
|
||||||
|
if(p.x>=0 && p.x<width && p.y>=0 && p.y<height){
|
||||||
|
buffer[p.x][p.y] += 1;
|
||||||
|
if(buffer[p.x][p.y]>maxValue){ maxValue = buffer[p.x][p.y]; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
if(fractal==1 || fractal==0){
|
||||||
|
if(n >= itterations){ n=0; }
|
||||||
|
buffer[_x][_y] += n;
|
||||||
|
if(buffer[_x][_y] > maxValue){ maxValue = buffer[_x][_y]; }
|
||||||
|
}
|
||||||
|
}
|
78
src/fractal/buffer.h
Executable file
78
src/fractal/buffer.h
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
#ifndef BUFFER_H_
|
||||||
|
#define BUFFER_H_
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
#define M_PI 3.14159265358979323846 /* pi */
|
||||||
|
|
||||||
|
|
||||||
|
#define ALL 0
|
||||||
|
#define MANDELBROT 1
|
||||||
|
#define BUDDHABROT 2
|
||||||
|
#define BUDDHABULB 3
|
||||||
|
|
||||||
|
|
||||||
|
struct Cur{
|
||||||
|
float x; // X position of cursur
|
||||||
|
float y; // Y position of cursur
|
||||||
|
float s; // Scale of cursur
|
||||||
|
float r; // Rotation of cursur
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Coords{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Pixel{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Buffer{
|
||||||
|
private:
|
||||||
|
std::vector<std::vector<int>> buffer; // Buffer array
|
||||||
|
Cur cur; // Viewing cursur
|
||||||
|
Cur start;
|
||||||
|
Cur end;
|
||||||
|
float ratio; // Ratio of image width to hight
|
||||||
|
int itterations; // Number of itterations for render (defult 255)
|
||||||
|
float contrast; // Log contrast of render output (defult 2)
|
||||||
|
int maxValue; // Maximum value of array to normalise
|
||||||
|
unsigned char fractal; // Fractal type
|
||||||
|
public:
|
||||||
|
int width; // Width of buffer
|
||||||
|
int height; // Height of buffer
|
||||||
|
int samples; // Rendering subresolution (defult 2)
|
||||||
|
|
||||||
|
Buffer(int _width, int _height); // Constructor
|
||||||
|
void save(std::string _filename); // Save buffer to PPM image
|
||||||
|
void clear(); // Clear buffer
|
||||||
|
std::string stats(); // Print buffer stats to console
|
||||||
|
|
||||||
|
int getMax(); // Return max value in buffer
|
||||||
|
void setItterations(int _itterations); // Set number of render itterations
|
||||||
|
void setSamples(int _subres); // Set subresolution of render
|
||||||
|
void setContrast(float _contrast); // Set contast of output image
|
||||||
|
void setFractal(unsigned char _fractal); // set type of fractal to render
|
||||||
|
|
||||||
|
void setCursor(float _x, float _y, float _s, float _r);
|
||||||
|
void setStart(float _x, float _y, float _s, float _r);
|
||||||
|
void setEnd(float _x, float _y, float _s, float _r);
|
||||||
|
void cursorUpdate(float _f);
|
||||||
|
Coords translate(int _x, int _y);
|
||||||
|
Pixel translate(float _x, float _y);
|
||||||
|
float map(float _v, float _a1, float _a2, float _b1, float _b2);
|
||||||
|
|
||||||
|
void render(int _x, int _y);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
33
src/fractal/timer.cpp
Executable file
33
src/fractal/timer.cpp
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
|
||||||
|
Timer::Timer(){
|
||||||
|
startTime = clock();
|
||||||
|
std::cout << startTime << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Timer::getTime(){
|
||||||
|
clock_t elapsedTime = (clock() - startTime) / CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
unsigned char seconds = elapsedTime % 60;
|
||||||
|
unsigned char minutes = (elapsedTime / 60) % 60;
|
||||||
|
unsigned char hours = (elapsedTime / 3600) % 24;
|
||||||
|
unsigned char days = elapsedTime / 86400;
|
||||||
|
|
||||||
|
std::string tmpString = "";
|
||||||
|
|
||||||
|
if(days<10){ tmpString += "0"; }
|
||||||
|
tmpString += std::to_string(days);
|
||||||
|
|
||||||
|
if(hours<10){ tmpString += ":0"; }else{ tmpString+=":"; }
|
||||||
|
tmpString += std::to_string(hours);
|
||||||
|
|
||||||
|
if(minutes<10){ tmpString += ":0"; }else{ tmpString+=":"; }
|
||||||
|
tmpString += std::to_string(minutes);
|
||||||
|
|
||||||
|
if(seconds<10){ tmpString += ":0"; }else{ tmpString+=":"; }
|
||||||
|
tmpString += std::to_string(seconds);
|
||||||
|
|
||||||
|
return tmpString;
|
||||||
|
}
|
18
src/fractal/timer.h
Executable file
18
src/fractal/timer.h
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef TIMER_H_
|
||||||
|
#define TIMER_H_
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Timer{
|
||||||
|
private:
|
||||||
|
clock_t startTime;
|
||||||
|
public:
|
||||||
|
Timer();
|
||||||
|
std::string getTime();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
40
src/main.cpp
Executable file
40
src/main.cpp
Executable file
|
@ -0,0 +1,40 @@
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
Buffer buffer(1920, 1080);
|
||||||
|
|
||||||
|
int main(int argc, char** argv){
|
||||||
|
|
||||||
|
Timer timer;
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
buffer.setContrast(2);
|
||||||
|
buffer.setSamples(8);
|
||||||
|
buffer.setItterations(255);
|
||||||
|
buffer.setFractal(ALL);
|
||||||
|
|
||||||
|
buffer.setStart(0, 0, 1, -10);
|
||||||
|
buffer.setEnd(0, 0, 0.8, 15);
|
||||||
|
|
||||||
|
std::cout << std::endl << buffer.stats() << std::endl << std::endl;
|
||||||
|
|
||||||
|
int frames = 200;
|
||||||
|
for(int f=0; f<=frames; f++){
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
buffer.cursorUpdate( (float)f/(float)frames );
|
||||||
|
for(int y=0; y<buffer.height; y++){
|
||||||
|
for(int x=0; x<buffer.width; x++){
|
||||||
|
for(int s=0; s<buffer.samples; s++){
|
||||||
|
buffer.render(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << " " << timer.getTime() << " Frame: " << f << " " << 100*y/buffer.height << "% maxValue: " << buffer.getMax() << " \r" << std::flush;
|
||||||
|
}
|
||||||
|
std::ostringstream filename;
|
||||||
|
filename << "output/frames/image_" << std::setfill('0') << std::setw(5) << f << ".ppm";
|
||||||
|
buffer.save( filename.str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl << std::endl << "Finished!" << std::endl << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
13
src/main.h
Executable file
13
src/main.h
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef MAIN_H_
|
||||||
|
#define MAIN_H_
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "fractal/buffer.h"
|
||||||
|
#include "fractal/buddhabulb.h"
|
||||||
|
#include "fractal/timer.h"
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue