Обновить
Комментарии 54
Такой узор можно было бы использовать для печати, которую сложно подделать, например, на денежных суррогатах.

А что сложного в ее подделке по сравнению с любым другим микроузором?

Просто, как вариант использования. Я так полагаю микроузоры вообще сложно подделать. И еще их надо нарисовать, а у меня готовый микроузор. Для этой картинки скорее всего понадобится специальный принтер
Для этой картинки скорее всего понадобится специальный принтер

Почему не подойдет принтер, на котором печатаются существующие микроузоры?

я не говорил что не подойдет, главное что цветной.

Существующие микроузоры вполне себе бывают цветными. Они были цветными на советских рублях в моем детстве.

Надо добавить 3-е измерение и посмотреть что получится в 3Д
Надеюсь, сможет кто-нибудь сделать, я в 3D не силен.

Может попробую на C# или Kotlin забабахать демку.

Мысленный эксперимент без 3D принтера показывает, что получится эллиптический параболоид)
Подождите, если длина произведения (в hex) выходит больше 6, то Вы берёте первые три цифры и последние три. Выходит, что красная компонента и старшая часть зелёной кодируют одно, а младшая часть зелёной и синяя — другое. Зачем так? Тем более, что для радиуса менее 4096 произведение всё равно меньше, чем #ffffff.

И ещё дополняете нулями не слева, как это было бы более логично, а справа. Если дополнять нулями слева, то выходит иначе, и на радиусе 1024 почти без красного, потому что максимальное значение — #0FF801, (0xFF * 0xFF).

R=1024, дополнение нулями слева
image
ну эта часть не используется в программе, я ввел ее чтоб была на запасной случай.
про c вы — правы. наверное из-за этой маленькой ошибки и получается Тетраскоп.
ну, у Вас на картинке получается их несколько, вложенных друг в друга (с радиусами 4, 16, 64, 1024), которые до 1, 2, 3 и 4 цифр в hex-квадрате.
Можно ли картинку считать абсолютом? Мне кажется попиксельная прорисовка интерференции волн совершенна, для того чтобы быть человеческим творением, — т.е. я скорее открыл нежели создал эту форму.
Там нет никакой интерференции. С бесконечным разрешением это были бы просто концентрические круги (поскольку по факту цвет точки зависит от расстояния до центра, точнее, квадрата расстояния). Но именно наложение пиксельной сетки даёт красивые дополнительные окружности.
Как же все же интересно экспериментировать, получать результат и видеть его. Но подгонять результат под красивый и желаемый — уже не так интересно, как было заявлено. А так да, можно фракталами строить довольно красивые и сложные фигуры.

Удачи с дальнейшими экспериментами!

Напомнило искажение горизонта событий, но уже на больших масштабах иллюзия уплотнения этих концентрических окружностей исчезла
image

Почему-то, увы, Shadertoy меня не хочет регистрировать, но я добавил поддержку масштаба с опциональным уменьшением со временем и поддержку первых трёх/последних трёх hex-цифр для чисел больше 0xFFFFFF:

Код шейдера
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 coord = fragCoord - (iResolution.xy/vec2(2.0));
    
    float factor = 50.0;
    
    // WARNING: weird zooming out
    factor = float(int(iTime*25.0) + 1) / 5.0;
    
    coord *= factor;
    int x = int(coord.x);
    int y = int(coord.y);

    int a = x*x + y*y;

    // WARNING: flashing
    // a += int(iTime * 5000.0);
    // a -= int(iTime * 1000.0);

    // emulating JS: a.toString(16) + "0".repeat(6 - a.toString(16).length)
    if (a < 0x100000) a = a << 4;
    if (a < 0x100000) a = a << 4;
    if (a < 0x100000) a = a << 4;
    if (a < 0x100000) a = a << 4;
    if (a < 0x100000) a = a << 4;
    
    // emulating JS: c.substring(0, 3) + c.substring(c.length-3);
    while (a > 0xFFFFFF) {
        a = ((a ^ (a & 0xFFF)) >> 4) | (a & 0xFFF);
    }
    
    fragColor = vec4(
        float((a >> 16) & 255) / 255.0,
        float((a >>  8) & 255) / 255.0,
        float((a >>  0) & 255) / 255.0,
        1.0
    );
}

