Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ca-tikz.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
48#ifndef CA_TIKZ_H
49#define CA_TIKZ_H
50
51#include <concepts>
52#include <ostream>
53#include <sstream>
54#include <string>
55#include <type_traits>
56#include <utility>
57
58#include <ah-errors.H>
59
60#include <ca-traits.H>
61#include <tpl_ca_concepts.H>
62#include <tpl_ca_hex_lattice.H>
64
65namespace Aleph {
66namespace CA {
67
74{
75 double cell_size = 0.35;
76 bool draw_grid = true;
77 bool include_legend = false;
78 std::string grid_colour = "gray!45";
79 std::string dead_label = "dead";
80 std::string alive_label = "alive";
81};
82
90template <typename State>
92{
93 State dead{};
94 std::string dead_colour = "white";
95 std::string alive_colour = "black";
96
101 [[nodiscard]] std::string operator()(const State &v) const
102 {
103 return v == dead ? dead_colour : alive_colour;
104 }
105};
106
107namespace ca_tikz_detail {
108
109template <typename Lattice>
110inline void require_rank2_rect(const char *fn)
111{
112 static_assert(LatticeLike<Lattice>, "TikZ rendering requires a LatticeLike frame");
113 static_assert(Lattice::rank == 2, "Rectangular TikZ rendering requires rank 2");
114 (void) fn;
115}
116
117} // namespace ca_tikz_detail
118
138template <typename Lattice, typename Palette>
139inline void render_rect_lattice_tikz(std::ostream &out,
140 const Lattice &frame,
142 const Rect_Tikz_Options &opts = {})
143 requires requires(Palette &&p, const typename Lattice::state_type &v) {
144 { p(v) } -> std::convertible_to<std::string>;
145 }
146{
147 ca_tikz_detail::require_rank2_rect<Lattice>("render_rect_lattice_tikz");
148 using coord_t = typename Lattice::coord_type;
149 ah_domain_error_if(opts.cell_size <= 0.0)
150 << "render_rect_lattice_tikz: cell_size must be positive";
151
152 out << "% Aleph::CA::render_rect_lattice_tikz\n";
153 out << "\\begin{tikzpicture}[x=1cm, y=-1cm]\n";
154 for (ca_size_t r = 0; r < frame.size(0); ++r)
155 for (ca_size_t c = 0; c < frame.size(1); ++c)
156 {
157 const double x0 = static_cast<double>(c) * opts.cell_size;
158 const double y0 = static_cast<double>(r) * opts.cell_size;
159 const double x1 = x0 + opts.cell_size;
160 const double y1 = y0 + opts.cell_size;
161 const std::string colour
162 = palette(frame.at(coord_t{static_cast<ca_index_t>(r), static_cast<ca_index_t>(c)}));
163 out << " \\path[fill=" << colour;
164 if (opts.draw_grid)
165 out << ", draw=" << opts.grid_colour;
166 out << "] (" << x0 << ", " << y0 << ") rectangle (" << x1 << ", " << y1 << ");\n";
167 }
168
169 if (opts.include_legend)
170 {
171 const double y = (static_cast<double>(frame.size(0)) + 0.7) * opts.cell_size;
172 out << " \\path[fill=white, draw=" << opts.grid_colour << "] (0, " << y << ") rectangle ("
173 << opts.cell_size << ", " << (y + opts.cell_size) << ");\n";
174 out << " \\node[anchor=west] at (" << (opts.cell_size * 1.25) << ", "
175 << (y + opts.cell_size * 0.5) << ") {" << opts.dead_label << "};\n";
176 out << " \\path[fill=black, draw=" << opts.grid_colour << "] (" << (opts.cell_size * 3.5)
177 << ", " << y << ") rectangle (" << (opts.cell_size * 4.5) << ", " << (y + opts.cell_size)
178 << ");\n";
179 out << " \\node[anchor=west] at (" << (opts.cell_size * 4.75) << ", "
180 << (y + opts.cell_size * 0.5) << ") {" << opts.alive_label << "};\n";
181 }
182
183 out << "\\end{tikzpicture}\n";
184 ah_runtime_error_if(not out) << "render_rect_lattice_tikz: output stream failed";
185}
186
196template <typename Lattice, typename Palette>
197[[nodiscard]] inline std::string render_rect_lattice_tikz(const Lattice &frame,
199 const Rect_Tikz_Options &opts = {})
200 requires requires(Palette &&p, const typename Lattice::state_type &v) {
201 { p(v) } -> std::convertible_to<std::string>;
202 }
203{
204 std::ostringstream out;
205 render_rect_lattice_tikz(out, frame, std::forward<Palette>(palette), opts);
206 return out.str();
207}
208
224template <typename Lattice, typename Palette>
225inline void render_lattice_tikz(std::ostream &out,
226 const Lattice &frame,
228 const Rect_Tikz_Options &opts = {})
229 requires requires(Palette &&p, const typename Lattice::state_type &v) {
230 { p(v) } -> std::convertible_to<std::string>;
231 }
232{
233 if constexpr (HexRenderable<Lattice>)
234 render_hex_lattice_tikz(out, frame, std::forward<Palette>(palette));
235 else if constexpr (TriRenderable<Lattice>)
236 render_triangular_lattice_tikz(out, frame, std::forward<Palette>(palette));
237 else
238 render_rect_lattice_tikz(out, frame, std::forward<Palette>(palette), opts);
239}
240
250template <typename Lattice, typename Palette>
251[[nodiscard]] inline std::string render_lattice_tikz(const Lattice &frame,
253 const Rect_Tikz_Options &opts = {})
254 requires requires(Palette &&p, const typename Lattice::state_type &v) {
255 { p(v) } -> std::convertible_to<std::string>;
256 }
257{
258 std::ostringstream out;
259 render_lattice_tikz(out, frame, std::forward<Palette>(palette), opts);
260 return out.str();
261}
262
273template <typename Lattice>
274inline void render_lattice_tikz(std::ostream &out,
275 const Lattice &frame,
276 const Rect_Tikz_Options &opts = {})
277{
279}
280
288template <typename Lattice>
289[[nodiscard]] inline std::string render_lattice_tikz(const Lattice &frame,
290 const Rect_Tikz_Options &opts = {})
291{
292 std::ostringstream out;
294 return out.str();
295}
296
297} // namespace CA
298} // namespace Aleph
299
300#endif // CA_TIKZ_H
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Definition ah-errors.H:527
#define ah_runtime_error_if(C)
Throws std::runtime_error if condition holds.
Definition ah-errors.H:271
size_t size_t int32_t * out
Definition ca-c-api.h:120
Common typedefs and tag types for the Cellular Automata module.
Lattice that adds boundary-aware access on top of a storage.
typename Storage::state_type state_type
typename Storage::coord_type coord_type
static constexpr std::size_t rank
ca_size_t size() const noexcept
state_type at(const coord_type &c) const
Strict access: throws if c is out of range.
Storage + topology that carries the cell values.
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y1_function > > y1(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4114
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y0_function > > y0(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4113
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
static mpfr_t y
Definition mpfr_mul_d.c:3
void require_rank2_rect(const char *fn)
Definition ca-tikz.H:110
void render_rect_lattice_tikz(std::ostream &out, const Lattice &frame, Palette &&palette, const Rect_Tikz_Options &opts={})
Render a rectangular 2D frame as a TikZ picture.
Definition ca-tikz.H:139
void render_hex_lattice_tikz(std::ostream &os, const Lattice &lat, Palette &&palette, double radius=0.5, bool pointy_top=true)
Render a hex frame as a stand-alone TikZ picture.
std::size_t ca_size_t
Unsigned size component used for extents and counts.
Definition ca-traits.H:63
void render_lattice_tikz(std::ostream &out, const Lattice &frame, Palette &&palette, const Rect_Tikz_Options &opts={})
Render any supported 2D CA lattice as TikZ.
Definition ca-tikz.H:225
void render_triangular_lattice_tikz(std::ostream &os, const Lattice &lat, Palette &&palette, const double side=1.0)
Render a triangular frame as a TikZ picture.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Default binary TikZ palette.
Definition ca-tikz.H:92
std::string operator()(const State &v) const
Map a cell state to a TikZ fill colour.
Definition ca-tikz.H:101
std::string alive_colour
fill colour for live cells
Definition ca-tikz.H:95
std::string dead_colour
fill colour for dead cells
Definition ca-tikz.H:94
State dead
state considered dead
Definition ca-tikz.H:93
TikZ rendering options for rectangular frames.
Definition ca-tikz.H:74
std::string alive_label
legend label for live cells
Definition ca-tikz.H:80
double cell_size
cell side length in centimetres
Definition ca-tikz.H:75
bool draw_grid
draw cell borders
Definition ca-tikz.H:76
std::string grid_colour
TikZ colour used for grid lines.
Definition ca-tikz.H:78
bool include_legend
append a compact alive/dead legend
Definition ca-tikz.H:77
std::string dead_label
legend label for dead cells
Definition ca-tikz.H:79
gsl_rng * r
C++20 concepts for the Cellular Automata module.
Hexagonal lattice with axial / offset / cube coordinate conversions and a TikZ-compatible pixel mappi...
Triangular lattice with up/down parity helpers and pixel mapping suitable for visualisation.