{"id":1573,"date":"2026-04-24T15:08:48","date_gmt":"2026-04-24T13:08:48","guid":{"rendered":"https:\/\/www.ellipsis.pink\/phl\/?page_id=1573"},"modified":"2026-05-04T15:59:48","modified_gmt":"2026-05-04T13:59:48","slug":"generative-art-sketches","status":"publish","type":"page","link":"https:\/\/www.ellipsis.pink\/phl\/?page_id=1573","title":{"rendered":"generative art: sketches"},"content":{"rendered":"\n<div class=\"wp-block-essential-blocks-advanced-heading  root-eb-advance-heading-b4857\"><div class=\"eb-parent-wrapper eb-parent-eb-advance-heading-b4857 \"><div class=\"eb-advance-heading-wrapper eb-advance-heading-b4857 button-1 waviy\" data-id=\"eb-advance-heading-b4857\"><h2 class=\"eb-ah-title\"><span class=\"first-title\">generative art: sketches<\/span><\/h2><\/div><\/div><\/div>\n\n\n\n<p class=\"is-style-text-subtitle has-accent-4-color has-text-color has-link-color has-large-font-size wp-elements-2ccb84028946168b322f5b421c0dafdb is-style-text-subtitle--1\" style=\"font-style:normal;font-weight:400\"><strong>Patterns, Fragments, Traces<\/strong> | <strong>Work in Progress<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<div data-wp-context=\"{ &quot;autoclose&quot;: false, &quot;accordionItems&quot;: [] }\" data-wp-interactive=\"core\/accordion\" role=\"group\" class=\"wp-block-accordion is-layout-flow wp-block-accordion-is-layout-flow\">\n<div data-wp-class--is-open=\"state.isOpen\" data-wp-context=\"{ &quot;id&quot;: &quot;accordion-item-2&quot;, &quot;openByDefault&quot;: false }\" data-wp-init=\"callbacks.initAccordionItems\" data-wp-on-window--hashchange=\"callbacks.hashChange\" class=\"wp-block-accordion-item is-layout-flow wp-block-accordion-item-is-layout-flow\">\n<h3 class=\"wp-block-accordion-heading has-accent-4-color has-text-color has-link-color wp-elements-f60b766219c7b961de9a5ec401493ea5\"><button aria-expanded=\"false\" aria-controls=\"accordion-item-2-panel\" data-wp-bind--aria-expanded=\"state.isOpen\" data-wp-on--click=\"actions.toggle\" data-wp-on--keydown=\"actions.handleKeyDown\" id=\"accordion-item-2\" type=\"button\" class=\"wp-block-accordion-heading__toggle\"><span class=\"wp-block-accordion-heading__toggle-title\">Current experiments from an ongoing body of work explore analogue, digital and print-based forms as linked states of a mobile practice. Hand-drawn sketches, mixed-media works on paper, Processing code and JavaScript animations operate as digital\u2013analogue \u201cpolyptychs\u201d: connected parts of one evolving work rather than separate projects. They move between paper, code, screen and print, looping from sketch to digital display and back again through further reworking.<\/span><span class=\"wp-block-accordion-heading__toggle-icon\" aria-hidden=\"true\">+<\/span><\/button><\/h3>\n\n\n\n<div inert aria-labelledby=\"accordion-item-2\" data-wp-bind--inert=\"!state.isOpen\" id=\"accordion-item-2-panel\" role=\"region\" class=\"wp-block-accordion-panel is-layout-flow wp-block-accordion-panel-is-layout-flow\">\n<p class=\"has-accent-4-color has-text-color has-link-color wp-elements-3125d82812202f5570365eae4dd7af15\">This project investigates how an art practice can remain active, rigorous and generative when the stable studio is replaced by movement, temporary conditions and portable tools.<\/p>\n\n\n\n<p class=\"has-accent-4-color has-text-color has-link-color wp-elements-24c8aaf8cd4ec319157427daf84826b6\">Pattern, text, image and code carry rhythm, repetition, disruption and cultural memory without fixing the work into image, scene or story. Together, they form a visual language shaped by place, language and cultural movement. Patterns, fragments and traces are not used as decoration or genre, but as ways of translating landscapes, memories, texts and movement into portable visual structures without resolving them into a fixed narrative.<\/p>\n\n\n\n<p class=\"has-accent-4-color has-text-color has-link-color wp-elements-58935ca5873c8a8296580a98a97069b3\">Mobility becomes both a constraint and a generative condition, producing works that are lighter, smaller and more experimental, but also more fragile, unresolved and fragmented. Within this mobile practice, sustainability is treated neither as a polished ideal nor as a failure of permanence, but as a process through which the work adapts, fragments, re-forms and continues under temporary or unstable conditions.<\/p>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:55px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"496\" height=\"720\" src=\"https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/05\/patterns-are-made-of-strokes-A4.jpg\" alt=\"\" class=\"wp-image-1737\" style=\"width:auto;height:720px\" srcset=\"https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/05\/patterns-are-made-of-strokes-A4.jpg 496w, https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/05\/patterns-are-made-of-strokes-A4-207x300.jpg 207w\" sizes=\"auto, (max-width: 496px) 100vw, 496px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<div class=\"wp-block-gutenbergp5-p5js gutenbergp5-align-center\"><iframe srcdoc=\"\n        <!DOCTYPE html&gt;\n        <html&gt;\n            <body style=&quot;padding: 0; margin: 0;&quot;&gt;<\/body&gt;\n            <script src=&quot;https:\/\/www.ellipsis.pink\/phl\/wp-content\/plugins\/easy-p5-js-block\/\/assets\/js\/p5.min.js&quot;&gt;<\/script&gt;\n            <script&gt;\n                function setup() {\n  createCanvas(1080, 720);\n}\n\nlet word1 = &quot;die faszination mit exakt geraden Linien&quot;;\nlet word2 = &quot;parallel lines meet in infinity&quot;;\nlet word3 = &quot;angles have to be 90 degrees&quot;;\n\nlet typingSpeed1 = 5;\nlet typingSpeed2 = 8;\nlet typingSpeed3 = 11;\n\nlet totalLines = 70;\n\nlet words;\nlet typingSpeeds;\nlet palette;\n\nlet xPositions = [];\nlet yPositions = [];\nlet lineWidths = [];\nlet fontSizes = [];\n\nlet wordChoice = [];\nlet methodChoice = [];\nlet colourChoice = [];\n\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n\n  words = [word1, word2, word3];\n  typingSpeeds = [typingSpeed1, typingSpeed2, typingSpeed3];\n\n  palette = [\n    color(0),             \/\/ black\n    color(145),          \/\/grey\n    color(241, 208, 9)    \/\/ orange\n  ];\n\n  randomiseTextField();\n}\n\nfunction draw() {\n  background(255);\n\n  for (let i = 0; i < totalLines; i++) {\n    let chosenWord = wordChoice[i];\n    let fullText = words[chosenWord];\n    let typeSpeed = typingSpeeds[chosenWord];\n\n    let letterCount = floor(frameCount \/ typeSpeed) % (fullText.length + 1);\n    let visibleText = fullText.substring(0, letterCount);\n\n    textSize(fontSizes[i]);\n\n    let c = palette[colourChoice[i]];\n    fill(c);\n    stroke(c);\n\n    \/\/ guideline\n    line(\n      xPositions[i],\n      yPositions[i] + 8,\n      xPositions[i] + lineWidths[i],\n      yPositions[i] + 8\n    );\n\n    \/\/ method 0 = steady left-to-right typing\n    if (methodChoice[i] === 0) {\n      drawTypedTextWithFixedLetterSpacing(\n        visibleText,\n        fullText,\n        xPositions[i],\n        yPositions[i],\n        lineWidths[i]\n      );\n    }\n\n    \/\/ method 1 = expanding \/ stretched typing\n    if (methodChoice[i] === 1) {\n      drawStretchedText(\n        visibleText,\n        xPositions[i],\n        yPositions[i],\n        lineWidths[i]\n      );\n    }\n  }\n}\n\nfunction randomiseTextField() {\n  for (let i = 0; i < totalLines; i++) {\n    xPositions[i] = random(0, width * 0.35);\n    yPositions[i] = random(40, height - 40);\n\n    lineWidths[i] = random(width * 0.35, width - xPositions[i]);\n    fontSizes[i] = random(16, 60);\n\n    \/\/ choose one of the three phrases\n    wordChoice[i] = floor(random(3));\n\n    \/\/ choose typing method\n    methodChoice[i] = floor(random(2));\n\n    \/\/ choose colour: 0 = black, 1 = grey, 2 = orange\n    colourChoice[i] = floor(random(3));\n  }\n}\n\n\/\/ click mouse to reshuffle everything\nfunction mousePressed() {\n  randomiseTextField();\n}\n\n\/\/ resize with browser window\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n  randomiseTextField();\n}\n\n\n\/\/ METHOD 1\n\/\/ steady typing from left to right\nfunction drawTypedTextWithFixedLetterSpacing(\n  visibleText,\n  fullText,\n  x,\n  y,\n  targetWidth\n) {\n  if (visibleText.length === 0) {\n    return;\n  }\n\n  let normalWidth = textWidth(fullText);\n  let extraSpace = targetWidth - normalWidth;\n\n  let letterSpacing = 0;\n\n  if (fullText.length &gt; 1) {\n    letterSpacing = extraSpace \/ (fullText.length - 1);\n  }\n\n  let currentX = x;\n\n  for (let i = 0; i < visibleText.length; i++) {\n    let letter = visibleText.substring(i, i + 1);\n    text(letter, currentX, y);\n    currentX = currentX + textWidth(letter) + letterSpacing;\n  }\n}\n\n\n\/\/ METHOD 2\n\/\/ expanding stretched typing\nfunction drawStretchedText(txt, x, y, targetWidth) {\n  if (txt.length === 0) {\n    return;\n  }\n\n  if (txt.length === 1) {\n    text(txt, x, y);\n    return;\n  }\n\n  let normalWidth = textWidth(txt);\n  let extraSpace = targetWidth - normalWidth;\n  let gap = extraSpace \/ (txt.length - 1);\n\n  let currentX = x;\n\n  for (let i = 0; i < txt.length; i++) {\n    let letter = txt.substring(i, i + 1);\n    text(letter, currentX, y);\n    currentX = currentX + textWidth(letter) + gap;\n  }\n}\n            <\/script&gt;\n        <\/html&gt;\" sandbox=\"allow-scripts allow-same-origin\" scrolling=\"no\" style=\"width:1080px;height:720px;overflow:hidden;\" width=\"1080px\" height=\"720px\" class=\"gutenbergp5-noresize\" title=\"p5.js canvas\"><\/iframe><\/div>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:55px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"has-small-font-size\">\u00a0<em>Patterns Are Made of Strokes<\/em>,<\/p>\n\n\n\n<p class=\"has-small-font-size\"> acrylic on paper, 2026. First part of a multimedia diptych. Work in progress toward\u00a0<em>Patterns, Fragments and Traces<\/em>.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"has-small-font-size\"><em>Parallel Lines<\/em>, interactive JavaScript artwork, 2026. <\/p>\n\n\n\n<p class=\"has-small-font-size\">Second part of the multimedia diptych, image changes on mouse click<\/p>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"345\" height=\"800\" src=\"http:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/doodle-1-800.jpg\" alt=\"\" class=\"wp-image-1581\" srcset=\"https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/doodle-1-800.jpg 345w, https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/doodle-1-800-129x300.jpg 129w\" sizes=\"auto, (max-width: 345px) 100vw, 345px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"539\" src=\"http:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/multiple-ellipse-figures-1024x539.jpg\" alt=\"\" class=\"wp-image-1625\" srcset=\"https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/multiple-ellipse-figures-1024x539.jpg 1024w, https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/multiple-ellipse-figures-300x158.jpg 300w, https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/multiple-ellipse-figures-768x405.jpg 768w, https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/multiple-ellipse-figures.jpg 1139w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-small-font-size\">Ink doodle translated to Processing code<\/p>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p class=\"has-small-font-size\">Ink on paper sketch and transformation into a javascript animation<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"410\" height=\"589\" src=\"http:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/ellipse-drawing.jpg\" alt=\"\" class=\"wp-image-1591\" style=\"object-fit:cover\" srcset=\"https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/ellipse-drawing.jpg 410w, https:\/\/www.ellipsis.pink\/phl\/wp-content\/uploads\/2026\/04\/ellipse-drawing-209x300.jpg 209w\" sizes=\"auto, (max-width: 410px) 100vw, 410px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-gutenbergp5-p5js gutenbergp5-align-center\"><iframe srcdoc=\"\n        <!DOCTYPE html&gt;\n        <html&gt;\n            <body style=&quot;padding: 0; margin: 0;&quot;&gt;<\/body&gt;\n            <script src=&quot;https:\/\/www.ellipsis.pink\/phl\/wp-content\/plugins\/easy-p5-js-block\/\/assets\/js\/p5.min.js&quot;&gt;<\/script&gt;\n            <script&gt;\n                \/\/ Continuous asynchronous ellipse animation\n\/\/ p5.js version\n\/\/ Canvas: 595 x 842 px\n\nlet baseW = 500.0;\nlet baseH = 900.0;\n\n\/\/ x, y, w, h, strokeMin, strokeMax, rotation\nlet ellipseData = [\n  \/\/ upper area\n  [165,  85, 130,  55, 1.5, 3.5, -0.10],\n  [290,  70, 105,  65, 2.0, 4.5,  0.12],\n  [150, 145, 165,  45, 1.5, 3.5, -0.18],\n  [270, 160, 200, 105, 1.0, 2.5,  0.08],\n  [420, 140,  85,  55, 1.5, 3.5,  0.05],\n\n  \/\/ upper-middle cluster\n  [150, 245, 160,  80, 1.5, 3.5,  0.10],\n  [290, 255, 210,  70, 1.0, 2.5, -0.08],\n  [370, 280,  95,  45, 1.5, 3.5,  0.18],\n  [410, 300, 110, 175, 2.0, 4.5, -0.22],\n  [ 92, 310, 125,  60, 2.5, 5.5, -0.10],\n\n  \/\/ orange ellipses - bottom of top part\n  [250, 330, 120,  42, 1.4, 3.2,  0.10],\n  [345, 348, 150,  50, 1.5, 3.4, -0.20],\n  [140, 365, 115,  44, 1.4, 3.0,  0.28],\n\n  \/\/ extra red ellipses - middle section\n  [205, 350, 155,  52, 1.4, 3.2, -0.28],\n  [315, 360, 145,  48, 1.5, 3.4,  0.24],\n  [185, 475, 170,  58, 1.5, 3.5, -0.16],\n  [300, 525, 185,  62, 1.6, 3.6,  0.20],\n\n  \/\/ central area\n  [260, 390, 220,  75, 1.5, 3.5,  0.05],\n  [230, 420, 190, 120, 1.0, 2.5, -0.18],\n  [340, 430, 220,  70, 1.0, 2.5, -0.04],\n  [405, 410, 130,  95, 3.0, 6.5,  0.20],\n  [100, 430, 140,  80, 1.5, 3.5,  0.10],\n  [120, 500, 170,  90, 1.0, 2.5,  0.06],\n\n  \/\/ orange ellipses - top of bottom part\n  [105, 560, 135,  48, 1.5, 3.2, -0.18],\n  [260, 610, 160,  52, 1.5, 3.4,  0.22],\n  [365, 615, 125,  46, 1.4, 3.1, -0.14],\n\n  \/\/ lower-middle area\n  [180, 575, 220,  70, 1.5, 3.5,  0.04],\n  [315, 590, 210,  70, 1.0, 2.5,  0.10],\n  [110, 670, 140, 190, 2.0, 4.5, -0.32],\n  [275, 690, 200,  80, 2.0, 4.5,  0.14],\n  [390, 665, 135,  80, 1.5, 3.5, -0.26],\n  [195, 740, 120,  70, 2.0, 4.5, -0.20],\n\n  \/\/ bottom area\n  [250, 780, 220,  70, 1.5, 3.5,  0.05],\n  [330, 830, 135,  55, 2.5, 5.5,  0.16],\n  [395, 760, 115,  75, 1.0, 2.5,  0.16],\n  [410, 830, 140,  80, 1.0, 2.5,  0.18]\n];\n\nlet ellipseColors = [];\nlet ellipseAlpha = [];\n\nlet cycleProgress = [];\nlet cycleSpeed = [];\nlet startAngles = [];\n\nlet colRed;\nlet colBlue;\nlet colOrange;\nlet colGreen;\n\nfunction setup() {\n  createCanvas(417, 589);\n  smooth();\n\n  colRed = color(&quot;#CB2D58&quot;);\n  colBlue = color(&quot;#186593&quot;);\n  colOrange = color(&quot;#EA4909&quot;);\n  colGreen = color(&quot;#6EEA09&quot;);\n\n  ellipseColors = [\n    \/\/ upper area\n    colRed, colRed, colBlue, colRed, colGreen,\n\n    \/\/ upper-middle cluster\n    colRed, colRed, colOrange, colGreen, colBlue,\n\n    \/\/ orange - bottom of top part\n    colOrange, colOrange, colOrange,\n\n    \/\/ extra reds\n    colRed, colRed, colRed, colRed,\n\n    \/\/ central\n    colRed, colBlue, colGreen, colOrange, colBlue, colBlue,\n\n    \/\/ orange - top of bottom part\n    colOrange, colOrange, colOrange,\n\n    \/\/ lower-middle\n    colRed, colOrange, colBlue, colRed, colGreen, colOrange,\n\n    \/\/ bottom\n    colRed, colBlue, colGreen, colGreen\n  ];\n\n  ellipseAlpha = [\n    \/\/ upper area\n    255, 255, 255, 120, 255,\n\n    \/\/ upper-middle cluster\n    255, 255, 255, 255, 255,\n\n    \/\/ orange - bottom of top part\n    255, 255, 255,\n\n    \/\/ extra reds\n    255, 255, 255, 255,\n\n    \/\/ central\n    255, 255, 255, 255, 255, 255,\n\n    \/\/ orange - top of bottom part\n    255, 255, 255,\n\n    \/\/ lower-middle\n    255, 255, 255, 255, 255, 255,\n\n    \/\/ bottom\n    255, 255, 255, 255\n  ];\n\n  for (let i = 0; i < ellipseData.length; i++) {\n    cycleProgress[i] = random(1);\n    cycleSpeed[i] = random(0.004, 0.012);\n    startAngles[i] = random(TWO_PI);\n  }\n}\n\nfunction draw() {\n background(&quot;#FAF6ED&quot;);\n\n  let sx = width \/ baseW;\n  let sy = height \/ baseH;\n  let sStroke = min(sx, sy);\n\n  for (let i = 0; i < ellipseData.length; i++) {\n    let amount;\n\n    if (cycleProgress[i] < 0.5) {\n      amount = map(cycleProgress[i], 0.0, 0.5, 0.0, 1.0);\n    } else {\n      amount = map(cycleProgress[i], 0.5, 1.0, 1.0, 0.0);\n    }\n\n    variedEllipseAnimated(\n      ellipseData[i][0] * sx,\n      ellipseData[i][1] * sy,\n      ellipseData[i][2] * sx,\n      ellipseData[i][3] * sy,\n      ellipseData[i][4] * sStroke,\n      ellipseData[i][5] * sStroke,\n      ellipseData[i][6],\n      ellipseColors[i],\n      ellipseAlpha[i],\n      amount,\n      startAngles[i]\n    );\n\n    cycleProgress[i] += cycleSpeed[i];\n\n    if (cycleProgress[i] &gt;= 1.0) {\n      cycleProgress[i] = 0.0;\n      startAngles[i] = random(TWO_PI);\n      cycleSpeed[i] = random(0.004, 0.012);\n    }\n  }\n}\n\n\/\/ Draw part of a rotated ellipse using many short line segments\n\/\/ with thin -&gt; thick -&gt; thin stroke variation\nfunction variedEllipseAnimated(cx, cy, w, h, swMin, swMax, rot, c, alphaVal, amount, startA) {\n  if (amount <= 0.001) return;\n\n  let step = 0.04;\n  let endA = startA + amount * TWO_PI;\n\n  stroke(red(c), green(c), blue(c), alphaVal);\n  noFill();\n\n  for (let a = startA; a < endA; a += step) {\n    let nextA = min(a + step, endA);\n\n    let lx1 = cos(a) * w \/ 2.0;\n    let ly1 = sin(a) * h \/ 2.0;\n\n    let lx2 = cos(nextA) * w \/ 2.0;\n    let ly2 = sin(nextA) * h \/ 2.0;\n\n    let x1 = cx + cos(rot) * lx1 - sin(rot) * ly1;\n    let y1 = cy + sin(rot) * lx1 + cos(rot) * ly1;\n\n    let x2 = cx + cos(rot) * lx2 - sin(rot) * ly2;\n    let y2 = cy + sin(rot) * lx2 + cos(rot) * ly2;\n\n    let wrappedA = ((a % TWO_PI) + TWO_PI) % TWO_PI;\n    let t = wrappedA \/ TWO_PI;\n\n    let sw;\n\n    if (t < 0.5) {\n      sw = lerp(swMin, swMax, t * 2.0);\n    } else {\n      sw = lerp(swMax, swMin, (t - 0.5) * 2.0);\n    }\n\n    strokeWeight(sw);\n    line(x1, y1, x2, y2);\n  }\n}\n            <\/script&gt;\n        <\/html&gt;\" sandbox=\"allow-scripts allow-same-origin\" scrolling=\"no\" style=\"overflow:hidden;\" width=\"\" height=\"\" class=\"\" title=\"p5.js canvas\"><\/iframe><\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Patterns, Fragments, Traces | Work in Progress \u00a0Patterns Are Made of Strokes, acrylic on paper, 2026. First part of a multimedia diptych. Work in progress toward\u00a0Patterns, Fragments and Traces. Parallel Lines, interactive JavaScript artwork, 2026. Second part of the multimedia diptych, image changes on mouse click Ink doodle translated to Processing code Ink on paper [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"single-pages-no-submenu","meta":{"_eb_attr":"","footnotes":""},"class_list":["post-1573","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.ellipsis.pink\/phl\/index.php?rest_route=\/wp\/v2\/pages\/1573","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ellipsis.pink\/phl\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.ellipsis.pink\/phl\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.ellipsis.pink\/phl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ellipsis.pink\/phl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1573"}],"version-history":[{"count":93,"href":"https:\/\/www.ellipsis.pink\/phl\/index.php?rest_route=\/wp\/v2\/pages\/1573\/revisions"}],"predecessor-version":[{"id":1768,"href":"https:\/\/www.ellipsis.pink\/phl\/index.php?rest_route=\/wp\/v2\/pages\/1573\/revisions\/1768"}],"wp:attachment":[{"href":"https:\/\/www.ellipsis.pink\/phl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1573"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}