У вас как-то не так анимация работает, но сам поправить ошибку не могу
Анимация движения, еще есть строчка a += int(iTime * 1000.0);, можете с ней поиграться

Код шейдера
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 size = iResolution.xy;
    
    float speed_fly = 150.0;
    
    size = vec2(iTime * speed_fly);
    
    vec2 coord = fragCoord - (size.xy/vec2(2.0));
    
  //  float factor = 50.0;
    
    // WARNING: weird zooming out
  //  factor = float(int(iTime*25.0) + 1) / 5.0;

    int x = int(coord.x);
    int y = int(coord.y);
    
    int a = x*x + y*y;
    
    //a += int(iTime * 1000.0);

    // WARNING: flashing
    // a += int(iTime * 5000.0);
    // a -= int(iTime * 1000.0);

    // emulating JS: a.toString(16) + "0".repeat(6 - a.toString(16).length)
    if (a < 0x100000) a = a << 4;
    if (a < 0x100000) a = a << 4;
    if (a < 0x100000) a = a << 4;
    if (a < 0x100000) a = a << 4;
    if (a < 0x100000) a = a << 4;
    
    // emulating JS: c.substring(0, 3) + c.substring(c.length-3);
    while (a > 0xFFFFFF) {
        a = ((a ^ (a & 0xFFF)) >> 4) | (a & 0xFFF);
    }
    
    fragColor = vec4(
        float((a >> 16) & 255) / 255.0,
        float((a >>  8) & 255) / 255.0,
        float((a >>  0) & 255) / 255.0,
        1.0
    );
}

Получил когда-то похожую конфигурацию при расчёте объёмов ячеек трёхмерной прямоугольной сетки, отсекаемых поверхностью полусферы:

image

Похоже, такая структура — результат взаимодействия окружности (сферы) с ортогональной решёткой. Главное тут — найти эффектный способ визуализации, чтобы проявилась структура
Вот что еще видно с моей картинки — пересечение четырех высот.
И походу с медианами и биссектриссами та же фигня, только менее отчетливо.
image
Здесь же на хабре, кажется, где-то была статья про алгоритмы ресемплинга изображений, где в качестве тестового изображения использовали картинку с zone plate. Разные алгоритмы ресемплинга приводили к таким же «фрактальным» артефактам из-за алиасинга. Что-то вроде такого:

image
image
у меня такие еще получились
Если начало координат в центре окружности, то x^2+y^2 — это расстояние от центра. Для всех точек на одной окружности вы должны были получить одинаковый цвет. Это вы в коде что-то нахимичили.
Мне больше всего интересно, можно ли с этой картинки считать ее звук? Выглядит так как будто можно, но способ я не знаю.
Угу, а ещё неплохо бы ауру считать. Она наверняка какая-то необычная получится.
Я сделал штуку для этого дела, чтоб послушать картинку в разных местах, замена RGB-видению:
красный: частота 768-512; синий: частота: 512-256; зеленый: частота 256-0
$('#C').on('mousemove touchmove', function(e){
		if (Tone.context.state !== 'running') {
			Tone.context.resume();
			synth = new Tone.PolySynth().toDestination();
			window.synth = synth;
			if ((typeof si) === 'undefined') {				
				mr = 0.1;
				si = setInterval(function(){					
					X = Math.abs(window.e.pageX-1024);
					Y = Math.abs(window.e.pageY-1024);
					if (X*X+Y*Y>R*R) return;
					memory = new Array(); n=0;
					memory.push( Math.floor( Math.abs(   Number.parseInt( rgb((X*X+Y*Y).toString()).substring(0,2), 16 )+512  ) ) );
					memory.push( Math.floor( Math.abs(   Number.parseInt( rgb((X*X+Y*Y).toString()).substring(2,4), 16 )+256  ) ) );
					memory.push( Math.floor( Math.abs(  Number.parseInt( rgb((X*X+Y*Y).toString()).substring(4,6), 16 )+0  ) ) );
					synth.triggerAttackRelease([memory[n], memory[n+1], memory[n+2]], Tone.now(), 0, 0.125);
				}, 128);
			}
		}
	});
	$(document).mousemove(function(e){
		window.e = e;
	});
