Аутентичный фрактальный город или программируем вид за окном

от автора

Экспериментируя с фрактальными функциями, я визуализировал 2д изображение, которое внешне очень напоминало мне обычный спальный район или строительные леса. Для glsl это будет примерно такая функция:

rgba=vec4((int(x)&int(y))>>(int(mod(floor(x),5.)*4.0))+(4-int(mod(floor(y),5.)))&1);

Если взять нужный масштаб, то получится то о чем я говорю. В примере я устанавливаю масштаб oxy*=49.91/2.50; Выполнив эти действия мы получим строчки с детализацией 2д-города:

Попробую объяснить, что именно мы сделали этой функцией: мы взяли треугольник серпинского (int(x)&int(y)) и расщепили его на квадратные матрицы 5×5 (не знаю как по другому выразить то что мы сделали, но слово расщепление наиболее точно выражает проделанную операцию).

Затем мы выбираем нужные строчки и подстраиваем их под текущее разрешение экрана:

// fractal city     float line=120.0;     vec2 oxy=vec2(xy.y,xy.x);     oxy=iResolution.y*2.5-oxy;     if(iResolution.y>1000.0) {         // fullscreen fix         xy/=2.0;oxy=vec2(xy.y,xy.x);         oxy=iResolution.y*2.5-oxy;         oxy/=2.0;oxy.x-=135.0;         oxy.x+=1000.0;line*=2.0;     }if(xy.y<line){         // all resolutions         oxy.y+=400.0;oxy-=130.0/2.0;         if(iResolution.y==281.0)oxy-=80.0;         if(iResolution.y==236.0)oxy+=30.0;         if(iResolution.y==288.0)oxy+=40.0;         oxy*=49.91/2.50;//zoom         // fractal city lines          rgba+=vec4((int(oxy.x)&int(oxy.y))         >>(int(mod(floor(oxy.x),5.)*4.0))         +(4-int(mod(floor(oxy.y),5.)))&1);     }

Тут надо сказать, что у меня не было возможности протестить все разрешения, и я взял просто стандартные, используемые на сайте, поэтому на фуллскринах, могут быть смещения, поэтому буду благодарен, если вы мне укажете на несостыковки у вас.

Осталось только добавить праздничные салюты и вид будет точно как из окна:

bool firework(vec2 xy, float time){     float t=time;     float r=length(xy);     float rad=atan(xy.y,xy.x);     float deg=degrees(rad);     xy=rotate(xy,deg);     r=length(xy);     rad=atan(xy.y,xy.x);     deg=degrees(rad);     float X=xy.x+sin(deg+t)*(deg+mod(t,100.0));     float Y=xy.y+cos(deg+t)*(deg+mod(t,100.0));     return (sqrt(X*X+Y*Y)<30.0&&r<150.0*(sin(t))); }

Весь код целиком


ссылка на оригинал статьи https://habr.com/ru/post/599641/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *