Meander Generator

Create a 2D array with a snake-like numerical pattern.

The most common use case for this is for an "energy meander" or a "dose series". However, this can also be used for a "focus meander", or some other meandering array; for this reason, no units are imposed on the generator.


Use "Lower Left" for asml300 meanders.

Use "Upper Left" for mla150 and gcaws6 meanders.

Crestec and Crestec130kv can be configured in either orientation.

Your generated array will appear here.



Want to create a FEM instead? Click here for the ASML FEM generator or here for the mla150 FEM generator.

import asyncio from pyscript import document from js import navigator, window def generate_meandering_array(start, step, rows, cols, start_corner="lower-left"): """ Generates a 2D array with a meandering (snake-like) pattern. The starting corner can be specified. """ grid = [[0 for _ in range(cols)] for _ in range(rows)] current_value = start if start_corner == "lower-left": # Start at bottom-left and move up for r in range(rows - 1, -1, -1): row_from_bottom = (rows - 1) - r if row_from_bottom % 2 == 0: # On even rows from bottom, go left-to-right for c in range(cols): grid[r][c] = current_value current_value += step else: # On odd rows from bottom, go right-to-left for c in range(cols - 1, -1, -1): grid[r][c] = current_value current_value += step else: # start_corner == "upper-left" # Start at top-left and move down for r in range(rows): if r % 2 == 0: # On even rows from top (0, 2, ...), go left-to-right for c in range(cols): grid[r][c] = current_value current_value += step else: # On odd rows from top (1, 3, ...), go right-to-left for c in range(cols - 1, -1, -1): grid[r][c] = current_value current_value += step return grid def toggle_corner(event): """Toggles the starting corner state and updates the button text.""" button = event.target if button.dataset.corner == "lower-left": button.dataset.corner = "upper-left" button.textContent = "Upper Left" else: button.dataset.corner = "lower-left" button.textContent = "Lower Left" def generate_and_display(event): """ Reads inputs, calls the generator, and displays the result. """ output_div = document.querySelector("#output") action_buttons_container = document.querySelector("#action-buttons-container") # 1. Get values and perform validation try: start = float(document.querySelector("#start").value) step = float(document.querySelector("#step").value) rows = int(document.querySelector("#rows").value) cols = int(document.querySelector("#cols").value) start_corner = document.querySelector("#corner-toggle").dataset.corner if rows <= 0 or cols <= 0: output_div.innerText = "Error: Rows and columns must be positive numbers." action_buttons_container.classList.add("hidden") return except ValueError: output_div.innerText = "Error: Please enter valid numbers for all fields." action_buttons_container.classList.add("hidden") return # 2. Generate the data meandering_array = generate_meandering_array(start, step, rows, cols, start_corner) # 3. Clear previous output and build the table output_div.innerHTML = "" # Clear the placeholder text table = document.createElement("table") table.classList.add("w-full", "text-sm", "border-collapse") for row_data in meandering_array: tr = document.createElement("tr") for cell_data in row_data: td = document.createElement("td") td.classList.add("p-3", "border", "border-gray-300", "text-center") if cell_data == int(cell_data): td.textContent = str(int(cell_data)) else: td.textContent = str(round(cell_data, 4)) tr.appendChild(td) table.appendChild(tr) output_div.appendChild(table) # Make the action buttons visible action_buttons_container.classList.remove("hidden") async def copy_table(event): """Copies the generated table to the clipboard in a tab-separated format.""" button = document.querySelector("#copy-button") output_div = document.querySelector("#output") table = output_div.querySelector("table") if not table: return # Build the tab-separated string for clipboard table_content = "" for row in table.querySelectorAll("tr"): cells = [cell.textContent for cell in row.querySelectorAll("td")] table_content += "\t".join(cells) + "\n" try: await navigator.clipboard.writeText(table_content) original_text = button.textContent button.textContent = "Copied!" await asyncio.sleep(2) # Show "Copied!" for 2 seconds button.textContent = original_text except Exception as e: button.textContent = "Copy Failed" print(f"Error copying to clipboard: {e}") def print_table(event): """Prepares the table for printing and opens the print dialog.""" output_div = document.querySelector("#output") # Add a class to the element we want to print output_div.classList.add("printable") # Trigger the browser's print functionality window.print() # Clean up by removing the class after printing is done output_div.classList.remove("printable")