Commits: 2

Describe the stacks and gutters as linear equations

index f9341b2..89fb03b 100644
--- a/playground.typ
+++ b/playground.typ
@@ -381,3 +381,149 @@ But adding a gutter messes the height of the stack:
=    ("780x300.jpg", "500x480.jpg", "780x300.jpg"),
=    "360x480.jpg",
=)
+
+== Solution for stacks and gutters
+
+To solve the image row with stacks and gutters we need to think of the problem as a set of $n$ equations with $n$ unknowns, where $n$ is the number of cells in a given row.
+
++ The total width $w$ of the row is known.
+
++ The height $h$ of every cell is equal.
+
++ We must solve for the width of each cell $w_i$
++ The aspect ratio of each cell content $r_i$ can be computed from the ratios of stacked images
+
+
++ For each cell the gutter height $g_i$ is known ($(s_i - 1) * g$) where $s_i$ is the number of stacked images in cell $i$ and $g$ is the given gutter size.
+
+Sum of all widths equal the total width
+
+$
+    w_0 + w_1 + ... + w_n = w
+$
+
+The height of each cell is the same
+
+$
+    h = g_i + w_i / r_i
+$
+
+
+The stack ratio $r_i$ can be calculated as inversion of the sum of inverted aspect ratios of each image.
+
+$
+    r_i = (sum_(j=0)^s r_j^(-1) )^(-1)
+$
+
+Where $s$ is the number of stacked images and $r_j$ is the ration of a stacked image $j$. Inverted ratio $r^(-1)$ is a ratio of height to width, as opposed to regular width to height. Conceptually it's like stacking the images on top of each other, scaling them to have equal width and measuring the aspect ratio of the whole stack.
+
+Let's try to solve it for a simplified set of images.
+
++ 300 ÷ 600 (portrait)
++ 800 ÷ 400 (landscape)
++ 600 ÷ 200 (landscape) <resolutions>
+
+#let total_width = 360pt
+#let gutter = 12pt
+
+
+The last two should be stacked, so there are two rows. Let's say the gutter is #gutter and available space is #total_width.
+
+
+$
+    g = #gutter
+$
+
+For simplicity let's already subtract the vertical gutter from the total width.
+
+$
+    w = #total_width
+$
+
+We can treat each cell as a stack: `(0) (1, 2)`. First cell is a stack of one image, second is a stack of two.
+
+The content ratio of first cell is simple
+
+$
+    r_0
+    = 300 / 600
+    = 0.5
+$
+
+
+The content ratio of the second is
+
+$
+    r_1
+    = 1 / ((800 / 400)^(-1) + (600 / 200)^(-1))
+    = (1/2 + 1/3)^(-1)
+    = 1.2
+$
+
+Now it's possible to solve the set of two equations to find $w_0$ and $w_1$:
+
+$
+    cases(
+        h = g_i + w_i / r_i,
+        w_0 + w_i = w
+    )
+$
+
+Becasue $h$ is the same for each cell we can write it as:
+
+$
+    cases(
+      g_0 + w_0 / r_0 = g_1 + w_1 / r_1,
+      w_0 + w_i = w
+    )
+$
+
+Substituting known values:
+
+$
+    cases(
+        0 + w_0 / 0.5 = 12 + w_1 / 1.2,
+        w_0 + w_1 = 360 \
+    )
+$
+
+Let's reduce the first equation to express $w_0$ in terms of $w_1$.
+
++ $2w_0 = 12 + w_1 / 1.2$
++ $w_0 = 6 + w_1 / 2.4$
+
+Now we can use it in the second equation and solve it:
+
++ $(6 + w_1 / 2.4) + w_1 = 360$
++ $(14.4 + w_1) + 2.4w_1 = 864$ (×2.4)
++ $3.4w_1 = 849.6$
++ $w_1 approx 250$
+
+Knowing the approximate value of $w_1$ and the total width $w$ we can calculate $w_0$ as the remaining length
+
++ $w_0 + w_1 = w$
++ $w_0 + 250 = 360$
++ $w_0 = 110$
+
+Let's check if the height's add up. Again, the image resolutions are are:
+
++ 300 ÷ 600 (portrait, 1:2)
++ 800 ÷ 400 (landscape, 2:1)
++ 600 ÷ 200 (landscape, 3:1)
+
+If the first image width $w_0$ is 110pt, then the height is
+
++ $h = w_0r_0^(-1) + g_0$
++ $h = 110 × 2 + 0$
++ $h = 220$.
+
+The height of two images in the stack combined would be
+
++ $h = w_1r_1^(-1) + g_i$
++ $h = 250 × 1.2^(-1) + 12$
++ $h = 250 × 10/12 + 12$
++ $h approx 220$
+
+It checks! Both cells have approximately the same height.
+
+Now the question is how to scale it arbitrary number of cells. For each cell there would be an additional unknown $w_i$, but also an additional equation $h = w_i r_i + g_i$

Describe "divide and conquer" approach to stacks and gutters

index 89fb03b..699bf9f 100644
--- a/playground.typ
+++ b/playground.typ
@@ -527,3 +527,18 @@ The height of two images in the stack combined would be
=It checks! Both cells have approximately the same height.
=
=Now the question is how to scale it arbitrary number of cells. For each cell there would be an additional unknown $w_i$, but also an additional equation $h = w_i r_i + g_i$
+
+== Divide and conquer approximation
+
+The equations above seem to work, and I can solve them on paper, but I don't (yet) know how to program a solver in Typst. In the mean time I want to try a "divide and conquer" approach to approximate the height and widths.
+
+In very broad terms:
+
+1. Identify the minimum possible height $h_min$ (that would be the height without any gutters). The current implementation of `image-row` function can calculate this.
+2. Identify the maximum possible height $h_max$ (that would be $h_min + max(g_i)$, so all the gutters without shrinking the content, which would be a case in a single cell containing a stack)
+3. Solve the $h = r_i w_i + g_i$ equations using $h = (h_min + h_max) / 2$ (i.e. midpoint)
+4. If $sum_(i=o)^n w_i approx w$ then that's it.
+5. If $sum_(i=o)^n w_i < w$, set $h_min := h$ and solve again.
+6. If $sum_(i=o)^n w_i > w$, set $h_max := h$ and solve again.
+
+Do it at most 100 times or so. Consider some small length, like 1pt to be sufficiently precise.