From 148225538b95567b0e4a2198ccc59f605289d1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Nordstr=C3=B6m?= Date: Thu, 29 May 2025 23:33:39 +0200 Subject: [PATCH] wip: add sky and start working on mountains --- katie_hewson_inspired/config/.gitignore | 1 + katie_hewson_inspired/output/.gitignore | 2 + .../sketch_katie_hewson_inspired.py | 108 ++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 katie_hewson_inspired/config/.gitignore create mode 100644 katie_hewson_inspired/output/.gitignore create mode 100644 katie_hewson_inspired/sketch_katie_hewson_inspired.py diff --git a/katie_hewson_inspired/config/.gitignore b/katie_hewson_inspired/config/.gitignore new file mode 100644 index 0000000..6830205 --- /dev/null +++ b/katie_hewson_inspired/config/.gitignore @@ -0,0 +1 @@ +/*.json diff --git a/katie_hewson_inspired/output/.gitignore b/katie_hewson_inspired/output/.gitignore new file mode 100644 index 0000000..a3ff1c0 --- /dev/null +++ b/katie_hewson_inspired/output/.gitignore @@ -0,0 +1,2 @@ +/*.svg +/*.hpgl diff --git a/katie_hewson_inspired/sketch_katie_hewson_inspired.py b/katie_hewson_inspired/sketch_katie_hewson_inspired.py new file mode 100644 index 0000000..61b81e0 --- /dev/null +++ b/katie_hewson_inspired/sketch_katie_hewson_inspired.py @@ -0,0 +1,108 @@ +import math +import vsketch +import vpype as vp +import numpy as np + +DEBUG = False + +class KatieHewsonInspiredSketch(vsketch.SketchClass): + + margin = vsketch.Param(1.0, step=0.1) + cloud_coverage = vsketch.Param(0.55, 0, 1, step=0.01) + cloud_lines = vsketch.Param(200, 0, 300, step=1) + + def sky(self, vsk : vsketch.Vsketch, start : tuple, end : tuple)-> None: + if DEBUG: + vsk.stroke(2) + x = np.linspace(start[0], end[0], 200, endpoint=True) + y = np.linspace(start[1], end[1], self.cloud_lines, endpoint=True) + noise = vsk.noise(x * 0.1, y * 0.1) + + for i_y, y_val in enumerate(y): + # each column, draw a line for every pairs of values + start_ = -1 + for i_x, x_val in enumerate(x): + if noise[i_x, i_y] < self.cloud_coverage: + if start_ == -1: + start_ = i_x + else: + if start_ != -1: + vsk.line( + x[start_], y_val, + x[i_x - 1], y_val + ) + start_ = -1 + if start_ != -1: + vsk.line( + x[start_], y_val, + x[-1], y_val + ) + + + def mountains(self, vsk: vsketch.Vsketch, start: tuple, end: tuple) -> None: + if DEBUG: + vsk.stroke(3) + # Generate a monotonic random array between start[0] and end[0] + x = np.sort(np.random.uniform(start[0], end[0], 200)) + x[0] = start[0] + x[-1] = end[0] + freq = 0.3 # Adjust this value for more or less frequent peaks + phase = np.random.uniform(0, 2 * np.pi) + y_pure = np.cos(x * freq + phase) * 2 + (end[1] - start[1]) / 2 + y = y_pure + vsk.noise(x * 0.5) * 2 + + x = np.append(x, [end[0], start[0], x[0]]) + y = np.append(y, [end[1], end[1], y[0]]) + vsk.polygon(x, y) + + # find where the derivative is zero (peaks) + dy = np.diff(y_pure) + peaks = np.where(np.diff(np.sign(dy)))[0] + 1 + for peak in peaks: + vsk.line( + x[peak], y[peak], + x[peak], end[1] + ) + + + + + def occultation(self, vsk: vsketch.Vsketch) -> None: + vsk.vpype("occult -i") + + def draw(self, vsk: vsketch.Vsketch) -> None: + vsk.size("a4", landscape=True) + vsk.scale("cm") + + width_cm = vsk.width / vp.UNITS["cm"] + height_cm = vsk.height / vp.UNITS["cm"] + + vsk.rect( + self.margin, + self.margin, + width_cm - self.margin , + height_cm - self.margin + ) + self.occultation(vsk) + self.sky( + vsk, + (self.margin,self.margin), + (width_cm, height_cm) + ) + self.occultation(vsk) + self.mountains( + vsk, + (self.margin, self.margin), + (width_cm, height_cm) + ) + self.occultation(vsk) + + + + + def finalize(self, vsk: vsketch.Vsketch) -> None: + vsk.vpype("linemerge linesimplify reloop linesort") + + +if __name__ == "__main__": + KatieHewsonInspiredSketch.display()