Не воспроизводится звук, Хром. :-(
модели вселенной, описывающей микро и макромир
А можно подробнее? Это как? И это тоже не понятное утверждение:
Эта модель — абсолют, под этим я понимаю, что ее физикоматематическая модель существует сама по себе, еще задолго до своего открытия и независимо от человека, как самодостаточная форма бытия
  1. Лично я вижу в этой форме целую галактику с черной дырой по центру и массивные объекты излучающие гравитационные волны, на нижних уровнях описывается микромир, на высших — макро, отчетливо видно 4 оси симметрии x=0,y=0, x=y и x=-y. У каждой точки есть три такие же относительно осей симметрии. Это как суперпозиция во множествах X, Y, Z, T, где последнее время. И отчетливо видны углы под 30, 60 и 90 градусов, как для стрелок на часах.
  2. Посмотри на нее еще раз, модель является очень сложной для элементарной формулы и содержит даже такие визуализации как пересечение высот в конкретной точке, или сетчатость — это не потому, что я сделал ее такой, а потому что она такой была.
Синусоида это прекрасно. Мой объект тоже повторяет себя в бесконечности.
… и мы не создали её, она уже была до нас.
Наверное имеется ввиду самоподобие обозримой вселенной, микро и макро мира.

См. книгу «Фрактальная геометрия природы» Б. Мандельброта,
обзор его доклада на конференции TED:
Бенуа Мандельброт на TED: «Фракталы и искусство изломов»
а также статью
Созерцание великого фрактального подобия


Сама мысль то не нова. Однако, чтобы убедиться в том, что эта «модель» скажем так «вездесуща», нужны хоть какие-то исследования. Ведь, как правило, на основе модели можно делать «предсказания». Т.е. вот если на модели так, то в реальном мире будет так. И проверить, а действительно ли это так.
Без такой проверки это всего лишь «математическая лирика»: мечта о том, что все разнообразие в мире основано на одной единственной элементарной формуле.
Писали визуализацию, по пути сделали ошибочку, получилась непонятная фигня — открыли структуру вселенной.

Вы бы ещё сказали что формула y^4-x^4=xy доказывает превосходство белой расы.
Ваш код не запустился из консоли в FireFox скорее всего из за использования внешних библиотек,
я минимально изменил его:
  1. $(document).ready(function(){});
    //заменил на
    (function(){})();
    //что за скобки? https://developer.mozilla.org/ru/docs/Словарь/IIFE
    
  2. $('body').append('<canvas id="C" width="'+(R*2)+'" height="'+(R*2)+'">');
    //заменил на
    document.body.innerHTML=('<canvas id="C" width="'+(R*2)+'" height="'+(R*2)+'"></canvas>');
    //appendChild() требовал больше изменений, document.write() запускался только поверх открытой страницы но не "новой вкладки"

Код с дополнениями
(function(){
	var R=1024; var D=2*R;
	var rgb = function(c){
		if(c.length<=6)	return c+("0".repeat(6-c.length));
		else return c.substring(0, 3)+c.substring(c.length-3);
	}
	document.body.innerHTML=('<canvas id="C" width="'+(R*2)+'" height="'+(R*2)+'"></canvas>');
	var canvas = document.getElementById('C');
	var ctx = canvas.getContext('2d');
	ctx.fillStyle="#ffffff00";
	ctx.fillRect(0, 0, 256, 256);
	for(var x = 0;x<D;x++) {
		for(var y = 0;y<D;y++) {					
			var X1 = R-x;
			var Y1 = R-y;
			var X2 = R+x;
			var Y2 = R+y;
			if (( x*x+y*y )   <=   R*R    ) {
				ctx.fillStyle="#"+(   rgb( (x*x+y*y).toString(16))   );
				ctx.fillRect(X1, Y1, 1, 1);
				ctx.fillRect(X1, Y2, 1, 1);
				ctx.fillRect(X2, Y1, 1, 1);
				ctx.fillRect(X2, Y2, 1, 1);
	}	}	}
})();


Живой пример на jsfiddle.net/6wk2oe40
хрусталик вообще я помешался на этой форме — в ней есть всё и ничто. можно рассмотреть что угодно. так понятно и так непонятно. если для вас это не так загадычно, попробуйте ответить на вопрос: откуда там вибрирующие пузырьки?
Я немного поторопился со статьей и в первоначальном варианте было немного не точное описание алгоритма, и внес правки в код, из-за которого исходное изображение немного сдвинуто вправо-вниз на один пиксель.
Выкладываю свой код тетраскопа для Go
package main

import (
    "image"
    "image/color"
    "image/draw"
    "image/png"
    "os"
     "strings"
    "strconv"
    //"fmt"
)

func ConvertToColor(s string) (r string) {
    r = s
    if len(s)<6 {
        r = s+strings.Repeat("0", 6-len(s))
    } else if len(s)>6 {
        r = string(s[0:6])
    }
    return r
}

func ParseHexColorFast(s string) (c color.RGBA) {
    c.A = 0xff

    if s[0] != '#' {
        return c
    }

    hexToByte := func(b byte) byte {
        switch {
        case b >= '0' && b <= '9':
            return b - '0'
        case b >= 'a' && b <= 'f':
            return b - 'a' + 10
        case b >= 'A' && b <= 'F':
            return b - 'A' + 10
        }
        return 0
    }
    c.R = hexToByte(s[1])<<4 + hexToByte(s[2])
    c.G = hexToByte(s[3])<<4 + hexToByte(s[4])
    c.B = hexToByte(s[5])<<4 + hexToByte(s[6])
    return
}

func main() {
    
    R:=1024
    D:=R*2    
    new_png_file := "tetrascope.png"
    
    myimage := image.NewRGBA(image.Rect(0, 0, D, D))
    bgcolor := color.RGBA{0, 0, 0, 0}
    draw.Draw(myimage, myimage.Bounds(), &image.Uniform{bgcolor}, image.ZP, draw.Src)

    for x:=0; x<R; x++ {
        for y:=0; y<R; y++ {
            x1 := R-x-1
            x2 := R+x-1
            y1 := R-y-1
            y2 := R+y-1
            if x*x+y*y <= R*R {
                var c int64;                
                c = int64(x*x+y*y);
                col := "#"+ConvertToColor(strconv.FormatInt(c, 16))
                //fmt.Println(col, x, y)
                color := ParseHexColorFast(col)
                pixel1 := image.Rect(x1, y1, x1+1, y1+1)
                pixel2 := image.Rect(x1, y2, x1+1, y2+1)
                pixel3 := image.Rect(x2, y1, x2+1, y1+1)
                pixel4 := image.Rect(x2, y2, x2+1, y2+1)
                draw.Draw(myimage, pixel1, &image.Uniform{color}, image.ZP, draw.Src)
                draw.Draw(myimage, pixel2, &image.Uniform{color}, image.ZP, draw.Src)
                draw.Draw(myimage, pixel3, &image.Uniform{color}, image.ZP, draw.Src)
                draw.Draw(myimage, pixel4, &image.Uniform{color}, image.ZP, draw.Src)
            }
        }   
    }

    myfile, err := os.Create(new_png_file)     // ... now lets save imag
    if err != nil {
        panic(err)
    }
    png.Encode(myfile, myimage)   // output file /tmp/two_rectangles.png
}

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