Skip to content

Commit

Permalink
Merge pull request #160 from ckormanyos/update_discovery
Browse files Browse the repository at this point in the history
Update discovery program and docs
  • Loading branch information
ckormanyos committed Sep 23, 2024
2 parents abb5182 + de7733a commit 2296f64
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 94 deletions.
1 change: 1 addition & 0 deletions MandelbrotDiscovery/MandelbrotDiscovery.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="mandelbrot_discovery.cpp" />
<ClCompile Include="mandelbrot_discovery_cmd.cpp" />
<ClCompile Include="mandelbrot_discovery_rescale.cpp" />
</ItemGroup>
<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions MandelbrotDiscovery/MandelbrotDiscovery.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
<ClCompile Include="mandelbrot_discovery_rescale.cpp">
<Filter>MandelbrotDiscovery</Filter>
</ClCompile>
<ClCompile Include="mandelbrot_discovery_cmd.cpp">
<Filter>MandelbrotDiscovery</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mandelbrot_discovery.h">
Expand Down
87 changes: 15 additions & 72 deletions MandelbrotDiscovery/mandelbrot_discovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#include <thread>

extern auto mandelbrot_discovery_rescale() -> void;
extern auto mandelbrot_discovery_cmd_res(const std::string& str_cmd, int& frac, std::string& str_cmd_result) -> bool;
extern auto mandelbrot_discovery_cmd_itr(const std::string& str_cmd, unsigned& iter, std::string& str_cmd_result) -> bool;

namespace mandelbrot_discovery_detail
{
Expand Down Expand Up @@ -405,7 +407,7 @@
local_rectangle_ref.center().get_x() + local_rectangle_ref.dx_half(),
local_rectangle_ref.center().get_y() - local_rectangle_ref.dy_half(),
local_rectangle_ref.center().get_y() + local_rectangle_ref.dy_half(),
my_mandelbrot_iterations
std::uint_fast32_t { my_mandelbrot_iterations }
);

mandelbrot_generator_type gen { mandelbrot_config_object };
Expand Down Expand Up @@ -601,12 +603,14 @@

write_string("cmd: ");

std::string str_cmd { };
std::string str_cmd { };
std::string str_cmd_result { };
bool do_iterate_and_redraw { };
int frac2 { };
unsigned iter { };

read_string(str_cmd);

bool do_iterate_and_redraw { };

if(str_cmd == "set")
{
write_string("click to set a point\n");
Expand All @@ -618,78 +622,17 @@
std::this_thread::sleep_for(std::chrono::microseconds(static_cast<unsigned>(UINT8_C(20))));
}
}
else if( (str_cmd.find("itr", static_cast<std::string::size_type>(UINT8_C(0))) == static_cast<std::string::size_type>(UINT8_C(0)))
&& (str_cmd.length() > static_cast<std::string::size_type>(UINT8_C(3))))
else if(::mandelbrot_discovery_cmd_itr(str_cmd, iter, str_cmd_result))
{
std::uint_fast32_t iter { };

const auto result_of_iter_from_chars =
std::from_chars
(
str_cmd.c_str() + static_cast<std::string::size_type>(UINT8_C(3)),
str_cmd.c_str() + str_cmd.length(),
iter
);

const auto err_code = result_of_iter_from_chars.ec;

if(err_code == std::errc())
{
my_mandelbrot_iterations = iter;
my_mandelbrot_iterations = iter;

write_string("new max. iterations: " + std::to_string(iter) + "\n");
}
write_string(str_cmd_result);
}
else if( (str_cmd.find("res", static_cast<std::string::size_type>(UINT8_C(0))) == static_cast<std::string::size_type>(UINT8_C(0)))
&& (str_cmd.length() > static_cast<std::string::size_type>(UINT8_C(3))))
else if(::mandelbrot_discovery_cmd_res(str_cmd, frac2, str_cmd_result))
{
// TODO ckormanyos Parse strings of the form:
// res, res1, res1/2, res1/4, res1/8, res1/16, ...
// ... and use this resolution information accordingly.

// See also code at GodBolt at: https://godbolt.org/z/Wq5nran4o

if((str_cmd == "res") || (str_cmd == "res1"))
{
my_mandelbrot_frac2_denominator = 1;

write_string("new resolution having fraction: 1/1\n");
}
else
{
// Regex pattern to match the required strings.
std::string pattern_str = "res(1)?(/(2|4|8|16))?";
std::regex pattern(pattern_str);

std::smatch match;

if (std::regex_match(str_cmd, match, pattern))
{
if((match[1].matched) && (match[3].matched))
{
const std::string str_frac { match[3].str() };
my_mandelbrot_frac2_denominator = frac2;

int frac2 { };

const auto result_of_iter_from_chars =
std::from_chars
(
str_frac.data(),
str_frac.data() + str_frac.length(),
frac2
);

const auto err_code = result_of_iter_from_chars.ec;

if(err_code == std::errc())
{
my_mandelbrot_frac2_denominator = frac2;

write_string("new resolution having fraction: 1/" + std::to_string(frac2) + "\n");
}
}
}
}
write_string(str_cmd_result);
}
else if(str_cmd == "calc")
{
Expand Down Expand Up @@ -1178,7 +1121,7 @@
const int IconId,
const int ScreenCoordinateX,
const int ScreenCoordinateY>
std::uint_fast32_t mandelbrot_discovery<WindowWidth, WindowHeight, MandelbrotRectangleTupleType, WindowTitle, IconId, ScreenCoordinateX, ScreenCoordinateY>::my_mandelbrot_iterations { static_cast<std::uint_fast32_t>(UINT32_C(400)) };
unsigned mandelbrot_discovery<WindowWidth, WindowHeight, MandelbrotRectangleTupleType, WindowTitle, IconId, ScreenCoordinateX, ScreenCoordinateY>::my_mandelbrot_iterations { static_cast<unsigned>(UINT16_C(400)) };

template<const int WindowWidth,
const int WindowHeight,
Expand Down
112 changes: 112 additions & 0 deletions MandelbrotDiscovery/mandelbrot_discovery_cmd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2024.
// Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <charconv>
#include <regex>
#include <string>

auto mandelbrot_discovery_cmd_itr(const std::string& str_cmd, unsigned& iter, std::string& str_cmd_result) -> bool
{
const bool
cmd_is_itr
{
(str_cmd.find("itr", static_cast<std::string::size_type>(UINT8_C(0))) == static_cast<std::string::size_type>(UINT8_C(0)))
&& (str_cmd.length() > static_cast<std::string::size_type>(UINT8_C(3)))
};

bool result_cmd_itr_is_ok { false };

if(cmd_is_itr)
{
unsigned local_iter { };

const auto result_of_iter_from_chars =
std::from_chars
(
str_cmd.c_str() + static_cast<std::string::size_type>(UINT8_C(3)),
str_cmd.c_str() + str_cmd.length(),
local_iter
);

const auto err_code = result_of_iter_from_chars.ec;

if(err_code == std::errc())
{
iter = local_iter;

str_cmd_result = "new max. iterations: " + std::to_string(local_iter) + "\n";

result_cmd_itr_is_ok = true;
}
}

return result_cmd_itr_is_ok;
}

auto mandelbrot_discovery_cmd_res(const std::string& str_cmd, int& frac2, std::string& str_cmd_result) -> bool
{
const bool
cmd_is_res
{
(str_cmd.find("res", static_cast<std::string::size_type>(UINT8_C(0))) == static_cast<std::string::size_type>(UINT8_C(0)))
&& (str_cmd.length() > static_cast<std::string::size_type>(UINT8_C(3)))
};

bool result_cmd_res_is_ok { false };

if(cmd_is_res)
{
// Parse strings of the form: res, res1, res1/2, res1/4, res1/8, res1/16.
// See also code at GodBolt at: https://godbolt.org/z/Wq5nran4o

if((str_cmd == "res") || (str_cmd == "res1"))
{
frac2 = 1;

str_cmd_result = "new resolution having fraction: 1/1\n";

result_cmd_res_is_ok = true;
}
else
{
// Regex pattern to match the required strings.
std::string pattern_str = "res(1)?(/(2|4|8|16))?";
std::regex pattern(pattern_str);

std::smatch match;

if (std::regex_match(str_cmd, match, pattern))
{
if((match[1].matched) && (match[3].matched))
{
const std::string str_frac { match[3].str() };

int local_frac2 { };

const auto result_of_iter_from_chars =
std::from_chars
(
str_frac.data(),
str_frac.data() + str_frac.length(),
local_frac2
);

const auto err_code = result_of_iter_from_chars.ec;

if(err_code == std::errc())
{
frac2 = local_frac2;

result_cmd_res_is_ok = true;
}
}
}
}
}

return result_cmd_res_is_ok;
}
7 changes: 7 additions & 0 deletions MandelbrotDiscovery/mandelbrot_discovery_rescale.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2024.
// Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <geometry.h>

#include <boost/gil/image.hpp>
Expand Down
35 changes: 13 additions & 22 deletions MandelbrotDiscovery/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,15 @@ coordinate points of the Mandelbrot set.
Build `MandelbrotDiscovery.exe` from the Microsoft(R) VisualStudio(R)
solution, `MandelbrotDiscovery.sln` located
[here](https://github.com/ckormanyos/mandelbrot/tree/main/MandelbrotDiscovery).
The program uses the classic Win32-API style. Aside from
the JPEG and PNG libraries and image-rescaling, the program
is written in a convenient, lightweight header-only fashion.
Aside from the JPEG/PNG libraries and image-rescaling,
the program is written in a convenient, lightweight
classic Win32-API style.

The program is mouse-and-command-driven.
Begin a search by starting `MandelbrotDiscovery.exe`.
Zooming is accomplished with commands entered in the command window
in combination with mouse-clicks in the client area of the Mandelbrot image window.

### Command Summary

The following commands are supported at the moment (with more planned for the future).

- <strong><code>help</code></strong> (or <strong><code>?</code></strong>) - Print the command list.
- <strong><code>set</code></strong> - Enter the <strong><code>set</code></strong> command prior to pointing and clicking to select now coordinates with the mouse.
- <strong><code>calc</code></strong> - The <strong><code>calc</code></strong> command calculated the Mandelbrot image at the currently set coordinate point. It subsequently displays the image after the calculation.</code>
- <strong><code>itrNNNN</code></strong> - Using <strong><code>itrNNNN</code></strong> sets the maximum number of iterations to the appended number. The command <strong><code>itr2000</code></strong>, for instance, sets the maximum number of iterations to $2,000$. Switch $2,000$ for another number like $40,000$ to obtain a maximum iteration count of $40,000$ and so on. The default iteration count at program start is modestly set to $400$. So don't be surprised if higher iteration counts are required for deeper and deeper dives.
- <strong><code>res1/F</code></strong> - Using <strong><code>res1/F</code></strong> sets the fractional resolution based on the default of $768{\times}768$ pixels. The command <strong><code>res1/2</code></strong>, for example, sets the resolution to $384{\times}384$ pixels. The fractions $1/1$, $1/2$, $1/4$, $1/8$ and $1/16$ are supported. The command <strong><code>res</code></strong> (or <strong><code>res1</code></strong>) restores the default resolution. Reduced resolution can significantly decrease computation time when searching via deep diving.
- <strong><code>redo</code></strong> - The command <strong><code>redo</code></strong> simply performs, yet again, the iteration at the coordinate point that is already set. This might be done if, for example, the image was not resolved and the iteration count needs to be increased. You can also exercise the <strong><code>set</code></strong> command one or more times prior to exercising the <strong><code>redo</code></strong> command.
- <strong><code>out</code></strong> - With <strong><code>out</code></strong> you can backstep one single order of magnification at the point that has been set and clicked. This can be done repeatedly if a different zoom pathway is desired even after zooming in to a point. So if you've taken a bit of a wrong turn, just zoom <strong><code>out</code></strong> one or more times and refine your coordinate search.
- <strong><code>exit</code></strong> - Quits the program and closes the image window.


### The Startup Windows

Upon startup, you should see the default Mandelbrot image. It is a square, gray-tone JPEG
Expand Down Expand Up @@ -138,13 +124,18 @@ The result of this dive ended up being:

![](https://github.com/ckormanyos/mandelbrot/blob/main/images/discovery/mandelbrot_discovery_dive_example.jpg)

## Additional Program Dynamic Behavior

The following features (and probably a few more) are TODO both in docs as well as in the program.
### Command Summary

### Changing the Resolution
The following commands are supported at the moment (with more planned for the future).

This feature is TODO both in docs as well as in the program.
- <strong><code>help</code></strong> (or <strong><code>?</code></strong>) - Print the command list.
- <strong><code>set</code></strong> - Enter the <strong><code>set</code></strong> command prior to pointing and clicking to select now coordinates with the mouse.
- <strong><code>calc</code></strong> - The <strong><code>calc</code></strong> command calculated the Mandelbrot image at the currently set coordinate point. It subsequently displays the image after the calculation.</code>
- <strong><code>itrNNNN</code></strong> - Using <strong><code>itrNNNN</code></strong> sets the maximum number of iterations to the appended number. The command <strong><code>itr2000</code></strong>, for instance, sets the maximum number of iterations to $2,000$. Switch $2,000$ for another number like $40,000$ to obtain a maximum iteration count of $40,000$ and so on. The default iteration count at program start is modestly set to $400$. So don't be surprised if higher iteration counts are required for deeper and deeper dives.
- <strong><code>res1/F</code></strong> - Using <strong><code>res1/F</code></strong> sets the fractional resolution based on the default of $768{\times}768$ pixels. The command <strong><code>res1/2</code></strong>, for example, sets the resolution to $384{\times}384$ pixels. The fractions $1/1$, $1/2$, $1/4$, $1/8$ and $1/16$ are supported. The command <strong><code>res</code></strong> (or <strong><code>res1</code></strong>) restores the default resolution. Reduced resolution can significantly decrease computation time when searching via deep diving.
- <strong><code>redo</code></strong> - The command <strong><code>redo</code></strong> simply performs, yet again, the iteration at the coordinate point that is already set. This might be done if, for example, the image was not resolved and the iteration count needs to be increased. You can also exercise the <strong><code>set</code></strong> command one or more times prior to exercising the <strong><code>redo</code></strong> command.
- <strong><code>out</code></strong> - With <strong><code>out</code></strong> you can backstep one single order of magnification at the point that has been set and clicked. This can be done repeatedly if a different zoom pathway is desired even after zooming in to a point. So if you've taken a bit of a wrong turn, just zoom <strong><code>out</code></strong> one or more times and refine your coordinate search.
- <strong><code>exit</code></strong> - Quits the program and closes the image window.

### Saving and Restoring Previous Work

Expand Down

0 comments on commit 2296f64

Please sign in to comment.