Fixed: Made negative sign handling and according direction consistent across all implemenatations

This commit is contained in:
Nikola
2026-07-13 22:42:47 +02:00
parent ee3b02db2d
commit c68d8c7c15
5 changed files with 24 additions and 16 deletions
+3 -1
View File
@@ -123,9 +123,11 @@ void checkInputs(_Bool n,_Bool r,_Bool o,_Bool d,_Bool s) {
} }
// THESE WORK FOR - in calculation
// REMOVE LATER: interesting test command ./tricorn -s -2.0,0.6 -r 0.0010 -n 200 -d 1920,1080 -o image.bmp -C // REMOVE LATER: interesting test command ./tricorn -s -2.0,0.6 -r 0.0010 -n 200 -d 1920,1080 -o image.bmp -C
// AND FOR NEGATIVE HEIGHT: ./tricorn -s -2,-0.5 -r 0.0010 -n 200 -d 1920,-1080 -o image.bmp -C // AND FOR NEGATIVE HEIGHT: ./tricorn -s -2,-0.5 -r 0.0010 -n 200 -d 1920,-1080 -o image.bmp -C
// THIS IS FOR + in calculation
// ./tricorn -s -2.0,-1.5 -d 1200,900 -r 0.003 -n 256 -o tricorn.bmp -C
const char* help_messsage = "Help Message\n\n" const char* help_messsage = "Help Message\n\n"
"Usage:\n" "Usage:\n"
" ./tricorn [OPTIONS]\n\n" " ./tricorn [OPTIONS]\n\n"
+1 -1
View File
@@ -49,8 +49,8 @@ void tricorn(float complex start, size_t width, ssize_t height, float res, unsig
const size_t y_step = (abs_height+thread_count-1)/thread_count; const size_t y_step = (abs_height+thread_count-1)/thread_count;
const float start_r = crealf(start); const float start_r = crealf(start);
const float start_i = cimagf(start);
const float directional_res = (flipped ? -1.0f: 1.0f)*res; const float directional_res = (flipped ? -1.0f: 1.0f)*res;
const float start_i = height > 0 ? cimag(start) : cimag(start) + (height * directional_res);
const_args* consts = malloc(sizeof(*consts)); const_args* consts = malloc(sizeof(*consts));
consts->width = width; consts->width = width;
+9 -8
View File
@@ -17,22 +17,23 @@ void tricorn_V2(float complex start, size_t width, ssize_t height, float res, un
int bytesPerColor = color ? 3 : 1; int bytesPerColor = color ? 3 : 1;
// Absolute height for iteration purposes // Absolute height for iteration purposes
ssize_t actual_height = height < 0 ? (ssize_t)(-height) : height; ssize_t actual_height = height > 0 ? height : (ssize_t)(-height);
ssize_t imag_step = height < 0 ? -1:1;
// Depending on the sign of height we generate the image top-down or bottom up
// As we iterate from the top always, if it is negative we would have to start at the end of the imaginary part and go in the oposite direction when generating
ssize_t imag_direction = height < 0 ? -1 : 1;
float c_start_real = creal(start); float c_start_real = creal(start);
float c_start_imag = cimag(start); float c_start_imag = height > 0 ? cimag(start) : creal(start) + (imag_direction * height * res);;
float c_imag = c_start_imag;
float vertical_step = imag_step * res; float vertical_step = imag_direction * res;
size_t position = 0; size_t position = 0;
float c_imag = c_start_imag;
// Simple iteration over every pixel in the picture // Simple iteration over every pixel in the picture
for(ssize_t y = 0; y < actual_height; y++){ for(ssize_t y = 0; y < actual_height; y++){
// Calculate imaginary part on each row as it stays the same // Calculate imaginary part on each row as it stays the same
float c_real = c_start_real; float c_real = c_start_real;
for(size_t x = 0; x < width; x++){ for(size_t x = 0; x < width; x++){
unsigned value = converge(c_real,c_imag,n); unsigned value = converge(c_real,c_imag,n);
@@ -52,7 +53,7 @@ void tricorn_V2(float complex start, size_t width, ssize_t height, float res, un
c_real += res; c_real += res;
} }
c_imag -= vertical_step; c_imag += vertical_step;
} }
} }
+5 -3
View File
@@ -19,17 +19,19 @@ void tricorn_V3(float complex start, size_t width, ssize_t height, float res, un
// Absolute height for iteration purposes // Absolute height for iteration purposes
ssize_t actual_height = height < 0 ? (ssize_t)(-height) : height; ssize_t actual_height = height < 0 ? (ssize_t)(-height) : height;
ssize_t imag_step = height < 0 ? -1:1;
size_t simd_width = (width / 4) * 4; size_t simd_width = (width / 4) * 4;
// Depending on the sign of height we generate the image top-down or bottom up
// As we iterate the image buffer from the top, if height is negative we would have to start at the end of the imaginary part and go in the oposite direction when generating
ssize_t imag_direction = height < 0 ? -1 : 1;
float c_start_real = creal(start); float c_start_real = creal(start);
float c_start_imag = cimag(start); float c_start_imag = height > 0 ? cimag(start) : cimag(start) + (height * imag_direction) * res;
__m128 four = _mm_set1_ps(4.0f); __m128 four = _mm_set1_ps(4.0f);
__m128 minus_two = _mm_set1_ps(-2.0f); __m128 minus_two = _mm_set1_ps(-2.0f);
for(ssize_t y = 0; y < actual_height;y++) { for(ssize_t y = 0; y < actual_height;y++) {
float c_imag = c_start_imag - (y*imag_step) * res; float c_imag = c_start_imag + (y * imag_direction) * res;
__m128 c_imag_vector = _mm_set1_ps(c_imag); __m128 c_imag_vector = _mm_set1_ps(c_imag);
size_t x = 0; size_t x = 0;
+6 -3
View File
@@ -18,11 +18,13 @@ void tricorn_V4(float complex start, size_t width, ssize_t height, float res, un
// Absolute height for iteration purposes // Absolute height for iteration purposes
ssize_t actual_height = height < 0 ? (ssize_t)(-height) : height; ssize_t actual_height = height < 0 ? (ssize_t)(-height) : height;
ssize_t imag_step = height < 0 ? -1:1;
size_t simd_width = (width / 4) * 4; size_t simd_width = (width / 4) * 4;
// Depending on the sign of height we generate the image top-down or bottom up
// As we iterate the image buffer from the top, if height is negative we would have to start at the end of the imaginary part and go in the oposite direction when generating
ssize_t imag_direction = height < 0 ? -1 : 1;
float c_start_real = creal(start); float c_start_real = creal(start);
float c_start_imag = cimag(start); float c_start_imag = height > 0 ? cimag(start) : cimag(start) + (height * imag_direction) * res;
__m128 four = _mm_set1_ps(4.0f); __m128 four = _mm_set1_ps(4.0f);
__m128 minus_two = _mm_set1_ps(-2.0f); __m128 minus_two = _mm_set1_ps(-2.0f);
@@ -31,7 +33,8 @@ void tricorn_V4(float complex start, size_t width, ssize_t height, float res, un
__m128 c_imag_vector = _mm_set1_ps(c_imag); __m128 c_imag_vector = _mm_set1_ps(c_imag);
float four_res = 4 * res; float four_res = 4 * res;
float vertical_step = imag_step * res;
float vertical_step = imag_direction * res;
__m128 vertical_step_vector = _mm_set1_ps(vertical_step); __m128 vertical_step_vector = _mm_set1_ps(vertical_step);
for(ssize_t y = 0; y < actual_height;y++) { for(ssize_t y = 0; y < actual_height;y++) {