trebeljahr / fractal-garden

An Exhibition Of Mathematical Beauty.
https://fractal.garden
MIT License
140 stars 12 forks source link

Barnsley-Fern broken on mobile #17

Closed trebeljahr closed 2 years ago

trebeljahr commented 2 years ago

image

When on Mobile the Barnsley Fern does not show correctly.

npx commented 2 years ago

Hey, I implemented a solution for this, however, this problem is not trivial, as we cannot (easily) determine the actual size of the final fractal, thus scaling it to the canvas is tricky. Especially, if we look at fractals growing horizontally (like the tree). This btw applies to all your growing fractals, and ideally a general solution for all of those is applied.

What do you consider feasible for an implementation.

trebeljahr commented 2 years ago

I think the PR you opened is a perfect start! I'm fine with "just" having hacked together magic number-centering solutions for each of the fractals. It's not "beautiful" or "clean" but much better than not having the fractals centered at all.

Testing your PR out right now, but from a first glance it looks good :+1:

A generic solution is like you said not trivial, especially considering that the different fractals are implemented in different ways/types. Some are custom recursive code (like Barnsley Fern / Fractal Tree) while others are L-Systems (Lévy Curve, Hilbert Curve, Sierpinski Triangle...), while yet others are WebGL based (Mandelbrot Set).

But if you have an idea that could work generically (even if only for one of these "subsets"), please feel free to open an issue and write some code that implements a generic solution :) Glad to accept PRs.

Just to get the thinking going: One idea I had, that might work for a generic solution, is to produce the points/vertices of the fractal first, and then use those points to determine the correct scale to display them on the canvas and then scale the canvas up/down accordingly and center the fractals so they take up a nice portion of the screen. The main problem with this approach would be the performance because you would have 2 loops where now there is only one -> 1. generate the vertices 2. draw the points. However, this could be accelerated if the second "loop" were done with a shader... But like you said, not trivial, though definitely something that would push the project forward a lot :+1:

What do you think?

And either way, thanks a lot for your contribution and take care :wave:

trebeljahr commented 2 years ago

one thing I noticed while testing, some of the ferns are a little small now on mobile:

image image

It would be cool if they could stretch further to the left and right :)

When I tried to look for a generic approach to calculate the width/height of those Ferns, I didn't come up with anything good either.

There is this part of Wikipedia with the Algorithms, but they also just draw points and map them with some magic numbers to X/Y coordinates...

But like I said, fiddling with magic numbers and adding them to the transformation rules would be 100% fine with me :)

trebeljahr commented 2 years ago

an idea of how to find those points is by keeping track of the points making up the fern in an array, then reducing it to find the min/max for the x/y values, and then using those in the map/remap function, as you see in Wikipedia. This way you can find out the range of the points you get from the transformations for the specific fern.

For the Barnsley Fern those would be: −2.1820 < x < 2.6558 0 ≤ y < 9.9983

and with the approach above you could find them for the other variants and then map accordingly :)

and the ratio between highX - lowX and highY - lowY gives you an aspect ratio you could use for figuring out whether something is "width" or "height" scaling as well :blush: so you don't have to hardcode it :+1:

trebeljahr commented 2 years ago

this would then be a semi-general solution - it would still involve finding and then hardcoding the upper/lower x/y bounds for each of the ferns, but then the centering would be done for all, in the same way, using that data :+1:

npx commented 2 years ago

Thanks for looking into it! Yeah I had a similar train of thought when looking at the implementation haha

However, even when determining the values and adding some fractal specific settings, fractals growing extremely in width (like the tree) will become rather small on a phone screen in portrait mode.

I'll see what I can do!

trebeljahr commented 2 years ago

thank you so much :) let me know how it goes, or if you need anything from me :+1:

trebeljahr commented 2 years ago

also that the tree grows small in portrait mode is ok I think. One way to resolve this would be to rotate it sideways on portrait mode when the screen is small or just live with it growing out of the bounds of the screen. It's a tradeoff then -> small fractal or "bad" looking one because it grows out of the bounds of the screen... honestly, either way would be fine with me, it depends a bit on how small the tree is in the end and then deciding which looks better :man_shrugging:

npx commented 2 years ago

Hey @trebeljahr,

I worked over the implementation and the result is "relatively" decent. You will find that now all trees will fit into the viewport correctly.

However, upon closer inspection of your implementation (which I assume was heavily inspired by the JS example in the wiki you linked hehe) I found that you implemented a kind of custom scaling - rather a distortion - which was applied to all ferns.

I have removed this for this iteration of the implementation, as it is not really part of the algorithm. Futhermore, I removed the scalingFactor for now. I experimented with scaling the width and height with custom values, but it didnt really look to neat tbh.

Please check out the current behaviour and implementation and if this is fine, I would urge you to merge it as is for now, and open a new ticket to add a custom distortion function per fern!

Let me know what you think!

EDIT: I also added a padding which is currently set to 100px on either side of the axis we limit he scaling by. I just noticed it might be a bit much so feel free to feel around with that!

2nd EDIT: Of course instead of a pixel padding we can easily change this to a percentage-wise padding, making the fern take up 95% or something of the limited axis.

trebeljahr commented 2 years ago

cool, just saw your comment now, checking it out :) at a first glance the work looks amazing thank you so much for taking the time :+1:

trebeljahr commented 2 years ago

I think the padding is a bit much as it is right now on small screens – 320 - 200, does not leave much place for the ferns ^^ Let's change that to a percentage-based value of say 80% or 85% or 90% of the available width/height and then it should be perfect I think and we can merge this :)

the thing you found with the distortion is super interesting, thanks for figuring it out!

The Barnsley Fern looks much thinner now ^^ To me it's interesting since the version on the Wikipedia page for the p5.js is different from the native canvas one and my guess would be that they give different results as well (the custom distorting one looks broader probably).

Even if you punch that into google images you get different versions :man_shrugging: some really broad, others very narrow...

image

npx commented 2 years ago

I personally think the fern looks a bit more elegant without he distortion but thats just my personal opinion haha I will quickly adjust to a percentage based padding and send you the update!

npx commented 2 years ago

When switching to percentage padding, I've noticed my remapping and positioning being off. After a bit more napkin math, i should now be remapped and positioned properly!

Check it out >:3

trebeljahr commented 2 years ago

just checked it out! now it's perfect <3 thank you so much :) I'll merge this then :+1: