From 41b2589b4671d7f35f132717e904d35d34874f1b Mon Sep 17 00:00:00 2001 From: Simon Waldherr Date: Thu, 24 Oct 2024 20:47:58 +0200 Subject: [PATCH 1/4] add Hilbert Curve --- fractals/hilbert_curve.py | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 fractals/hilbert_curve.py diff --git a/fractals/hilbert_curve.py b/fractals/hilbert_curve.py new file mode 100644 index 000000000000..26d8f23f7015 --- /dev/null +++ b/fractals/hilbert_curve.py @@ -0,0 +1,70 @@ +""" +Hilbert Curve + +The Hilbert curve is a space-filling curve that recursively fills a square +with an intricate pattern. It is used in computer science, graphics, and various fields. + +Reference: +https://en.wikipedia.org/wiki/Hilbert_curve + +Requirements: + - matplotlib + - numpy +""" + +import matplotlib.pyplot as plt + + +def hilbert_curve(order, x0=0, y0=0, xi=1, xj=0, yi=0, yj=1): + """ + Generates the points for the Hilbert curve of the specified order. + + The Hilbert curve is built using recursive rules. This function returns + a list of (x, y) points. + + Parameters: + - order: the recursion depth or order of the curve + - x0, y0: the starting coordinates + - xi, xj: the transformation matrix for x coordinates + - yi, yj: the transformation matrix for y coordinates + + >>> len(hilbert_curve(1)) + 5 + >>> len(hilbert_curve(2)) + 17 + >>> len(hilbert_curve(3)) + 65 + """ + if order == 0: + return [(x0 + (xi + yi) / 2, y0 + (xj + yj) / 2)] + + points = [] + points += hilbert_curve(order - 1, x0, y0, yi / 2, yj / 2, xi / 2, xj / 2) + points += hilbert_curve( + order - 1, x0 + xi / 2, y0 + xj / 2, xi / 2, xj / 2, yi / 2, yj / 2 + ) + points += hilbert_curve( + order - 1, x0 + xi / 2 + yi / 2, y0 + xj / 2 + yj / 2, xi / 2, xj / 2, yi / 2, yj / 2 + ) + points += hilbert_curve( + order - 1, x0 + xi / 2 + yi, y0 + xj / 2 + yj, -yi / 2, -yj / 2, -xi / 2, -xj / 2 + ) + + return points + + +def plot_hilbert_curve(points): + """ + Plots the Hilbert curve using matplotlib. + """ + x, y = zip(*points) + plt.plot(x, y) + plt.title("Hilbert Curve") + plt.gca().set_aspect('equal', adjustable='box') + plt.show() + + +if __name__ == "__main__": + order = 5 # Order of the Hilbert curve + curve_points = hilbert_curve(order) + plot_hilbert_curve(curve_points) From 77ebcc4fa9d414c80790042ccc087d61f8f494ab Mon Sep 17 00:00:00 2001 From: Simon Waldherr Date: Thu, 24 Oct 2024 21:35:01 +0200 Subject: [PATCH 2/4] apply coding style --- fractals/hilbert_curve.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/fractals/hilbert_curve.py b/fractals/hilbert_curve.py index 26d8f23f7015..519f5d1a5174 100644 --- a/fractals/hilbert_curve.py +++ b/fractals/hilbert_curve.py @@ -44,10 +44,22 @@ def hilbert_curve(order, x0=0, y0=0, xi=1, xj=0, yi=0, yj=1): order - 1, x0 + xi / 2, y0 + xj / 2, xi / 2, xj / 2, yi / 2, yj / 2 ) points += hilbert_curve( - order - 1, x0 + xi / 2 + yi / 2, y0 + xj / 2 + yj / 2, xi / 2, xj / 2, yi / 2, yj / 2 + order - 1, + x0 + xi / 2 + yi / 2, + y0 + xj / 2 + yj / 2, + xi / 2, + xj / 2, + yi / 2, + yj / 2, ) points += hilbert_curve( - order - 1, x0 + xi / 2 + yi, y0 + xj / 2 + yj, -yi / 2, -yj / 2, -xi / 2, -xj / 2 + order - 1, + x0 + xi / 2 + yi, + y0 + xj / 2 + yj, + -yi / 2, + -yj / 2, + -xi / 2, + -xj / 2, ) return points @@ -60,7 +72,7 @@ def plot_hilbert_curve(points): x, y = zip(*points) plt.plot(x, y) plt.title("Hilbert Curve") - plt.gca().set_aspect('equal', adjustable='box') + plt.gca().set_aspect("equal", adjustable="box") plt.show() From 4a6642a5b7af6b93657838a67989f1bedc7121e7 Mon Sep 17 00:00:00 2001 From: Simon Waldherr Date: Thu, 24 Oct 2024 22:25:59 +0200 Subject: [PATCH 3/4] better coding style --- fractals/hilbert_curve.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/fractals/hilbert_curve.py b/fractals/hilbert_curve.py index 519f5d1a5174..c5d5aa58c54e 100644 --- a/fractals/hilbert_curve.py +++ b/fractals/hilbert_curve.py @@ -12,10 +12,20 @@ - numpy """ +import doctest + import matplotlib.pyplot as plt -def hilbert_curve(order, x0=0, y0=0, xi=1, xj=0, yi=0, yj=1): +def hilbert_curve( + order: int, + x0: float = 0, + y0: float = 0, + xi: float = 1, + xj: float = 0, + yi: float = 0, + yj: float = 1, +) -> list[tuple[float, float]]: """ Generates the points for the Hilbert curve of the specified order. @@ -28,6 +38,9 @@ def hilbert_curve(order, x0=0, y0=0, xi=1, xj=0, yi=0, yj=1): - xi, xj: the transformation matrix for x coordinates - yi, yj: the transformation matrix for y coordinates + Returns: + - A list of (x, y) coordinates representing the Hilbert curve. + >>> len(hilbert_curve(1)) 5 >>> len(hilbert_curve(2)) @@ -65,9 +78,15 @@ def hilbert_curve(order, x0=0, y0=0, xi=1, xj=0, yi=0, yj=1): return points -def plot_hilbert_curve(points): +def plot_hilbert_curve(points: list[tuple[float, float]]) -> None: """ Plots the Hilbert curve using matplotlib. + + Parameters: + - points: A list of (x, y) coordinates representing the Hilbert curve. + + Returns: + - None """ x, y = zip(*points) plt.plot(x, y) @@ -77,6 +96,8 @@ def plot_hilbert_curve(points): if __name__ == "__main__": + doctest.testmod() + order = 5 # Order of the Hilbert curve curve_points = hilbert_curve(order) plot_hilbert_curve(curve_points) From f3101eae93284169898b83291b3131b06ec32bb6 Mon Sep 17 00:00:00 2001 From: Simon Waldherr Date: Thu, 24 Oct 2024 23:09:24 +0200 Subject: [PATCH 4/4] fix errors in test cases --- fractals/hilbert_curve.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fractals/hilbert_curve.py b/fractals/hilbert_curve.py index c5d5aa58c54e..bb6cb05a0ff0 100644 --- a/fractals/hilbert_curve.py +++ b/fractals/hilbert_curve.py @@ -42,11 +42,11 @@ def hilbert_curve( - A list of (x, y) coordinates representing the Hilbert curve. >>> len(hilbert_curve(1)) - 5 + 4 >>> len(hilbert_curve(2)) - 17 + 16 >>> len(hilbert_curve(3)) - 65 + 64 """ if order == 0: return [(x0 + (xi + yi) / 2, y0 + (xj + yj) / 2)]