Skip to content

Commit 61d621a

Browse files
update prime-art
1 parent d160615 commit 61d621a

11 files changed

+73
-9
lines changed

image/PNG/include/png.hxx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class PNG {
4242
}
4343

4444
public:
45-
PNG(const std::string &fileName) : fileName(fileName) {}
45+
PNG(std::string fileName) : fileName(fileName) {}
4646

4747
~PNG() {
4848
if (pngPtr) {
@@ -81,9 +81,14 @@ class PNG {
8181
}
8282

8383
bool write() {
84+
if (pngPtr && infoPtr) {
85+
png_destroy_write_struct(&pngPtr, &infoPtr);
86+
pngPtr = nullptr;
87+
infoPtr = nullptr;
88+
}
89+
8490
output.open(fileName, std::ios::binary);
8591
if (!output) return false;
86-
8792
int rowBytes = imageWidth * get_channel_count();
8893
if (imageBuffer.size() != static_cast<size_t>(imageHeight * rowBytes))
8994
imageBuffer.resize(imageHeight * rowBytes);
@@ -126,4 +131,9 @@ class PNG {
126131
void set_color_type(png_byte ct) { imageColorType = ct; }
127132
void set_bit_depth(png_byte bd) { imageBitDepth = bd; }
128133
void set_buffer(const std::vector<png_byte> &buf) { imageBuffer = buf; }
134+
void set_filename(const std::string &fileName) {
135+
if (input.is_open()) input.close();
136+
if (output.is_open()) output.close();
137+
this->fileName = fileName;
138+
}
129139
};

image/PNG/src/prime-art.cxx

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,55 @@ int main(int argc, const char* argv[]) {
4242
else
4343
HEIGHT = WIDTH;
4444
AREA = WIDTH * HEIGHT;
45-
std::string filename =
46-
"prime-spiral-" + std::to_string(WIDTH) + "-" + std::to_string(HEIGHT) + ".png";
45+
std::string filename = "prime-uniform-" + std::to_string(WIDTH) + "-" +
46+
std::to_string(HEIGHT) + ".png";
47+
std::string filename2 = "prime-spiral-" + std::to_string(WIDTH) + "-" +
48+
std::to_string(HEIGHT) + ".png";
4749
PNG writer(filename);
4850
writer.set_width(WIDTH);
4951
writer.set_height(HEIGHT);
5052
writer.set_color_type(PNG_COLOR_TYPE_RGB);
5153
writer.set_bit_depth(8);
5254

53-
std::vector<png_byte> data(AREA * 3);
55+
std::vector<png_byte> data(AREA * 3), data2(AREA * 3);
5456

5557
Prime<uint64_t> prime;
56-
const float scaleR = 0.5 * sqrt(2);
57-
const float scaleTheta = std::log(scaleR);
58+
59+
/* Solve r untuk setiap i
60+
*
61+
* ketika i = s * s gw mau r = halfdiagonal = sqrt(2)/2 * s
62+
* sehingga r = dR * s * s = sqrt(2)/2 *s
63+
* r = d R * s = sqrt(2)
64+
* karena s * s = i
65+
* s haruslah sqrt(i)
66+
* sehingga r = dR * sqrt(i)
67+
*/
68+
69+
/* Solve dR
70+
*
71+
* r(s*s) haruslah dR * s
72+
* sehingga dR = r(s*s)/s
73+
* karena r(s*s) = sqrt(2)/2 *s
74+
* dR = sqrt(2)/2
75+
*/
76+
77+
/* Solve dTheta
78+
*
79+
* anggap r tetap sehingga ada 2pi * r unit titik
80+
* karena ada 2pi*r titik dan pada titik terakhir theta harus = 2pi
81+
* maka dTheta = 1/r
82+
* karena r = dR * sqrt(i) dan dR = sqrt(2)/2 maka
83+
* dTheta = 2/sqrt(2) * sqrt(i)
84+
*/
85+
86+
const float dR = 0.5 * std::sqrtf(2.0f);
5887
const uint64_t cx = WIDTH / 2;
5988
const uint64_t cy = HEIGHT / 2;
6089

6190
for (uint32_t i : prime.from_range_limit(AREA)) {
62-
float r = scaleR * std::sqrt(i);
63-
float theta = scaleTheta * i;
91+
float dTheta = 2 / std::sqrtf(2 * i);
92+
float r = dR * std::sqrtf(i);
93+
float theta = dTheta * i;
6494
uint64_t x = uint64_t(cx + r * std::cos(theta));
6595
uint64_t y = uint64_t(cy + r * std::sin(theta));
6696
if (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT) {
@@ -77,4 +107,28 @@ int main(int argc, const char* argv[]) {
77107
std::cout << "berhasil ditulis ke " << filename << std::endl;
78108
else
79109
std::cout << "gagal menulis ke " << filename << std::endl;
110+
111+
// spiral logarithmic cek ini
112+
// https://en.wikipedia.org/wiki/Logarithmic_spiral
113+
const float dTheta = std::log(dR);
114+
for (uint32_t i : prime.from_range_limit(AREA)) {
115+
float r = dR * std::sqrtf(i);
116+
float theta = dTheta * i;
117+
uint64_t x = uint64_t(cx + r * std::cos(theta));
118+
uint64_t y = uint64_t(cy + r * std::sin(theta));
119+
if (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT) {
120+
uint64_t n = y * WIDTH + x;
121+
uint64_t base = (n) * 3;
122+
data2[base + 0] = 255;
123+
data2[base + 1] = 255;
124+
data2[base + 2] = 255;
125+
}
126+
}
127+
128+
writer.set_filename(filename2);
129+
writer.set_buffer(data2);
130+
if (writer.write())
131+
std::cout << "berhasil ditulis ke " << filename2 << std::endl;
132+
else
133+
std::cout << "gagal menulis ke " << filename2 << std::endl;
80134
}

prime-spiral-10-10.png

114 Bytes
Loading

prime-spiral-1000-1000.png

384 Bytes
Loading

prime-spiral-1024-1024.png

-63 Bytes
Loading

prime-spiral-10240-10240.png

-2.84 KB
Loading

prime-uniform-10-10.png

109 Bytes
Loading

prime-uniform-100-100.png

1.26 KB
Loading

prime-uniform-1000-1000.png

77.9 KB
Loading

prime-uniform-1024-1024.png

81.1 KB
Loading

0 commit comments

Comments
 (0)