Возведение в степень: правила, примеры

Сегодня, когда всё популярнее становится трассировка лучей (ray tracing) выполняемая из «глаза» камеры, этот урок нужно усвоить заново: код становится лучше, а жизнь — проще, если центр пикселя находится в координате (0,5; 0.5). Если вы уверены, что делаете всё правильно, то продолжайте в том же духе, для вас в статье нет ничего нового. Прочитайте лучше вот это.
Смысл размещения центра пикселя в (0,5; 0,5) впервые объяснила (по крайней мере, мне) милая короткая статья Пола Хекберта «Что такое координаты пикселя?» из книги 1990 года Graphics Gems, стр. 246-248.
Сегодня эту статью найти трудновато, поэтому вкратце изложу её суть. Допустим, у нас есть экран с шириной и высотой 1000. Давайте рассмотрим только ось X. Может возникнуть искушение назначить 0,0 центром самого левого пикселя в строке, 1,0 — центром следующего, и так далее. Можно даже использовать округление, при котором координаты с плавающей запятой 73,6 и 74,4 переносятся в центр 74,0.
Однако над этим стоит поразмыслить. При таком сопоставлении левый край будет находиться в координате -0,5, а правый — в 999,5. С такой системой неудобно работать. Хуже того, если к значениям координат пикселей применяются различные операторы наподобие abs() или mod(), то такое сопоставление может привести к незначительным погрешностям на краях.
Проще работать с интервалом от 0,0 до 1000,0, в котором центр каждого пикселя имеет дробную часть 0,5. Например, тогда целочисленный пиксель 43 будет иметь красивый интервал значений значений входящих в него субпикселей от 43,0 до 43,99999. Вот чертёж из статьи Пола:


В OpenGL центр пикселя всегда имел дробную часть (0,5; 0,5). Поначалу DirectX этого не придерживался, но в версии DirectX 10 взялся за ум.
Операции для преобразования из целочисленных координат в координаты пикселя с плавающей запятой заключаются в прибавлении 0,5; для преобразования float в integer достаточно использовать floor().
Но это уже давняя история. Ведь сегодня все делают так, правда? Я вернулся к этой теме, потому что начал встречать в примерах (псевдо)кода генерации направления перспективной камеры для трассировки лучей такое:
float3 ray_origin = camera->eye; float2 d = 2.0 * ( float2(idx.x, idx.y) / float2(width, height) ) — 1.0; float3 ray_direction = d.x*camera->U + d.y*camera->V + camera->W;
Вектор idx — это целочисленное местоположение пикселя, width и height — разрешение экрана. Вектор d вычисляется и используется для генерации вектора в мировом пространстве при помощи перемножения двух векторов, U и V. Затем прибавляется вектор W — направление камеры в мировом пространстве. U и V обозначают положительные направления осей X и Y плоскости отображения на расстоянии W от глаза. В представленном выше коде всё это выглядит красиво и симметрично; так оно по большей части и есть.

Вектор d должен обозначать пару значений от -1,0 до 1,0 в нормализованных координатах устройства (Normalized Device Coordinates, NDC) для точек на экране. Однако, здесь код даёт сбой. Продолжим наш пример: целочисленное местоположение пикселя (0; 0) переносится в (-1,0; -1,0). Кажется, это хорошо, правда? Но максимальное целочисленное местоположение пикселя равно (999; 999), что преобразуется в (0,998; 0,998). Суммарная разница 0,002 вызвана тем, что это неверное наложение сдвигает всю картинку на полпикселя. Эти центры пикселей должны находиться в 0,001 от каждого из краёв.
Вторая строка кода должна выглядеть так:
float2 d = 2.0 * ( ( float2(idx.x, idx.y) + float2(0.5,0.5) ) / float2(width, height) ) — 1.0;
Тогда мы получим правильный интервал NDC для центров пикселей, от -0,999 до 0,999. Если мы вместо этого преобразуем угловые значения с плавающей запятой (0,0; 0,0) и (1000,0; 1000,0) этим способом (мы не прибавляем 0,5, потому что уже и так работаем с плавающей запятой), то получим полный интервал NDC, от -1,0 до 1,0, от края до края; это доказывает правильность кода.
Если 0,5 вас раздражает и вам не хватает симметрии, то для генерации случайных значений внутри пикселя, т.е. когда вы выполняете сглаживание испусканием случайных лучей через каждый пиксель, можно использовать такую изящную формулировку:
float2 d = 2.0 * ( ( float2(idx.x, idx.y) + float2( rand(seed), rand(seed) ) ) / float2(width, height) ) — 1.0;
Мы просто прибавляем к каждому целочисленному значению местоположения пикселя случайное число из интервала [0.0,1.0). Средним этого случайного значения будет 0,5, то есть центр пикселя.
Так что скажу кратко: будьте внимательны. Реализуйте полупиксель правильно. По моему опыту, такие ошибки полупикселей всплывают во множестве разных мест (камеры, сэмплирование текстур и т.п.) на протяжении долгих лет моей работы над кодом растеризатора в Autodesk. Далее по конвейеру они не приносят ничего, кроме боли. Если мы не будем внимательны, они могут появиться и в трассировщиках лучей.

  • Дробный показатель степени
  • Действия над степенями с дробными показателями

Дробный показатель

Число с дробным показателем степени равно корню с показателем, равным знаменателю, и подкоренным числом в степени, равной числителю.

Чтобы разобраться, почему число в дробной степени равно корню, надо вспомнить правило извлечения корня из степени:

Чтобы извлечь корень из степени, надо показатель степени разделить на показатель корня:

Действия над степенями с дробными показателями

Действия над степенями с дробными показателями совершаются по тем же правилам, которые установлены для степеней с целым показателем.

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

В частном случае n или q могут равняться единице.

При умножении дробных степеней с одинаковыми основаниями их показатели складываются:

При делении дробных степеней с одинаковыми основаниями из показателя делимого вычитается показатель делителя:

Чтобы возвести степень в другую степень в случае дробных показателей, достаточно перемножить показатели степеней:

Чтобы извлечь корень из дробной степени, достаточно показатель степени разделить на показатель корня:

Правила действий применимы не только к положительным дробным показателям, но и к отрицательным.

Предлагаем попробовать наш калькулятор степеней, который поможет возвести в степень онлайн любое число.

Использовать калькулятор очень просто — введите число, которое вы хотите возвести в степень, а затем число — степень и нажмите на кнопку «Посчитать».

Примечательно то, что наш онлайн калькулятор степеней может возвести в степень как положительную, так и отрицательную. А для извлечения корней на сайте есть другой калькулятор.

Как возвести число в степень.

Давайте рассмотрим процесс возведения в степень на примере. Пусть нам необходимо возвести число 5 в 3-ю степень. На языке математики 5 — это основание, а 3 — показатель (или просто степень). И записать это можно кратко в таком виде:

Возведение в степень

А чтобы найти значение, нам будет необходимо число 5 умножить на себя 3 раза, т. е.

53 = 5 x 5 x 5 = 125

Соответственно, если мы хотим найти значение числа 7 в 5 степени, мы должны число 7 умножить на себя 5 раз, т. е. 7 x 7 x 7 x 7 x 7. Другое дело когда требуется возвести число в отрицательную степень.

Как возводить в отрицательную степень.

При возведении в отрицательную степень необходимо использовать простое правило:

как возводить в отрицательную степень

Все очень просто — при возведении в отрицательную степень мы должны поделить единицу на основание в степени без знака минус — т. е. в положительной степени. Таким образом, чтобы найти значение
2-3

мы должны поступить следующим образом:

Оставить комментарий

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