Tw1ddle / geometrize-haxe

:triangular_ruler: Geometrize is a Haxe port of primitive that geometrizes images into geometric primitives
https://www.geometrize.co.uk/
Other
348 stars 31 forks source link

bitmapOffset - run only inside a given bitmap region #19

Open cancerberoSgx opened 5 years ago

cancerberoSgx commented 5 years ago

This PR is not meant at all to be merged but as a starting point to discuss this feature. Also kind of personal notes and updates on these research.

What

Visually this will enable the users to select a region of the bitmap and apply the algorithm only there with custom options. In my experience I've noticed that some shape combinations will ignore some areas (often faces). Also could help with lines/curves that often are "too long" and ruin a landscape

Internally it isolates the region at the bitmap level so the whole algorithm runs in that context (reads, creates, mutates and render shapes only there). algorithm in new regions consume existing bitmap and collaborate with future sections/series.

Changes

Concerns:

Nice to have

non rectangular regions for shapes/faces - rectangles are too artificial and pronounced...

cancerberoSgx commented 5 years ago

some examples:


[
    {
    iterations: 255,
    shapeTypes: [ShapeTypes.ROTATED_ELLIPSE],
    alpha: 22,
    candidateShapesPerStep: 22,
    shapeMutationsPerStep: 44,
  }, 
  {
    iterations: 355,
    bitmapOffset: { x: 211, y: 11, width: 158, height: 188 },
    shapeTypes: [ShapeTypes.RECTANGLE],
    alpha: 141,
    shapeMutationsPerStep: 55,
    candidateShapesPerStep:70,
  }, 
  {
    iterations: 255,
    shapeTypes: [ShapeTypes.TRIANGLE],
    bitmapOffset: { x:  12, y: 11, width: 188, height: 138 },
    alpha: 152,
    shapeMutationsPerStep: 55,
    candidateShapesPerStep: 70,
  },
  {
    iterations: 755,
    shapeTypes: [ShapeTypes.LINE, ShapeTypes.QUADRATIC_BEZIER],
    bitmapOffset: { x:  32, y: 122, width: 218, height: 148 },
    shapeMutationsPerStep: 55,
    candidateShapesPerStep: 110,
    alpha: 166
  }
  ]

blubells 6


[
    {
    iterations: 55,
    shapeTypes: [ShapeTypes.ROTATED_ELLIPSE, ShapeTypes.TRIANGLE],
    alpha: 62,
    candidateShapesPerStep: 42,
    shapeMutationsPerStep: 44,
  }, 
  {
    iterations: 55,
    bitmapOffset: { x: 0, y: 0, width: 333, height: 220 },
    shapeTypes: [ShapeTypes.RECTANGLE],
  }, 
  {
    iterations: 55,
    shapeTypes: [ShapeTypes.TRIANGLE],
    bitmapOffset: { x:  444, y: 0, width: 311, height: 220 },
  },
  {
    iterations: 255,
    shapeTypes: [ShapeTypes.QUADRATIC_BEZIER],
    bitmapOffset: { x:  0, y: 300, width: 688, height: 200 },
    alpha: 196
  }
  ]

parrots 1

Tw1ddle commented 5 years ago

Thanks for this.

This is a legit approach for restricting where the algorithm runs, though I think a more flexible way to solve the problem this addresses is to make it simple to override the setup/mutation functions for the shapes themselves. I've started to implement this in my C++ application as an "area of influence" shape/mask that limits where shapes can spawn/mutate, some Chaiscript scripts use this (I need to update the C++ app and make some videos about how to use it!).

Approaching it this way makes it easier to provide custom versions of the shape setup/mutation code as add-ons/extensions. That's sort of the idea I have for this C++ code anyway - to eventually have many different versions of scripts for setting up/mutating shapes. I don't suggest using scripts for the Haxe library, but maybe a new set of functions (which together provide a "mode" where the code only runs within a region), for example:

https://github.com/Tw1ddle/geometrize-scripts/tree/783e5c670d0aca2394d9a81308c7b77fa4fe39db/scripts/pointer_area_of_interest_mutators

https://github.com/Tw1ddle/geometrize-scripts/tree/783e5c670d0aca2394d9a81308c7b77fa4fe39db/scripts/default_shape_mutators

What do you think? I could do it like this for the Haxe library when I find some time.

cancerberoSgx commented 5 years ago

Aja I'm checking it out. Whatever you think is the better approach would be awesome to implement in this library too since this feature attacks a problem I think is inerenth to the algorithm: each shape has a "taste" for different image "patterns" and if for example, a region of the image has a pattern with rect lines or rect angles then rectangles and lines simply won't be drawn on other parts of the image without those patterns.

About your solution, I'm not sure only with custom Shape's methods for render and mutate will be enough for this library and I think we might still need to add some "offset" logic on the bitmap and model. In the meanwile I will continue working on some tests for performance to see the cost of the current code.

Thanks and feel free to close this PR if you think so we can still keep discussing the feature here.