diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9c96f7c..46bd93b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -138,7 +138,7 @@ set(TARGETS_REQ_NONE "BurningShip" "apollony" "apomorph" "bifurcation_diagram"
"attracting_torus_shadow" "mandelbrot_potential" "demo_colorizer" "mandelbrot_triangle" "multibrotMovie"
"multibrotSnaps" "peterdejong" "barrymartin" "tinkerbell" "tinkerbell_search" "pickoverPopcorn" "sic" "sic_search"
"sierpinski_triangle" "sprott2d" "test_draw_fonts" "test_images" "tippets" "tricorn" "tricornMovie" "types" "butterfly"
- "LevyCurve" "test_color_con" "demo_corners")
+ "LevyCurve" "test_color_con" "demo_corners" "simone_attractor_search")
set(TARGETS_REQ_OPENGL "glut_image")
set(TARGETS_REQ_TIFF "brownianDiffusion" "displayImageSDL2" "dlaBrownian" "dlaDrift" "img_process" "test_interp_scale" "geomTfrm_LensDistortion"
"geomTfrm_Arb" "geomTfrm_Rotate" "mandelbrot_precomp_p1")
@@ -148,7 +148,7 @@ set(TARGETS_USE_OPENMP "mandelbrot_bm_cplx_openmp" "mandelbrot_precomp" "mandelb
"newton_modified" "newton_min_root" "newton_3updown" "newton_roter" "attracting_torus_shadowM" "laguerre_3updown"
"laguerre_simple" "kalisetJ" "kalisetM1" "kalisetM2" "phoenix" "phoenixI" "phoenixD" "phoenixM" "phoenixM2" "doublePendulum"
"doublePendulumM" "wakOrb01" "wakOrb02" "wakOrb03" "brusselator" "heartFrac" "duck" "mandelbrot_meanOrbit" "feather"
- "simone_attractor" "lorenz_mM" "peterdejongEAAO" "demo_data_and_filter")
+ "simone_attractor" "lorenz_mM" "peterdejongEAAO" "demo_data_and_filter" "simone_attractor_bmovie")
set(TARGETS_REQ_GTEST "all_gtests"
"c_set_chan_dbl" "c_set_chan_byte" "c_set_chan_gen" "c_set_chan_const" "c_set_chan_hex" "c_set_rgba_pack" "c_set_rgb_tga"
"c_set_rgb_wavelengthCM" "c_set_rgb_wavelengthLA" "c_set_cs_csFPcircular12" "c_set_cs_csCBSpectral" "c_set_cs_csBin"
diff --git a/docs/changelog.html b/docs/changelog.html
index e1fe895..2f38cf5 100644
--- a/docs/changelog.html
+++ b/docs/changelog.html
@@ -3,7 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
+
Change Log
@@ -230,12 +230,12 @@ Change Log
Updated: |
-2025-02-23 14:47:57 |
+2025-02-25 16:42:17 |
Generated: |
-2025-02-23 15:37:40 |
+2025-02-25 16:42:18 |
@@ -359,6 +359,9 @@ 1. Changes On HEAD Since L
New
- peterdejongEAAO.cpp
+- simone_attractor_bmovie.cpp
+- simone_attractor_search.cpp
+
- demo_corners.cpp
- lorenz_mM.cpp
- heart2025.cpp
diff --git a/docs/changelog.org b/docs/changelog.org
index f710a04..8421f15 100644
--- a/docs/changelog.org
+++ b/docs/changelog.org
@@ -94,6 +94,9 @@ Copyright \copy {{{time(%Y)}}} Mitch Richling. All rights reserved.
- Examples
- New
- peterdejongEAAO.cpp
+ - simone_attractor_bmovie.cpp
+ - simone_attractor_search.cpp
+
- demo_corners.cpp
- lorenz_mM.cpp
- heart2025.cpp
diff --git a/examples/simone_attractor.cpp b/examples/simone_attractor.cpp
index 2b4161d..c9337ac 100644
--- a/examples/simone_attractor.cpp
+++ b/examples/simone_attractor.cpp
@@ -29,15 +29,14 @@
@endparblock
@filedetails
- I came acros the Simone Attractor on Paul Bourke's web site: http://www.paulbourke.net/fractals/simone_orbits/
- The iteration is:
+ I came across the Simone Attractor on Paul Bourke's web site (http://www.paulbourke.net/fractals/simone_orbits/). Apparently it's based on, or inspired by,
+ work done by Simone Conradi; however, the web page provides no references. The governing iteration is as follows:
@f[ \begin{eqnarray}
x_{n+1} & = & \sin(x^2_n - y^2_n+a) \\
- y_{n+1} & = & \cos(2x_ny_n+b) \\
+ y_{n+1} & = & \cos(2 x_n y_n+b) \\
\end{eqnarray} @f]
- Note: This example is experimental, and still in work...
*/
/*******************************************************************************************************************************************************.H.E.**/
/** @cond exj */
@@ -48,26 +47,63 @@
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
std::vector> params {
- /* a b x0 y0 maxitr */
- { 3.69, 4.511, 0.0, 0.0, 100000000}, // 0
- { 3.64, 1.710, 0.0, 0.0, 100000000}, // 1
+ /* a b maxitr */
+ { 0.432882, -1.570796, 10000000}, // 00
+ { 0.536566, 1.570796, 10000000}, // 01
+ { 0.690363, 0.995086, 10000000}, // 02
+ { 0.517835, 1.680190, 10000000}, // 03
+ { 0.565480, 1.062950, 10000000}, // 04
+ { 0.546562, 1.135860, 10000000}, // 05
+ { 0.456968, 1.837620, 10000000}, // 06
+ { 0.484075, 1.234150, 10000000}, // 07
+ { 0.491253, 1.127530, 10000000}, // 08
+ { 0.443006, 1.747070, 10000000}, // 09
+ { 0.490425, 1.223740, 10000000}, // 10
+ { 0.464411, 1.909230, 10000000}, // 11
+ { 0.486090, 1.139340, 10000000}, // 12
+ { 0.448678, 1.075730, 10000000}, // 13
+ { 0.465456, 1.154130, 10000000}, // 14
+ { 0.375753, 1.877880, 10000000}, // 15
+ { 0.351747, 1.345850, 10000000}, // 16
+ { 0.375383, 1.495300, 10000000}, // 17
+ { 0.378139, 1.323700, 10000000}, // 18
+ { 0.407792, 1.786880, 10000000}, // 19
+ { 0.381058, 1.749780, 10000000}, // 20
+ { 0.422341, 1.361320, 10000000}, // 21
+ { 0.720252, -1.100380, 10000000}, // 22
+ { 0.382110, -1.012590, 10000000}, // 23
+ { 0.404479, -1.626160, 10000000}, // 24
+ { 0.442941, -1.453160, 10000000}, // 25
+ { 0.458452, -1.380980, 10000000}, // 26
+ { 0.064952, -0.775113, 10000000}, // 27
+ { -0.068023, -0.802403, 10000000}, // 28
+ { 0.254331, -0.762604, 10000000}, // 29
+ { -0.223881, -0.714717, 10000000}, // 30
+ { -0.537199, -0.809482, 10000000}, // 31
+ { -0.528728, -0.864537, 10000000}, // 32
+ { -0.783708, -1.135120, 10000000}, // 33
+ { -0.629771, -0.964981, 10000000}, // 34
+ { -0.557026, -0.844882, 10000000}, // 35
+ { -0.501792, -0.675246, 10000000}, // 36
+ { 0.032832, -0.709609, 10000000}, // 37
+ { 0.519031, -1.436470, 10000000}, // 38
+ { 0.037161, 1.936070, 10000000}, // 39
};
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
int main(void) {
std::chrono::time_point startTime = std::chrono::system_clock::now();
- const int BSIZ = 7680/4;
+ const int BSIZ = 7680/1;
+# pragma omp parallel for schedule(static,1)
for(decltype(params.size()) j=0; j(params[j][4]);
+ uint64_t maxitr = static_cast(params[j][2]);
- decltype(theRamCanvas)::coordFltType xn = x0;
- decltype(theRamCanvas)::coordFltType yn = y0;
+ decltype(theRamCanvas)::coordFltType xn = 0;
+ decltype(theRamCanvas)::coordFltType yn = 0;
for(uint64_t i=0;i1000) {
decltype(theRamCanvas)::coordIntType ix = theRamCanvas.real2intX(xn);
decltype(theRamCanvas)::coordIntType iy = theRamCanvas.real2intY(yn);
- theRamCanvas.getPxColorRefNC(ix, iy).tfrmAdd(1);
+ if (theRamCanvas.isOnCanvas(ix, iy))
+ theRamCanvas.getPxColorRefNC(ix, iy).tfrmAdd(1);
}
if((i % 10000000) == 0)
+# pragma omp critical
std::cout << "ITER(" << j << "): " << i << std::endl;
}
-
theRamCanvas.autoHistStrech();
- theRamCanvas.applyHomoPixTfrm(&decltype(theRamCanvas)::colorType::tfrmLn1);
+ theRamCanvas.applyHomoPixTfrm(&decltype(theRamCanvas)::colorType::tfrmPow, 1/4.0);
+ theRamCanvas.rotate90CW();
+ theRamCanvas.scaleDownMean(4);
theRamCanvas.autoHistStrech();
- std::cout << "ITER(" << j << "): " << "TIFF" << std::endl;
+# pragma omp critical
+ std::cout << "ITER(" << j << "): " << "DONE" << std::endl;
theRamCanvas.writeTIFFfile("simone_attractor_" + mjr::math::str::fmt_int(j, 2, '0') + ".tiff",
- mjr::ramCanvasPixelFilter::ColorSchemeOnChan(theRamCanvas));
+ mjr::ramCanvasPixelFilter::ColorSchemeOnChan(theRamCanvas));
+
}
std::chrono::duration runTime = std::chrono::system_clock::now() - startTime;
std::cout << "Total Runtime " << runTime.count() << " sec" << std::endl;
diff --git a/examples/simone_attractor_bmovie.cpp b/examples/simone_attractor_bmovie.cpp
new file mode 100644
index 0000000..be8b287
--- /dev/null
+++ b/examples/simone_attractor_bmovie.cpp
@@ -0,0 +1,98 @@
+// -*- Mode:C++; Coding:us-ascii-unix; fill-column:158 -*-
+/*******************************************************************************************************************************************************.H.S.**/
+/**
+ @file simone_attractor_bmovie.cpp
+ @author Mitch Richling
+ @brief Draw fractals inspired by the book Symmetry in Chaos.@EOL
+ @std C++20
+ @see https://www.mitchr.me/SS/sic/index.html
+ @copyright
+ @parblock
+ Copyright (c) 1988-2015, Mitchell Jay Richling All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+ @endparblock
+ @filedetails
+
+ I came across the Simone Attractor on Paul Bourke's web site (http://www.paulbourke.net/fractals/simone_orbits/). Apparently it's based on, or inspired by,
+ work done by Simone Conradi; however, the web page provides no references. The governing iteration is as follows:
+
+ @f[ \begin{eqnarray}
+ x_{n+1} & = & \sin(x^2_n - y^2_n+a) \\
+ y_{n+1} & = & \cos(2 x_n y_n+b) \\
+ \end{eqnarray} @f]
+
+ ffmpeg -y -framerate 15 -i simone_attractor_bmovie_%4d.tiff -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" -c:v libx264 -crf 10 -b:v 0 -preset veryslow simone_attractor_bmovie_100_crf10.mp4;
+ ffmpeg -y -framerate 15 -i simone_attractor_bmovie_%4d.tiff -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" -c:v libx264 -crf 0 -b:v 0 -preset veryslow simone_attractor_bmovie_100_crf00.mp4;
+ magick -delay 1 -loop 0 -dispose previous simone_attractor_bmovie_????.tiff simone_attractor_bmovie_100.gif
+
+*/
+/*******************************************************************************************************************************************************.H.E.**/
+/** @cond exj */
+
+//--------------------------------------------------------------------------------------------------------------------------------------------------------------
+#include "ramCanvas.hpp"
+#include "MRMathSTR.hpp"
+
+//--------------------------------------------------------------------------------------------------------------------------------------------------------------
+int main(void) {
+ std::chrono::time_point startTime = std::chrono::system_clock::now();
+ const int BSIZ = 6400;
+ const int NUMFRM = 15*6;
+ const double R = 0.002;
+ const double ANGMIN = 0.0;
+ const double ANGMAX = std::numbers::pi*2;
+ const uint64_t MAXITR = 10000000;
+
+# pragma omp parallel for schedule(static,1)
+ for(int frame=0; frame1000) {
+ decltype(theRamCanvas)::coordIntType ix = theRamCanvas.real2intX(xn);
+ decltype(theRamCanvas)::coordIntType iy = theRamCanvas.real2intY(yn);
+ if (theRamCanvas.isOnCanvas(ix, iy))
+ theRamCanvas.getPxColorRefNC(ix, iy).tfrmAdd(1);
+ }
+ }
+ theRamCanvas.autoHistStrech();
+ theRamCanvas.applyHomoPixTfrm(&decltype(theRamCanvas)::colorType::tfrmPow, 1/4.0);
+ theRamCanvas.rotate90CW();
+ theRamCanvas.scaleDownMean(8);
+ theRamCanvas.autoHistStrech();
+# pragma omp critical
+ std::cout << "FRAME(" << frame << "): DONE" << std::endl;
+ theRamCanvas.writeTIFFfile("simone_attractor_bmovie_" + mjr::math::str::fmt_int(frame, 4, '0') + ".tiff",
+ mjr::ramCanvasPixelFilter::ColorSchemeOnChan(theRamCanvas));
+
+ }
+ std::chrono::duration runTime = std::chrono::system_clock::now() - startTime;
+ std::cout << "Total Runtime " << runTime.count() << " sec" << std::endl;
+ return 0;
+}
+/** @endcond */
diff --git a/examples/simone_attractor_search.cpp b/examples/simone_attractor_search.cpp
new file mode 100644
index 0000000..f876c6a
--- /dev/null
+++ b/examples/simone_attractor_search.cpp
@@ -0,0 +1,72 @@
+// -*- Mode:C++; Coding:us-ascii-unix; fill-column:158 -*-
+/*******************************************************************************************************************************************************.H.S.**/
+/**
+ @file simone_attractor_search.cpp
+ @author Mitch Richling
+ @brief Find parameters for simone attractor that light up lots of pixels.@EOL
+ @std C++20
+ @see https://www.mitchr.me/SS/sic/index.html
+ @copyright
+ @parblock
+ Copyright (c) 1988-2015,2025, Mitchell Jay Richling All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+ @endparblock
+*/
+/*******************************************************************************************************************************************************.H.E.**/
+/** @cond exj */
+
+//--------------------------------------------------------------------------------------------------------------------------------------------------------------
+#include "ramCanvas.hpp"
+
+//--------------------------------------------------------------------------------------------------------------------------------------------------------------
+int main(void) {
+ std::chrono::time_point startTime = std::chrono::system_clock::now();
+ const int BSIZ = 2048;
+
+ std::random_device rd;
+ std::mt19937 rEng(rd());
+ std::uniform_real_distribution uniform_dist_double(-2.0, 2.0);
+ std::uniform_int_distribution uniform_dist_int(3, 7);
+
+ mjr::ramCanvas1c16b theRamCanvas(BSIZ, BSIZ, -1, 1, -1, 1); // Just used for coordinate conversion. ;)
+
+ uint64_t maxCnt = 0;
+ for(int j=0; j<100000; j++) {
+ std::map ptcnt;
+ double a = uniform_dist_double(rEng);
+ double b = uniform_dist_double(rEng);
+ double xn = 0;
+ double yn = 0;
+ std::complex z(0.01,0.01);
+ for(uint64_t i=0;i<1000;i++) {
+ double tmp = std::sin(xn*xn-yn*yn+a);
+ yn = std::cos(2*xn*yn+b);
+ xn = tmp;
+ ptcnt[((uint64_t)theRamCanvas.real2intX(xn))<<32 | ((uint64_t)theRamCanvas.real2intY(yn))] = 1;
+ }
+ if(ptcnt.size() >= maxCnt) {
+ maxCnt = ptcnt.size();
+ std::cout << " { " << a << ", " << b << ", 0.0, 0.0, 10000000}, // " << maxCnt << std::endl;
+ }
+ }
+ std::chrono::duration runTime = std::chrono::system_clock::now() - startTime;
+ std::cout << "Total Runtime " << runTime.count() << " sec" << std::endl;
+ return 0;
+}
+/** @endcond */