If you're seeing this message, it means we're having trouble loading external resources on our website.

Ако си зад уеб филтър, моля, увери се, че домейните *. kastatic.org и *. kasandbox.org са разрешени.

Основно съдържание

Шум на Перлин

Един добър генератор на случайни числа произвежда номера, които нямат връзка помежду си и видимо не следват някакъв модел. Както започваме да забелязваме, малка доза случайност върши добра работа, когато програмираме естествено, реалистично поведение. Въпреки това, ако се ръководим единствено от случайността, няма непременно да получим естествен резултат.
Съществува алгоритъм, известен като "шум на Пърлин", който дава повече естествени резултати. Кен Пърлин развива функцията шум, докато работи върху оригиналния филм Tron в началото на 80-те години; той го използва, за да създаде процедурни текстури за компютърно генерирани ефекти. През 1997 г. Пърлин печели Оскар за технически постижения с този свой труд. Шумът на Пърлин може да се използва за генериране на различни ефекти с физически качества, като облаци, пейзажи и шарени текстури, като мрамор.
Шумът на Пърлин има по-органичен облик, защото произвежда естествено подредена ("плавна") последователност от псевдо-случайни числа. Графиката по-долу показва Пърлин шум във времето, с абсциса представляваща време; обърни внимание на гладкостта на кривата.
Природата на кода изображение
Фигура I.5: Шум
За контраст, в следващата графика по-долу можем да видим чисто случайни числа във времето.
Природата на кода изображение
Фигура I.6: Случайност
ProcessingJS има вградена имплементация на алгоритъм за шум на Пърлин: функцията noise(). noise() приема един, два или три аргумента, тъй като шум се изчислява в едно, две или три измерения. Нека започнем от едномерен шум.

Детайлност на шума

Документацията на функцията noise() ни казва, че шумът се изчислява по няколко "октави". Ако извикаме функцията noiseDetail(), ще променим както броя на октавите, така и тяхното значение по отношение една на друга. Това на свой ред променя поведението на функцията за шум.
Помисли как бихме нарисували кръг в нашия ProcessingJS прозорец на произволно място x.
var x = random(0, width);
ellipse(x, 180, 16, 16);
Сега, вместо на произволно място x, ние искаме Пърлин шум на местоположение x, което е "по-плавно". Може би си мислиш, че всичко, което трябва да се направи, е да замениш random() с noise(), т.е.
var x = noise(0, width);
ellipse(x, 180, 16, 16);
Докато концептуално това е точно нещото, което искаме да направим – да изчислим стойност x, която варира между 0 и ширината според шума на Пърлин – това не е правилно изпълнение. Аргументите на функцията random() задават диапазон от стойности между минимум и максимум, но noise() не работи по същия начин. Вместо това, noise() очаква от нас да подадем един аргумент, който означава "момент във времето" и винаги връща стойност между 0 и 1. Можем да мислим за едномерния шум на Пърлин като за линейна последователност от стойности във времето. Например ето няколко примерни входа, които връщат стойности:
ВремеСтойност на шума
00,469
0,010,480
0,020,492
0,030,505
0,040,517
За да получим достъп до една от тези стойности за шума в ProcessingJS, ние трябва да подадем определен момент във времето на noise() функцията. Например:
var n = noise(0{,}03);
Според горната таблица, noise() ще върне стойност 0,505 при време 0,03. Можем да напишем програма, която съхранява променлива за време и продължително прави заявка за стойността на шума в draw().
Горният код резултира в отпечатването на една и същата стойност отново и отново. Това се случва, защото извикваме резултата от функцията noise() за същата точка във времето отново и отново.
Ако обаче увеличим променливата за времето t, ще получим различен резултат.
Степента, с която увеличаваме t също се отразява на гладкостта на шума. Ако правим големи скокове във времето, тогава препускаме напред и стойностите ще станат по-случайни.
Шум във времето
Фигура 1,7
Опитай да изпълниш горния код няколко пъти, като увеличаваш t с 0,01, 0,02, 0,05, 0,1, 0,0001 и ще видиш различни резултати.

Пренасяне на шума

Сега сме готови да отговорим на въпроса какво да правим със стойността на шума. След като имаме стойност с диапазон между 0 и 1, от нас зависи да пренесем този диапазон към каквото поискаме.
Можем просто да умножим по максималното число в диапазона, но също така това е една добра възможност да въведем фунцкията на ProcessingJS map(), която ще ни помогне в повече ситуации по-късно. Функцията map() приема пет аргумента. Първо подаваме стойността, която искаме да пренесем, в този случай – n. След това трябва да зададем текущия диапазон (минимум и максимум) на стойността, последван от желания диапазон.
Природата на кода изображение
Фигура I.8
В този случай знаем, че шумът е с диапазон между 0 и 1, но бихме искали да нарисуваме правоъгълник с широчина между 0 и текущата широчина.
Можем да приложим съвсем същата логика за нашата случайна походка и да присвоим и двете стойности за x и y според шума на Пърлин.
Забележи как горният пример изисква допълнителен чифт променливи: tx и ty. Това е така, защото трябва да следим две променливи за време , една за местоположението по x на обекта Walker и една за местоположението по y.
Но има нещо леко странно в тези променливи. Защо tx започва от 0, а ty – от 10 000? Въпреки че тези числа са избрани случайно, ние много специфично сме инициализирали нашите две променливи за време с различни стойности. Това е така защото функцията на шума е детермининистична: тя ти дава същия резултат за определено време t всеки път. Ако поискаме стойността на шума за едно и също време t и за x, и за y, тогава x и y винаги ще бъдат равни, което означава, че обектът Walker ще се движи само по диагонал. Вместо това просто използваме две различни части на множеството от шумове, като започнем от 0 за x и 10 000 за y, така че да могат x и yда изглеждат, че действат независимо една от друга.
Природата на кода изображение
Фигура 1.7
Всъщност, тук нямаме някакво действително понятие за време. Това е полезна метафора, която ще ни помогне да разберем как работи функцията на шума, но това, което всъщност имаме, е пространство, а не време. Графиката горе показва линейна последователност от стойности за шума в едноизмерно пространство и можем да изискаме стойност на конкретно място x, когато пожелаем. В примери често ще виждаш променлива с име xoff, която ще сочи към отместването x по протежение на графиката на шума, а не t за време (както е отбелязано в диаграмата).
В следващото предизвикателство ще се опиташ да използваш шум с Walker по малко по-различен начин. Забавлявай се!

Курсът "Компютърни симулации на физични явления" е производeн на "Природата на кода" от Даниел Шифман, използвана от Creative Commons Attribution-NonCommercial 3,0 Unported License.

Искаш ли да се присъединиш към разговора?

Все още няма публикации.
Разбираш ли английски? Натисни тук, за да видиш още дискусии в английския сайт на Кан Академия.