Роман Кортес принес красные розы, написанные в сценариях JavaScript. Роза, сделанная с кодом, - лучший подарок на День Святого Валентина, который подарил вашей девушке потрясающими программистами! (Совет: эффект просмотра и скорость будут очень разными в разных браузерах)
Изображение генерируется кодом, и пользователь может обновить страницу и повторить процесс презентации просмотра розы.
Код реализации 3D Rose выглядит следующим образом:
Копия кода выглядит следующим образом: с (m = math) c = cos, s = sin, p = pow, r = random; c.width = c.height = f = 500; h = -250; функция p (a, b, c) {if (c> 60) return [s (a*7)*(13+5/(. 2+p (b*4,4)))-s (b)*50, b*f+50,625+c (a*7)*(13+ 5/(. 2+p (b*4,4)))+b*400, a*1-b/2, a]; a = a*2-1; b = b*2-1; if (a*a+b*b <1) {if (c> 37) {n = (j = c & 1) ? 6: 4; o = .5/(a+.01)+c (b*125)*3-a*300; w = b*h; return [o*c (n)+w*s (n)+j*610-390, o*s (n) -w*c (n)+550-j*350,1180+c (b+a)*99-j*300, .4-a*.1+p (1-b*b, -h*6)*. 15-a*b*.4+c (a+b)/5+p (c (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((15-a*b*. o*(a+1)+(b> 0? a*45-20; w = b*b*h; z = o*s (c)+w*c (c) +620; return [o*c (c) -w*s (c), 28+c (b*.5)*99-b*b*b*60-z/ z/ 2-h, z, (b*b*.3+p ((1- (a*a)), 7)*. 15+.3)*b, b*.7]} o = a*(2-b)*(80-c*2); w = 99-c (a)*120-c (b)*(-hc*4.9)+c (p (1-b, 7))*50+c*2; z = o*s (c)+w*c (c) +700; вернуть [o*c (c) -w*s (c), b*99-c (p (b, 7))*50-c/3-z/1,35+450, z, (1-b/1.2)*. 9+a*.1, P ((1-B), 20) /4+.05]}} setInterval ('for (i = 0; i <1e4; i ++) if (s = p (r (), r (), i%46/.74)) {z = s [2]; x = ~~ (s [0]*f/zh); y ~ ~~ (s [1]*f/zh); (! m [q = y*f+x] | m [q]> z) m [q] = z, a.fillstyle = "rgb ("+~ (s [3]*h)+","+~ (s [4]*h)+","+~ (s [3]*s [3]*-80)+")", A.FillRect (x, y, y, 1, 1) ', 1)', 1) ', 1).
Конечно, заинтересованные люди могут понять следующий процесс реализации и связанные с ним теории:
Эффект презентации этого трехмерного кода Rose использует метод Монте-Карло, а создатель высоко оценил метод Монте-Карло. Он сказал, что метод Монте -Карло является «невероятно мощным инструментом» с точки зрения функциональной оптимизации и отбора проб. Для метода Монте -Карло, пожалуйста, см. Метод Монте -Карло.
Конкретные операции:
Выбор образцов выбора эффекта
Я использовал несколько разных диаграмм формы, чтобы сформировать эту розу кода. В общей сложности использовались 31 формы: 24 лепестки, 4 чашелистика, 2 листья и 1 цветочный стебель, и каждая диаграмма формы была изображена в коде.
Во -первых, определите диапазон отбора проб:
Поверхность функции (a, b) {// Я использую A и B в качестве параметров в диапазоне от 0 до 1. Return {x: a*50, y: b*50}; // Эта поверхность будет квадратом 50x50 размера}Затем напишите код разграничения формы:
var canvas = document.body.appendchild (document.createElement ("canvas")), context = canvas.getcontext ("2d"), a, b, position; // Теперь я собираюсь выбрать поверхность при. b); context.fillRect (position.x, position.y, 1, 1);}}Теперь попробуйте более плотный интервал выборки:
Как вы можете видеть сейчас, поскольку интервалы выборки становятся более плотными и ближе, точки приближаются и ближе к самой высокой плотности, расстояние между соседними точками составляет меньше одного пикселя, а интервал не может быть замечен обнаженным глазом (см. 0,01). Чтобы не вызывать слишком много визуальной разницы, интервал выборки дополнительно уменьшается. В настоящее время область чертежа была заполнена (результаты сравнения составляют 0,01 и 0,001).
Далее я использую эту формулу, чтобы нарисовать круг: (x-x0)^2 + (y-y0)^2 <радиус^2, где (x0, y0) является центром круга:
Функция поверхности (a, b) {var x = a * 100, y = b * 100, radius = 50, x0 = 50, y0 = 50; if (x - x0) * (x - x0) + (y - y0) * (y - y0) <радиус * радиус) {// Внутри CirclerTurn {x: y: y};}} null null null null null null nullurn {//// nullurn nullurn {/// nullurn nullurn {//// nullurn nullurn {/// nullurn nullurn {/// nullurn nullurn {/// nullurn nullurn {/// nulrЧтобы предотвратить переполнение, необходимо добавить условие отбора проб:
if (position = surface (a, b)) {context.fillrect (position.x, position.y, 1, 1);}Существуют разные способы определения круга, некоторые из которых не требуют отказа от отбора проб. Мне не нужно использовать какой из них, чтобы определить круг, поэтому я использую другой метод для определения круга:
Функциональная поверхность (a, b) {// Обведите круг, используя полярный координатгар угол = a * math.pi * 2, radius = 50, x0 = 50, y0 = 50; return {x: math.cos (angel) * radius * b + x0, y: math.sin (angel) * radius * b + y0};};(Этот метод требует плотной выборки для заполнения по сравнению с предыдущим методом.)
Хорошо, теперь позвольте кругу деформации, чтобы сделать его более похожим на лепесток:
Функциональная поверхность (a, b) {var x = a * 100, y = b * 100, radius = 50, x0 = 50, y0 = 50; if (x - x0) * (x - x0) + (y - y0) * (y - y0) <радиус * радиус) {return {x: y: y * (1 + b) / 2 / / deformation};Это похоже на лепесток розы. Здесь вы также можете попытаться изменить некоторые значения функций, и появится много интересных форм.
Далее добавьте к нему цвет:
Функция поверхности (a, b) {var x = a * 100, y = b * 100, radius = 50, x0 = 50, y0 = 50; if (x - x0) * (x - x0) + (y - y0) * (y - y0) <радиус * радиус) {return {x: y: y * (1 + b) / 2, r: 100 + math. a Gradientg: 50, b: 50};} else {return null;}} for (a = 0; a <1; a + = .01) {for (b = 0; b <1; b + = 0,001) {if (point = surface (a, b) {context.fillstyle = "rgb (" + point.r + "," + point.b + point. ")"; context.fillRect (point.x, point.y, 1, 1);}}}Появляется цветный лепесток.
3D поверхностная и перспективная проекция
Определение трехмерной поверхности просто, например, определить трубчатый объект:
Поверхность функции (a, b) {var angel = a * math.pi * 2, radius = 100, длина = 400; return {x: math.cos (angle) * Radius, y: math.sin (угол) * Radius, z: b * Длина - длина / 2, // путем вычислительного длина / 2 I -центрированные в трубу (0, 0, 0) r: 0, g: g. 0};}Затем добавьте перспективу проекции. Сначала нам нужно определить камеру:
Как показано выше, поместите камеру в (0, 0, z) и холст в плоскости x/y. Точки выборки, проецируемые на холст:
var px, py, // Прогнозируется на Canvas x и y координатппертизующие = 350, Halfheight = canvas.height / 2, Halfwidth = canvas.width / 2, камераз = -700; для (a = 0; a <1; a += .001) {for (b = 0; b <1; b +=. {px = (point.x * перспектива) / (точка 1);}}}Эффект:
Z-буфер
Z-Buffer-очень распространенный метод в компьютерной графике. При затенении объектов выполняется работа «скрытая поверхность», так что часть скрытых объектов не будет отображаться.
На картинке выше-роза, обработанная с помощью Z-буферной технологии. (Вы можете видеть, что у него уже есть трехмерность)
Код заключается в следующем:
var zbuffer = [], zbufferindex; for (a = 0; a <1; a += 0,001) {for (b = 0; b <1; b += .01) {if (point = surface (a, b)) {px = math.floor (point.x * perspecment) / (point.z -cameraz) +половина); (point.z - cameraz) + halfheight); zbufferindex = py * canvas.width + px; if ((typeof zbuffer [zbufferindex] === "Undefined") || (point.z <zbuffer [zbufferindex])) {zubuffer [zbufferindex] = point.zecle.zem. point.r + "," + point.g + "," + point.b + ")"; контекст.Повернуть
Вы можете использовать любой метод вращения вектора. В создании розы кода я использую вращение Euler. Теперь поверните ранее написанный трубчатый объект, чтобы повернуть вокруг оси Y:
Функция поверхности (a, b) {var angen = a * math.pi * 2, radius = 100, длина = 400, x = math.cos (angel) * radius, y = math.sin (ange) * radius, z = b * длина - длина / 2, yaxisrotationangle = -.4, // in radians! x * x * cos. Math.sin (yaxisrotationAngle), Rotatedz = x * -math.sin (yaxisRotationAngle) + z * math.cos (yaxisrotationAngle); return {x: rotatedX, y: y, z: rotedz, r: 0, g: math.floor (b * 255), b: 0};};};};};Эффект:
Метод Монте -Карло
Что касается времени отбора проб, слишком большого и слишком маленького приведет к чрезвычайно плохим визуальному опыту, поэтому необходимо установить разумный интервал выборки, и здесь используется метод Монте -Карло.
wind.sem.setInterval (function () {for (i = 0; i <10000; i ++) {if (point = surface (math.random (), math.random ())) {px = math.floor (point.x * перспектива) / (point.z - cameraz) +полутория); HalfHeight); zBufferIndex = py * canvas.width + px; if ((typeof zbuffer [zbufferindex] === "undefined") || (точка. точкаУстановите A и B как случайные параметры и полное заполнение поверхности с достаточной выборкой. Я набираю 10000 баллов каждый раз и жду, когда экран завершит обновление.
Следует также отметить, что если случайное число неверно, эффект заполнения поверхности будет неверным. В некоторых браузерах выполнение математики. Рендом является линейным, что может привести к ошибкам в эффектах поверхностного заполнения. В настоящее время вы должны использовать что-то вроде Mersenne Twister (алгоритм случайных чисел) для выполнения высококачественной выборки PRNG, чтобы избежать ошибок.
Заканчивать
Для того, чтобы каждая часть розы завершилась и отображалась одновременно, необходимо добавить функцию, чтобы установить параметр для каждой части, чтобы вернуть значение для синхронизации. И использовать функцию сегмента, чтобы представить различные части розы. Например, в части лепестки я использую вращение и деформацию для их создания.
Хотя метод отбора проб поверхности является одним из самых известных и старейших методов создания трехмерной графики, этот метод добавления Монте-Карло и Z-буфера к поверхностному отбору проб не является распространенным явлением. Это может быть не очень креативным для производства сценария реального сценария, но его простая реализация кода и небольшой размер по-прежнему удовлетворительны.
Надеемся, что эта статья вдохновит энтузиастов компьютерной графики попробовать разные методы презентации и повеселиться от нее. (Роман Кортес)
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.