WIP, working
This commit is contained in:
parent
e80c22afc0
commit
29bc09d5fe
|
|
@ -6,7 +6,15 @@
|
|||
// Configure tool-specific properties.
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {},
|
||||
"settings": {
|
||||
"conan-extension.installArgs": [
|
||||
"-of build",
|
||||
"-b \"*\"",
|
||||
"-s build_type=Debug"
|
||||
],
|
||||
"cmake.buildDirectory": "${workspaceFolder}/build",
|
||||
"cmake.installPrefix": "${workspaceFolder}/install"
|
||||
},
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools",
|
||||
"twxs.cmake",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
find_package(Boost 1.84.0 REQUIRED COMPONENTS headers CONFIG)
|
||||
find_package(Boost 1.89.0 REQUIRED COMPONENTS headers CONFIG)
|
||||
find_package(JPEG REQUIRED)
|
||||
|
||||
project(http-mandelbrot)
|
||||
|
|
@ -6,6 +6,7 @@ project(http-mandelbrot)
|
|||
add_executable(
|
||||
${PROJECT_NAME}
|
||||
./src/main.cpp
|
||||
./src/mandelbrot.cpp
|
||||
)
|
||||
|
||||
set_property(
|
||||
|
|
|
|||
|
|
@ -24,19 +24,22 @@
|
|||
max-height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div id="map" style="width: 100%; height: 100%;"></div>
|
||||
<div id="map" style="width: 100%; height: 100%;">
|
||||
<div class="leaflet-bottom leaflet-left">
|
||||
<input type="button" id="Btn1" value="Btn1" onclick="" class="btnStyle span3" />
|
||||
<input type="button" id="Btn2" value="Btn2" onclick="SaveRoutes()" class="btnStyle span3 leaflet-control" />
|
||||
<input type="button" id="Btn3" value="Btn3" onclick="editRoutes()" class="btnStyle span3 leaflet-control" />
|
||||
<span id="studentsCount" class="lblStyle span3 leaflet-control"> Ikke rutesat: </span>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
const map = L.map('map', {crs: L.CRS.Simple}).setView([0.0, 0.0], 1);
|
||||
const map = L.map('map', {crs: L.CRS.Simple, zoomSnap: 0}).setView([0.0, 0.0], 1);
|
||||
|
||||
const tiles = L.tileLayer('http://localhost:9800/render_{x}_{y}_{z}', {
|
||||
const tiles = L.tileLayer('/render_z{z}x{x}y{y}w256h256ar8.0ai0.0maxiter200.jpg', {
|
||||
maxZoom: 1000
|
||||
}).addTo(map);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,90 +21,10 @@
|
|||
#include <vector>
|
||||
#include <complex>
|
||||
#include <regex>
|
||||
|
||||
#include "mandelbrot.hpp"
|
||||
namespace
|
||||
{
|
||||
const std::regex regex_renderpath(R"REGEX(\/render_(-?\d+)_(-?\d+)_(\d+))REGEX");
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
class window
|
||||
{
|
||||
public:
|
||||
window(T x_min, T x_max, T y_min, T y_max)
|
||||
: m_x_min(x_min), m_x_max(x_max), m_y_min(y_min), m_y_max(y_max)
|
||||
{}
|
||||
|
||||
T size() const {
|
||||
return width() * height();
|
||||
}
|
||||
|
||||
T width() const {
|
||||
return m_x_max - m_x_min;
|
||||
}
|
||||
|
||||
T height() const {
|
||||
return m_y_max - m_y_min;
|
||||
}
|
||||
|
||||
T x_min() const {return m_x_min;}
|
||||
T x_max() const {return m_x_max;}
|
||||
T y_min() const {return m_y_min;}
|
||||
T y_max() const {return m_y_max;}
|
||||
|
||||
private:
|
||||
T m_x_min;
|
||||
T m_x_max;
|
||||
T m_y_min;
|
||||
T m_y_max;
|
||||
};
|
||||
|
||||
// Convert a pixel coordinate to the complex domain
|
||||
std::complex<double> scale(const window<int>& scr, const window<double>& fr, const std::complex<double>& c)
|
||||
{
|
||||
return std::complex<double>(c.real() / (double)scr.width() * fr.width() + fr.x_min(),
|
||||
c.imag() / (double)scr.height() * fr.height() + fr.y_min());
|
||||
}
|
||||
|
||||
int escape(const std::complex<double>& c,
|
||||
int iter_max,
|
||||
const std::function<std::complex<double>(std::complex<double>, std::complex<double>)>& func)
|
||||
{
|
||||
std::complex<double> z(0);
|
||||
int iter = 0;
|
||||
|
||||
while (abs(z) < 2.0 && iter < iter_max) {
|
||||
z = func(z, c);
|
||||
iter++;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
void fractal(
|
||||
const window<int>& scr,
|
||||
const window<double>&fract,
|
||||
int max_iterations,
|
||||
const std::function<std::complex<double>(std::complex<double>, std::complex<double>)>& fractal_fn,
|
||||
const std::function<void(int x, int y, int num_iter)>& painter)
|
||||
{
|
||||
for(int y = scr.y_min(); y < scr.y_max(); ++y)
|
||||
{
|
||||
for(int x = scr.x_min(); x < scr.x_max(); ++x)
|
||||
{
|
||||
auto num_iter = escape(
|
||||
scale(scr,
|
||||
fract,
|
||||
std::complex<double>{double(y), double(x)}
|
||||
),
|
||||
max_iterations,
|
||||
fractal_fn);
|
||||
|
||||
painter(x,y,num_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::regex regex_renderpath(R"REGEX(\/render_z(\d+)x(-?\d+)y(-?\d+)w(\d+)h(\d+)ar(-?\d+\.\d+)ai(-?\d+\.\d+)maxiter(\d+).jpg)REGEX");
|
||||
|
||||
constexpr unsigned int config_max_simultanious_requests = 10;
|
||||
constexpr uint64_t config_request_body_limit = (10 * 1024);
|
||||
|
|
@ -141,19 +61,26 @@ void fractal(
|
|||
return;
|
||||
}
|
||||
|
||||
std::cout << "GET: " << target << std::endl;
|
||||
std::smatch base_match;
|
||||
std::string tmp(target);
|
||||
if (std::regex_match(tmp, base_match, regex_renderpath) && base_match.size() == 4)
|
||||
if (std::regex_match(tmp, base_match, regex_renderpath) && base_match.size() == 9)
|
||||
{
|
||||
double offset_y = std::stoi(base_match[1]);
|
||||
double offset_x = std::stoi(base_match[2]);
|
||||
double z = std::stoi(base_match[3]);
|
||||
int z = std::stoi(base_match[1]);
|
||||
int offset_y = std::stoi(base_match[2]);
|
||||
int offset_x = std::stoi(base_match[3]);
|
||||
int width = std::stoi(base_match[4]);
|
||||
int height = std::stoi(base_match[5]);
|
||||
double a_real = std::stof(base_match[6]);
|
||||
double a_img = std::stof(base_match[7]);
|
||||
int max_iter = std::stoi(base_match[8]);
|
||||
std::complex<float> factor_a(a_real, a_img);
|
||||
|
||||
auto renderfn = [offset_y, offset_x, z, req, target, rs, tmp]() mutable
|
||||
auto renderfn = [offset_y, offset_x, z, width, height, factor_a, max_iter, req, target, rs, tmp]() mutable
|
||||
{
|
||||
constexpr int pixel_width = 256;
|
||||
constexpr int pixel_height = 256;
|
||||
constexpr int max_iterations = 255;
|
||||
int pixel_width = width;
|
||||
int pixel_height = height;
|
||||
int max_iterations = max_iter;
|
||||
|
||||
|
||||
boost::gil::rgb8_image_t image(pixel_width,pixel_height);
|
||||
|
|
@ -164,7 +91,7 @@ void fractal(
|
|||
{
|
||||
if(x >= 0 && y >= 0 && x < pixel_width && y < pixel_height)
|
||||
{
|
||||
bmrshared::color c({.h=(num_iter*5)%360,.s=(0.5+(num_iter/200.0)), .v=1.0});
|
||||
bmrshared::color c({.h=(num_iter*2)%360,.s=1.0, .v=1.0});
|
||||
auto crgb = c.rgb();
|
||||
uint8_t r = crgb.r * 255;
|
||||
uint8_t g = crgb.g * 255;
|
||||
|
|
@ -176,23 +103,19 @@ void fractal(
|
|||
}
|
||||
};
|
||||
|
||||
auto fract_fn = [](std::complex <double> z, std::complex<double> c) -> std::complex<double>
|
||||
{
|
||||
return z * z + c;
|
||||
};
|
||||
|
||||
auto zoomfactor = 1.0/std::pow(2, z);
|
||||
|
||||
fractal(window<int>{0,pixel_width, 0,pixel_height},
|
||||
window<double>{offset_x * zoomfactor, (offset_x + 1)*zoomfactor, offset_y * zoomfactor ,(offset_y + 1)*zoomfactor},
|
||||
max_iterations,
|
||||
fract_fn,
|
||||
painter);
|
||||
const auto zoomfactor = 1.0/std::pow(2, z);
|
||||
window<float> src_window{offset_x * zoomfactor, (offset_x + 1)*zoomfactor, offset_y * zoomfactor ,(offset_y + 1)*zoomfactor};
|
||||
window<float> dst_window{0,pixel_width, 0,pixel_height};
|
||||
|
||||
mandelbrot<float> fractal(src_window, dst_window, max_iterations, factor_a);
|
||||
fractal.apply(painter);
|
||||
|
||||
std::stringstream out_buffer( std::ios_base::out | std::ios_base::binary );
|
||||
boost::gil::write_view(out_buffer,
|
||||
boost::gil::view(image),
|
||||
boost::gil::image_write_info<boost::gil::jpeg_tag>(70));
|
||||
boost::gil::image_write_info<boost::gil::jpeg_tag>(90));
|
||||
|
||||
auto& ok = rs.create_response<boost::beast::http::response<boost::beast::http::string_body>>(boost::beast::http::status::ok, req.version());
|
||||
ok.set(boost::beast::http::field::server, BOOST_BEAST_VERSION_STRING);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
// GNU Lesser General Public License v3.0
|
||||
// Copyright (c) 2025 Bart Beumer <bart@4beumer.nl>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License v3.0 as published by
|
||||
// the Free Software Foundation.
|
||||
//
|
||||
#include "mandelbrot.hpp"
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// GNU Lesser General Public License v3.0
|
||||
// Copyright (c) 2025 Bart Beumer <bart@4beumer.nl>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License v3.0 as published by
|
||||
// the Free Software Foundation.
|
||||
//
|
||||
#include <complex>
|
||||
#include <functional>
|
||||
#include "window.hpp"
|
||||
|
||||
template<typename TFloat>
|
||||
class mandelbrot
|
||||
{
|
||||
public:
|
||||
using painter_fn = std::function<void(int x, int y, int iterations)>;
|
||||
using escape_fn = std::function<std::complex<TFloat>(std::complex<TFloat>, std::complex<TFloat>)>;
|
||||
|
||||
mandelbrot(
|
||||
window<TFloat> source_window,
|
||||
window<TFloat> destination_window,
|
||||
int max_iterations,
|
||||
std::complex<TFloat> factor_a)
|
||||
: m_source_window(source_window)
|
||||
, m_destination_window(destination_window)
|
||||
, m_max_iterations(max_iterations)
|
||||
, m_factor_a(factor_a)
|
||||
{}
|
||||
|
||||
void apply(const painter_fn& painter) const
|
||||
{
|
||||
auto fract_fn = [factor = m_factor_a](std::complex <TFloat> z, std::complex<TFloat> c) -> std::complex<TFloat>
|
||||
{
|
||||
return std::pow<TFloat>(z, factor) + c;
|
||||
};
|
||||
|
||||
const TFloat dst_factor_x = 1.0 / m_destination_window.width() * m_source_window.width();
|
||||
const TFloat dst_factor_y = 1.0 / m_destination_window.height() * m_source_window.height();
|
||||
|
||||
for (int x = 0; x < m_destination_window.width(); ++x)
|
||||
{
|
||||
for (int y = 0; y < m_destination_window.height(); ++y)
|
||||
{
|
||||
const auto _x = x * dst_factor_x + m_source_window.x_min();
|
||||
const auto _y = y * dst_factor_y + m_source_window.y_min();
|
||||
const int iterations = escape(std::complex<TFloat>(_y, _x), fract_fn);
|
||||
|
||||
painter(y,x,iterations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int escape(const std::complex<TFloat>& c,
|
||||
const escape_fn& func) const
|
||||
{
|
||||
std::complex<TFloat> z(0);
|
||||
int iter = 0;
|
||||
|
||||
while (abs(z) < 2.0 && iter < m_max_iterations) {
|
||||
z = func(z, c);
|
||||
iter++;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
private:
|
||||
window<TFloat> m_source_window;
|
||||
window<TFloat> m_destination_window;
|
||||
int m_max_iterations;
|
||||
std::complex<TFloat> m_factor_a;
|
||||
};
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// GNU Lesser General Public License v3.0
|
||||
// Copyright (c) 2025 Bart Beumer <bart@4beumer.nl>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License v3.0 as published by
|
||||
// the Free Software Foundation.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
template <typename T>
|
||||
class window
|
||||
{
|
||||
public:
|
||||
window(T x_min, T x_max, T y_min, T y_max)
|
||||
: m_x_min(x_min), m_x_max(x_max), m_y_min(y_min), m_y_max(y_max)
|
||||
{}
|
||||
|
||||
T size() const {
|
||||
return width() * height();
|
||||
}
|
||||
|
||||
T width() const {
|
||||
return m_x_max - m_x_min;
|
||||
}
|
||||
|
||||
T height() const {
|
||||
return m_y_max - m_y_min;
|
||||
}
|
||||
|
||||
T x_min() const {return m_x_min;}
|
||||
T x_max() const {return m_x_max;}
|
||||
T y_min() const {return m_y_min;}
|
||||
T y_max() const {return m_y_max;}
|
||||
|
||||
private:
|
||||
T m_x_min;
|
||||
T m_x_max;
|
||||
T m_y_min;
|
||||
T m_y_max;
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
find_package(Boost 1.84.0 REQUIRED COMPONENTS program_options headers CONFIG)
|
||||
find_package(Boost 1.89.0 REQUIRED COMPONENTS program_options headers CONFIG)
|
||||
find_package(JPEG REQUIRED)
|
||||
|
||||
project(text2image)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
find_package(freetype REQUIRED)
|
||||
find_package(Boost 1.84.0 REQUIRED COMPONENTS headers CONFIG)
|
||||
find_package(Boost 1.89.0 REQUIRED COMPONENTS headers CONFIG)
|
||||
|
||||
project(bmrshared-freetype)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
find_package(Boost 1.84.0 REQUIRED COMPONENTS headers CONFIG)
|
||||
find_package(Boost 1.89.0 REQUIRED COMPONENTS headers CONFIG)
|
||||
project(bmrshared-web)
|
||||
|
||||
add_library(
|
||||
|
|
|
|||
Loading…
Reference in New Issue