aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example.cc45
-rw-r--r--src/imgen.cc48
-rw-r--r--src/imgen.h22
3 files changed, 75 insertions, 40 deletions
diff --git a/example.cc b/example.cc
index 18d0e78..22f5c19 100644
--- a/example.cc
+++ b/example.cc
@@ -3,44 +3,49 @@
#include <cmath>
#include <algorithm>
-template <int p>
-double minkowski_metric(int refX, int refY, int x, int y) {
- return std::pow(
- std::pow(std::abs(refX - x), p) + std::pow(std::abs(refY - y), p),
- 1.0/p
- );
+int minkowski_metric(double p, int refX, int refY, int x, int y) {
+ return static_cast<int>(std::nearbyint(
+ std::pow(
+ std::pow(std::abs(refX - x), p) + std::pow(std::abs(refY - y), p),
+ 1.0 / p
+ )
+ ));
}
-double euclidean_metric(int refX, int refY, int x, int y) {
- return minkowski_metric<2>(refX, refY, x, y);
+int euclidean_metric(int refX, int refY, int x, int y) {
+ return minkowski_metric(2, refX, refY, x, y);
}
int manhattan_metric(int refX, int refY, int x, int y) {
- return minkowski_metric<1>(refX, refY, x, y);
+ return minkowski_metric(1, refX, refY, x, y);
}
int main(int, char*[]) {
using refpos = std::tuple<int, int, imgen::color>;
- std::array<refpos, 5> ref{
- refpos(100, 50, imgen::color(255, 0, 0 )),
- refpos(490, 300, imgen::color(0, 255, 0 )),
- refpos(250, 250, imgen::color(0, 0, 255)),
- refpos(400, 20, imgen::color(100, 10, 100)),
- refpos(60, 400, imgen::color(20, 60, 300))
+ std::array<refpos, 9> ref{
+ refpos( 0, 0, imgen::color(255, 0, 0 )),
+ refpos( 100, 100, imgen::color(0, 255, 0 )),
+ refpos(-100, 100, imgen::color(0, 0, 255 )),
+ refpos( 100, -100, imgen::color(255, 255, 0 )),
+ refpos(-100, -100, imgen::color(0, 255, 255 )),
+ refpos( 200, 200, imgen::color(255, 0, 0 )),
+ refpos(-200, 200, imgen::color(0, 255, 0 )),
+ refpos( 200, -200, imgen::color(0, 255, 255 )),
+ refpos(-200, -200, imgen::color(255, 255, 0 ))
};
imgen::write_ppm(
"test.ppm",
- 500,
- 500,
- [&ref](std::size_t x, std::size_t y) -> imgen::color {
+ 512,
+ 512,
+ [&ref](std::ptrdiff_t x, std::ptrdiff_t y) -> imgen::color {
const refpos& nearest = *std::min_element(
ref.begin(),
ref.end(),
[x, y](const refpos& a, const refpos& b) -> bool {
- return minkowski_metric<5>(std::get<0>(a), std::get<1>(a), x, y)
- < minkowski_metric<5>(std::get<0>(b), std::get<1>(b), x, y);
+ return euclidean_metric(std::get<0>(a), std::get<1>(a), x, y)
+ < euclidean_metric(std::get<0>(b), std::get<1>(b), x, y);
}
);
diff --git a/src/imgen.cc b/src/imgen.cc
index d574672..25731e1 100644
--- a/src/imgen.cc
+++ b/src/imgen.cc
@@ -1,34 +1,50 @@
#include "imgen.h"
-#include <fstream>
-
namespace {
inline void write_color(std::ofstream& out, const imgen::color& color) {
- out << std::get<0>(color);
- out << std::get<1>(color);
- out << std::get<2>(color);
+ out << std::get<0>(color)
+ << std::get<1>(color)
+ << std::get<2>(color);
}
}
namespace imgen {
+ppm_pixel_stream::ppm_pixel_stream(
+ const std::string& path,
+ const std::size_t width,
+ const std::size_t height
+): stream_() {
+ this->stream_.open(path, std::ios::binary | std::ios::out);
+ this->stream_.sync_with_stdio(false);
+
+ this->stream_ << "P6\n" << width << " " << height << "\n255\n";
+}
+
+ppm_pixel_stream& ppm_pixel_stream::operator<<(const color& value) {
+ write_color(this->stream_, value);
+
+ return *this;
+}
+
void write_ppm(
- const std::string& path,
- const std::size_t sizeX,
- const std::size_t sizeY,
- std::function<color(std::size_t, std::size_t)> generator
+ const std::string& path,
+ const std::size_t width,
+ const std::size_t height,
+ std::function<color(std::ptrdiff_t, std::ptrdiff_t)> generator
) {
- std::ofstream out;
- out.open(path, std::ios::binary | std::ios::out);
- out.sync_with_stdio(false);
+ ppm_pixel_stream file(path, width, height);
- out << "P6\n" << sizeX << " " << sizeY << "\n255\n";
+ const std::ptrdiff_t min_y = height / 2 * -1;
+ const std::ptrdiff_t max_y = height / 2;
+ const std::ptrdiff_t min_x = width / 2 * -1;
+ const std::ptrdiff_t max_x = width / 2;
- for ( std::size_t posY = 0; posY < sizeY; ++posY ) {
- for ( std::size_t posX = 0; posX < sizeX; ++posX ) {
- write_color(out, generator(posX, posY));
+ for ( std::ptrdiff_t posY = min_y; posY < max_y; ++posY ) {
+ for ( std::ptrdiff_t posX = min_x; posX < max_x; ++posX ) {
+ file << generator(posX, posY);
}
}
}
diff --git a/src/imgen.h b/src/imgen.h
index 5ddbaf6..35b798d 100644
--- a/src/imgen.h
+++ b/src/imgen.h
@@ -1,16 +1,30 @@
#include <string>
#include <utility>
+#include <fstream>
#include <functional>
namespace imgen {
using color = std::tuple<std::uint8_t, std::uint8_t, std::uint8_t>;
+class ppm_pixel_stream {
+ public:
+ ppm_pixel_stream(const std::string& path,
+ const std::size_t width,
+ const std::size_t height);
+
+ ppm_pixel_stream& operator<<(const color& value);
+
+ private:
+ std::ofstream stream_;
+
+};
+
void write_ppm(
- const std::string& path,
- const std::size_t sizeX,
- const std::size_t sizeY,
- std::function<color(std::size_t, std::size_t)> generator
+ const std::string& path,
+ const std::size_t sizeX,
+ const std::size_t sizeY,
+ std::function<color(std::ptrdiff_t, std::ptrdiff_t)> generator
);
}