43# include <unordered_set>
44# include <type_traits>
89 for (
size_t i = 0; i <
libraries.size(); ++i)
181 const std::string & fill_color)
294 std::ostringstream
ss;
295 ss << std::fixed << std::setprecision(3) << v;
297 std::string
out =
ss.str();
417 return style.fill
and not style.pattern.empty();
430 box.initialized =
true;
494 if (poly.
size() == 0)
500 const Point p = it.get_current_vertex().to_point();
508 if (poly.
size() == 0)
512 for (
size_t i = 0; i < poly.
size(); ++i)
519 return make_box(
r.get_xmin(),
r.get_xmax(),
r.get_ymin(),
r.get_ymax());
529 std::min(
y0,
y1), std::max(
y0,
y1));
554 for (
const auto & p :
pl.vertices)
565 [](
const auto & val) {
return bbox_of(val); }, entry.object));
579 escaped.reserve(text.size() + 8);
580 for (
const char ch: text)
583 case '\\':
escaped +=
"\\textbackslash{}";
636 const double s = std::min(map.
sx, map.
sy);
640 const double used_w = xr * s;
641 const double used_h = yr * s;
677 static std::pair<double, double>
697 template <
typename Out>
706 output <<
" (" << x <<
"," <<
y <<
") "
710 template <
typename Out>
720 if (vertices.
size() == 1)
731 for (
size_t i = 0; i < vertices.
size(); ++i)
735 output <<
"(" << x <<
"," <<
y <<
")";
737 output <<
" -- (" << x <<
"," <<
y <<
")";
742 output <<
";" << std::endl;
745 template <
typename Out>
755 template <
typename Out>
766 template <
typename Out>
774 if (
rx == 0.0
or ry == 0.0)
783 output <<
" (" << cx <<
"," << cy <<
") "
784 <<
"ellipse [x radius=" <<
rx <<
", y radius=" <<
ry <<
"];"
788 template <
typename Out>
794 constexpr double two_pi = 2.0 * 3.14159265358979323846;
803 const double t =
two_pi *
static_cast<double>(i) /
820 output <<
"(" << x <<
"," <<
y <<
")";
822 output <<
" -- (" << x <<
"," <<
y <<
")";
824 output <<
" -- cycle;" << std::endl;
827 template <
typename Out>
833 output <<
" \\node[inner sep=1pt";
836 output <<
"] at (" << x <<
"," <<
y <<
") {";
844 template <
typename Out>
851 vertices.
append(it.get_current_vertex().to_point());
856 template <
typename Out>
863 for (
size_t i = 0; i < poly.
size(); ++i)
869 template <
typename Out>
875 const std::array<Point, 4> corners =
r.corners();
876 for (
const Point & p: corners)
881 template <
typename Out>
929 for (
size_t i = 0; i <
clipped.size(); ++i)
930 for (
size_t j = i + 1; j <
clipped.size(); ++j)
944 template <
typename Out>
956 output <<
" (" <<
x0 <<
"," <<
y0 <<
") .. controls ("
957 << x1 <<
"," <<
y1 <<
") .. (" << x2 <<
"," << y2 <<
");"
961 template <
typename Out>
974 output <<
" (" <<
x0 <<
"," <<
y0 <<
") .. controls ("
975 << x1 <<
"," <<
y1 <<
") and (" << x2 <<
"," << y2
976 <<
") .. (" <<
x3 <<
"," <<
y3 <<
");"
991 template <
typename Out>
1009 const int nx0 =
static_cast<int>(std::ceil(xmin / sx));
1010 const int nx1 =
static_cast<int>(std::floor(xmax / sx));
1011 const int ny0 =
static_cast<int>(std::ceil(ymin / sy));
1012 const int ny1 =
static_cast<int>(std::floor(ymax / sy));
1014 for (
int i =
nx0; i <=
nx1; ++i)
1025 for (
int i =
ny0; i <=
ny1; ++i)
1027 const auto y =
Geom_Number(
static_cast<double>(i) * sy);
1046 for (
int i =
nx0; i <=
nx1; ++i)
1048 const auto x =
Geom_Number(
static_cast<double>(i) * sx);
1059 for (
int i =
ny0; i <=
ny1; ++i)
1061 const auto y =
Geom_Number(
static_cast<double>(i) * sy);
1078 std::unordered_set<std::string>
seen;
1079 for (
const auto & [label, style]: entries)
1084 std::string
color =
obj.style.draw_color;
1105 template <
typename Out>
1112 for (
size_t i = 0; i < entries.
size(); ++i)
1122 output <<
" (" <<
x0 <<
"," <<
y <<
") -- (" << x1 <<
"," <<
y <<
");"
1125 output <<
" \\node[anchor=west] at (" << (x1 + 1.2) <<
"," <<
y
1126 <<
") {" <<
escape_latex(entries[i].label) <<
"};" << std::endl;
1130 template <
typename Out>
1141 output <<
" \\tikzset{" << name <<
"/.style={" <<
opts <<
"}}" << std::endl;
1145 template <
typename Out>
1175 template <
typename Out>
1179 std::visit([&]<
typename T0>(
const T0 &
value)
1181 using T = std::decay_t<T0>;
1182 if constexpr (std::is_same_v<T, Point>)
1184 else if constexpr (std::is_same_v<T, Polar_Point>)
1186 else if constexpr (std::is_same_v<T, Segment>)
1188 else if constexpr (std::is_same_v<T, Triangle>)
1190 else if constexpr (std::is_same_v<T, Ellipse>)
1192 else if constexpr (std::is_same_v<T, RotatedEllipse>)
1194 else if constexpr (std::is_same_v<T, Text>)
1196 else if constexpr (std::is_same_v<T, Polygon>)
1198 else if constexpr (std::is_same_v<T, Regular_Polygon>)
1200 else if constexpr (std::is_same_v<T, Rectangle>)
1202 else if constexpr (std::is_same_v<T, LineEq>)
1204 else if constexpr (std::is_same_v<T, Tikz_Quadratic_Bezier>)
1206 else if constexpr (std::is_same_v<T, Tikz_Cubic_Bezier>)
1208 else if constexpr (std::is_same_v<T, Tikz_Polyline>)
1226 const double & xoffset = 0.0,
const double & yoffset = 0.0)
1230 <<
"Tikz_Plane width and height must be greater than zero";
1271 for (
const auto &
object :
objects_)
1343 const double step_y = 1.0,
1347 <<
"Grid steps must be greater than zero";
1427 output << std::fixed << std::setprecision(6);
1428 output <<
"% Requires: \\usepackage{tikz}" << std::endl;
1432 output <<
"% TikZ libraries:";
1433 for (
size_t i = 0; i <
libraries.size(); ++i)
1439 output <<
"\\pgfdeclarelayer{background}" << std::endl
1440 <<
"\\pgfdeclarelayer{foreground}" << std::endl
1441 <<
"\\pgfdeclarelayer{overlay}" << std::endl;
1443 output <<
"\\begin{tikzpicture}[x=1mm,y=1mm]" << std::endl;
1445 output <<
" \\pgfsetlayers{background,main,foreground,overlay}" << std::endl;
1447 output <<
" % " <<
objects_.size() <<
" geometric objects in plane" << std::endl;
1459 for (
size_t i = 0; i <
objects_.size(); ++i)
1465 quicksort_op(order, [&](
const size_t lhs,
const size_t rhs)
1474 const char *current =
nullptr;
1475 for (
const size_t idx: order)
1478 if (current ==
nullptr or std::string(current) != target)
1480 if (current !=
nullptr)
1481 output <<
" \\end{pgfonlayer}" << std::endl;
1482 output <<
" \\begin{pgfonlayer}{" << target <<
"}" << std::endl;
1487 if (current !=
nullptr)
1488 output <<
" \\end{pgfonlayer}" << std::endl;
1491 for (
const size_t idx: order)
1496 output <<
" \\end{scope}" << std::endl;
1497 output <<
"\\end{tikzpicture}" << std::endl;
1505 template <
typename Geom>
1507 std::is_constructible_v<Tikz_Plane::Object, std::decay_t<Geom>>;
1510 template <TikzDrawable Geom>
1517 template <TikzDrawable Geom>
1618 const Point & point,
1619 const std::string & label,
1620 const std::string &
placement =
"above",
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
size_t size_t int32_t value
size_t size_t int32_t * out
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
constexpr bool is_empty() const noexcept
Checks if the container is empty.
T & insert(const T &data)
insert a copy of data at the beginning of the array.
T & get_first() noexcept
return a modifiable reference to the first element.
T & append(const T &data)
Append a copy of data
void reserve(size_t cap)
Reserves cap cells into the array.
bool has_curr() const noexcept
Return true if the iterator has current item.
const Geom_Number & get_vradius() const
Gets the vertical radius.
const Point & get_center() const
Gets the center point of the ellipse.
Point highest_point() const
Gets the highest point on the ellipse boundary.
Point rightmost_point() const
Gets the rightmost point on the ellipse boundary.
const Geom_Number & get_hradius() const
Gets the horizontal radius.
Point leftmost_point() const
Gets the leftmost point on the ellipse boundary.
Point lowest_point() const
Gets the lowest point on the ellipse boundary.
Represents a point with rectangular coordinates in a 2D plane.
const Geom_Number & get_x() const noexcept
Gets the x-coordinate value.
const Geom_Number & get_y() const noexcept
Gets the y-coordinate value.
Polar representation of a 2D point.
A general (irregular) 2D polygon defined by a sequence of vertices.
const bool & is_closed() const
Check if the polygon is closed.
const size_t & size() const
Get the number of vertices.
An axis-aligned rectangle.
A regular polygon defined by center, side length, and vertex count.
Point get_vertex(const size_t &i) const
Get the i-th vertex of the polygon.
const size_t & size() const
Get the number of vertices.
An ellipse with arbitrary rotation.
const Geom_Number & get_b() const
Gets the semi-axis 'b' (local y-axis radius).
ExtremalPoints extremal_points() const
Computes the four axis-extremal points of the rotated ellipse.
const Geom_Number & get_sin() const
Gets the sine of the rotation angle.
const Geom_Number & get_a() const
Gets the semi-axis 'a' (local x-axis radius).
const Geom_Number & get_cos() const
Gets the cosine of the rotation angle.
const Point & get_center() const
Gets the center point.
Represents a line segment between two points.
const Point & rightmost_point() const noexcept
Gets the endpoint with the largest x-coordinate.
const Point & highest_point() const noexcept
Gets the endpoint with the largest y-coordinate.
const Point & lowest_point() const noexcept
Gets the endpoint with the smallest y-coordinate.
const Point & leftmost_point() const noexcept
Gets the endpoint with the smallest x-coordinate.
const Point & get_tgt_point() const noexcept
Gets the target point of the segment.
const Point & get_src_point() const noexcept
Gets the source point of the segment.
Represents a text string positioned at a 2D point.
Point lowest_point() const
Gets the lowest point (the anchor point).
Point highest_point() const
Gets the highest point (the anchor point).
Point rightmost_point() const
Gets the rightmost point (the anchor point).
const std::string & get_str() const
Gets the text string.
const Point & get_point() const
Gets the position point of the text.
Point leftmost_point() const
Gets the leftmost point (the anchor point).
2D TikZ canvas storing geometry objects and emitting LaTeX output.
void draw_polyline(Out &output, const Array< Point > &vertices, const bool closed, const Tikz_Style &style, const Geom_Box &box, const Mapping &map) const
void set_axis_style(const Tikz_Style &style)
Configure the style used to draw Cartesian axes.
void draw_object(const Styled_Object &entry, Out &output, const Geom_Box &box, const Mapping &map) const
static std::pair< double, double > map_point(const Point &p, const Geom_Box &box, const Mapping &map)
Mapping compute_mapping(const Geom_Box &box, const bool squarize) const
static Geom_Box bbox_of(const Ellipse &e)
static std::string draw_options(const Tikz_Style &style, const bool allow_fill=false)
Array< Legend_Entry > collect_legend_entries() const
void draw_regular_polygon(const Regular_Polygon &poly, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map) const
Array< std::string > required_tikz_libraries() const
Collect TikZ libraries required by currently emitted features.
std::variant< Point, Polar_Point, Segment, Triangle, Ellipse, RotatedEllipse, Text, Polygon, Regular_Polygon, Rectangle, LineEq, Tikz_Quadratic_Bezier, Tikz_Cubic_Bezier, Tikz_Polyline > Object
Runtime set of supported objects.
void draw(std::ostream &output, const bool squarize=true) const
Emit a complete tikzpicture with all inserted objects.
void remove_coordinate_grid()
Disable coordinate grid rendering.
void set_clip_padding_mm(const double &padding_mm)
Configure clip expansion around frame borders.
void draw_point(const Point &p, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map) const
void put_cartesian_axis()
Enable Cartesian axes drawing (only when 0 lies in range).
static bool style_requires_patterns(const Tikz_Style &style) noexcept
Return true when rendering style needs the patterns library.
static constexpr int Layer_Default
static Geom_Box make_box(const Geom_Number &xmin, const Geom_Number &xmax, const Geom_Number &ymin, const Geom_Number &ymax)
void clear_tikz_styles()
Clear all registered \tikzset style definitions.
Array< Legend_Entry > legend_entries_
void clear()
Remove all inserted objects from the plane.
static std::string fmt_double(const double v)
static const char * layer_name(const int layer)
const double & get_wide() const
Plane width in millimeters.
static void append_option(std::string &opts, const std::string &opt)
const double & get_height() const
Plane height in millimeters.
void put(const Object &obj, const Tikz_Style &style, const int layer)
Insert an object with explicit style/layer.
void draw_tikzset_styles(Out &output) const
static constexpr int Layer_Foreground
static std::string text_options(const Tikz_Style &style)
Tikz_Plane(const double &wide, const double &height, const double &xoffset=0.0, const double &yoffset=0.0)
Construct a TikZ plane with fixed frame size.
static void draw_text(const Text &t, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map)
void enable_auto_legend(const bool enabled=true)
Enable auto-legend generation from style colors.
static double map_y(const Geom_Number &y, const Geom_Box &box, const Mapping &map)
void enable_native_tikz_layers(const bool enabled=true)
Enable native PGF layers (\pgfdeclarelayer).
void draw_cartesian_axis(Out &output, const Geom_Box &box, const Mapping &map) const
bool with_cartesian_axis_
Geom_Box compute_box() const
static std::string point_options(const Tikz_Style &style)
size_t size() const
Number of currently inserted objects.
void put_coordinate_grid(const double step_x=1.0, const double step_y=1.0, const bool draw_ticks=true)
Enable coordinate grid/ticks with user step sizes.
static Geom_Box bbox_of(const Polar_Point &pp)
bool with_coordinate_grid_
static Geom_Box bbox_of(const Tikz_Cubic_Bezier &b)
void draw_legend(Out &output) const
const double & get_yoffset() const
Vertical scope offset in millimeters.
static constexpr int Layer_Background
static double map_x_length(const Geom_Number &dx, const Mapping &map)
Tikz_Style default_style_
static std::string escape_latex(const std::string &text)
void set_point_radius_mm(const double &radius_mm)
Configure point marker radius.
void draw_rectangle(const Rectangle &r, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map) const
static double map_x(const Geom_Number &x, const Geom_Box &box, const Mapping &map)
static void draw_cubic_bezier(const Tikz_Cubic_Bezier &b, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map)
Array< Styled_Object > objects_
const Tikz_Style & get_default_style() const
Default style used by put(obj) and non-styled put_in_plane.
void put(const Object &obj)
Insert an object with default style on default layer.
static void draw_rotated_ellipse(const RotatedEllipse &e, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map)
static Geom_Box bbox_of(const Polygon &poly)
static Geom_Box bbox_of(const LineEq &l)
void draw_polygon(const Polygon &poly, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map) const
static Geom_Box bbox_of(const Triangle &t)
void set_grid_style(const Tikz_Style &style)
Configure the style used to draw coordinate grids.
const Tikz_Style & get_axis_style() const
Style used for Cartesian axes when enabled.
void draw_coordinate_grid(Out &output, const Geom_Box &box, const Mapping &map) const
static Geom_Box bbox_of(const Segment &s)
static Geom_Box bbox_of(const Point &p)
void draw_triangle(const Triangle &t, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map) const
static Geom_Box bbox_of(const Tikz_Quadratic_Bezier &b)
static Geom_Box bbox_of(const Tikz_Polyline &pl)
void register_tikz_style(const std::string &name, const Tikz_Style &style)
Register a reusable \tikzset style for the rendered picture.
static double map_y_length(const Geom_Number &dy, const Mapping &map)
void add_legend_entry(const std::string &label, const Tikz_Style &style)
Add a legend entry to be rendered in the top-left corner.
static Geom_Box bbox_of(const Rectangle &r)
static void merge_box(Geom_Box &dst, const Geom_Box &src)
static Geom_Box bbox_of(const Regular_Polygon &poly)
static void draw_quadratic_bezier(const Tikz_Quadratic_Bezier &b, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map)
const Tikz_Style & get_grid_style() const
Style used for coordinate grids when enabled.
void draw_segment(const Segment &s, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map) const
void clear_legend()
Remove user-provided legend entries.
void draw_line_eq(const LineEq &l, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map) const
static Geom_Box bbox_of(const Text &t)
double effective_clip_padding_mm() const
void set_default_style(const Tikz_Style &style)
Configure the default style for subsequent non-styled inserts.
static constexpr int Layer_Overlay
const double & get_clip_padding_mm() const
Clip expansion around the frame; <= 0 means auto (point radius).
const double & get_point_radius_mm() const
Radius used to draw point primitives (millimeters).
double legend_entry_step_mm_
static Geom_Box bbox_of(const RotatedEllipse &e)
void draw_ellipse(const Ellipse &e, const Tikz_Style &style, Out &output, const Geom_Box &box, const Mapping &map) const
std::map< std::string, Tikz_Style > tikz_style_defs_
const double & get_xoffset() const
Horizontal scope offset in millimeters.
void remove_cartesian_axis()
Disable Cartesian axes drawing.
A non-degenerate triangle defined by three points.
const Point & get_p3() const
Gets the third vertex.
const Point & get_p2() const
Gets the second vertex.
const Point & rightmost_point() const
Gets the vertex with the largest x-coordinate.
const Point & lowest_point() const
Gets the vertex with the smallest y-coordinate.
const Point & get_p1() const
Gets the first vertex.
const Point & highest_point() const
Gets the vertex with the largest y-coordinate.
const Point & leftmost_point() const
Gets the vertex with the smallest x-coordinate.
A geometry type that Tikz_Plane::Object can wrap.
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y1_function > > y1(const __gmp_expr< T, U > &expr)
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y0_function > > y0(const __gmp_expr< T, U > &expr)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
2D infinite line representation using slope-intercept form.
Main namespace for Aleph-w library functions.
void put_cubic_bezier_native_in_plane(Tikz_Plane &plane, const Point &p0, const Point &p1, const Point &p2, const Point &p3, const Tikz_Style &style={}, const int layer=Tikz_Plane::Layer_Default)
Insert a cubic Bézier using native TikZ controls syntax.
void put_quadratic_bezier_native_in_plane(Tikz_Plane &plane, const Point &p0, const Point &p1, const Point &p2, const Tikz_Style &style={}, const int layer=Tikz_Plane::Layer_Default)
Insert a quadratic Bézier using native TikZ controls syntax.
void put_cubic_bezier_in_plane(Tikz_Plane &plane, const Point &p0, const Point &p1, const Point &p2, const Point &p3, const size_t subdivisions=64, const Tikz_Style &style={}, const int layer=Tikz_Plane::Layer_Default)
Approximate and insert a cubic Bézier as an open polyline.
void put_in_plane(Tikz_Plane &plane, const Geom &geom_obj)
Insert any supported geometry type in a Tikz_Plane.
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
double geom_number_to_double(const Geom_Number &n)
Converts a Geom_Number to its double precision representation.
void put_quadratic_bezier_in_plane(Tikz_Plane &plane, const Point &p0, const Point &p1, const Point &p2, const size_t subdivisions=64, const Tikz_Style &style={}, const int layer=Tikz_Plane::Layer_Default)
Approximate and insert a quadratic Bézier as an open polyline.
mpq_class Geom_Number
Numeric type used by the geometry module.
void put_point_label_in_plane(Tikz_Plane &plane, const Point &point, const std::string &label, const std::string &placement="above", const Tikz_Style &style=make_tikz_draw_style("black"), const int layer=Tikz_Plane::Layer_Overlay)
Insert a point label with configurable placement (above, etc.).
void append_unique_tikz_library(Array< std::string > &libraries, const std::string &library)
Append library into libraries unless already present.
Tikz_Style make_tikz_draw_style(const std::string &draw_color)
Create a basic draw style with a custom color.
Tikz_Style make_tikz_fill_style(const std::string &draw_color, const std::string &fill_color)
Create a basic fill style with custom draw/fill colors.
static long & color(typename GT::Node *p)
void quicksort_op(C< T > &a, const Compare &cmp=Compare(), const size_t threshold=Quicksort_Threshold)
Optimized quicksort for containers using operator().
2D point and geometric utilities.
2D polygon representation and geometric operations.
static Rectangle box(const int x1, const int y1, const int x2, const int y2)
2D infinite line in slope-intercept form.
Iterator over the vertices of a polygon.
Represents a cubic Bézier curve for native TikZ rendering.
Point p1
First control point.
Point p2
Second control point.
An object with its associated style, layer, and insertion order.
Tikz_Style style
The style used to render the object.
int layer
The rendering layer.
Object object
The geometric object.
size_t order
Insertion order within the layer.
An open or closed polyline for TikZ rendering.
Array< Point > vertices
Ordered vertices.
bool closed
Whether to close the polyline.
Represents a quadratic Bézier curve for native TikZ rendering.
Style descriptor for TikZ primitives.
std::string text_anchor
TikZ node anchor (anchor=<value>)
std::string fill_color
TikZ fill color (fill=<color>)
std::string pattern
TikZ pattern (e.g. north east lines)
double opacity
opacity=<value> in [0,1], when >= 0
std::string extra_options
Raw extra options appended as-is.
std::string text_color
TikZ text color (text=<color>)
bool fill
Fill closed shapes (polygon/triangle/ellipse)
std::string text_placement
TikZ placement (above, below left, ...)
std::string tikz_style_name
Optional named style (from \tikzset)
double line_width_mm
line width=<value>mm when > 0
std::string draw_color
TikZ draw color (draw=<color>)
std::string text_font_command
e.g. \\small, \\footnotesize
std::string pattern_color
TikZ pattern color (pattern color=<color>)
Dynamic array container with automatic resizing.
Comprehensive sorting algorithms and search utilities for Aleph-w.