Skip to content

ParaLogia/dessin

Repository files navigation

Dessin

Dessin is an interactive pattern generator using recursive geometry.

Play around with the sliders and watch the shapes transform in real time!

example2

Live Demo

https://paralogia.github.io/dessin/

Controls:

  • Left click: Play/Pause
  • Right click: Context Menu (you can save/copy the image)
  • Slider parameters (left-to-right/top-down):
    • Scaling Factor
    • Rotation Angle
    • Polygon Sides
    • Displacement
    • Animation Speed

Technologies/Technical Challenges

Dessin is implemented using JavaScript and rendered on an HTML5 canvas. Future iterations may incorporate SVGs for scalable images.

Fixed Point Computation

In order to produce self-similar images, the program starts with a single polygon. Next. it repeatedly draws and then applies an affine transformation to the figure, until a certain depth is reached. Some transformations will appear to converge at some point other than the center, as in the figure below:

fixed point example

This convergence point, also known as a fixed point, is a natural center of rotation when animating the figure, so I wrote some utility functions to compute this fixed point using a matrix representation of the affine transformation. For the mathematically-minded, this boils down to finding the eigenvector of the matrix that corresponds to the eigenvalue of 1.

// Finds the fixed point of an affine transformation represented by a 3x3 matrix
// Note: Input matrix should be formatted like a DOMMatrix from the Canvas API
function fixedPoint(matrix) {
  const { a, b, c, d, e: dx, f: dy } = matrix;

  const subMatrix = [
    [ 1-a,  0-c ],
    [ 0-b,  1-d ]
  ]
  const invSubMatrix = invertMatrix(subMatrix);
  const transVec = [dx, dy];
  return matVecMultiply(invSubMatrix, transVec);
}

// Inverts a matrix representing an affine or linear transformation
function invertMatrix(matrix) {
  const [[a, c, dx], [b, d, dy], ..._] = matrix;
  
  const det = a*d - b*c; 

  if (dx || dy) {
    // Affine
    return [
      [  d/det,   -c/det,   (c*dy-d*dx)/det ],
      [ -b/det,    a/det,   (b*dx-a*dy)/det ],
      [ 0,         0,       1               ]
    ]
  } else {
    // Linear
    return [
      [  d/det,   -c/det ],
      [ -b/det,    a/det ]  
    ]
  }
}

function matVecMultiply(mat, vec) {
  const res = vec.map(() => 0);
  for (let i = 0; i < mat.length; i++) {
    for (let j = 0; j < vec.length; j++) {
      res[i] += vec[j]*mat[i][j];
    }
  }
  return res;
}

Example Patterns

Discover your own fascinating patterns!

example4 example1 example3 example5

Credits

About

Interactive pattern generator using recursive geometry

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published