Добавлен , опубликован

Кривая Безье

Я не буду расписывать какую-либо статью про кривые, какие они бывают, когда кем придуманы и прочую ерунду, ибо в этом нет смысла, всё уже давно разжёвано максимально понятным образом. В самом низу находятся источники, я просто покидаю примеры для понимания. Так же, на хайве есть векторная наработка по кривым с алгоритмом Де Кастельжо:

Зачем?

Это очень простая вещь на самом деле и тем не менее позволяет легко создавать сложные траектории снарядов, которые всем попадались на глаза
Мне необходимо было разобраться как динамически добавлять больше 4 опорных точек для кривой и возникли проблемы, из-за которых пришлось изучать что как где и почему
И да, у меня есть псевдостатья по безье, но мне этого было недостаточно
хотя, скорее всего, и из того, что там есть, можно было сделать безье высшей степени, суммировав значения, но мне не хватило мозгов как всегда

Треугольник Паскаля

Для прямого метода нужен треугольник Паскаля:
Делается просто:
    private static hashtable PascalTriangle = InitHashtable( )
    private static integer PascalTriangleRows = 2

    static method RegistPascalTriangle takes integer i returns nothing
        local integer n
        local integer k
        
        if i > PascalTriangleRows then
            set n = PascalTriangleRows
            
            loop
                set k = 0
                
                loop
                    call SaveInteger( PascalTriangle, n, k, LoadInteger( PascalTriangle, n - 1, k - 1 ) + LoadInteger( PascalTriangle, n - 1, k ) )
                    
                    set k = k + 1
                    exitwhen k > n
                endloop
                
                set n = n + 1
                exitwhen n > i
            endloop
        
            set PascalTriangleRows = i
        endif
    endmethod
    
    static method onInit takes nothing returns nothing
        call SaveInteger( PascalTriangle, 0, 0, 1 )
        call SaveInteger( PascalTriangle, 1, 0, 1 )
        call SaveInteger( PascalTriangle, 1, 1, 1 )
    endmethod
Можно естественно воспользоваться двумерным массивом примерно 7х7, чтобы покрыть практически все нужды и не занимать хэштаблицу, единственная проблема, что массивность двумерных должна быть определена заранее в вджассе, т.е. если есть динамическая фигня и вдруг в игре поднадобилось 8х8+ размерность, то всё сломается

Построение кривой

call RegistPascalTriangle( count )

set i = 0

loop
	set r = LoadInteger( PascalTriangle, count - 1, i ) * Pow( 1.00 - time, count - 1 - i ) * Pow( time, i )
            
	set x1 = x1 + r * x[i]
	set y1 = y1 + r * y[i]
	set z1 = z1 + r * z[i]
            
	set i = i + 1
	exitwhen i >= count
endloop
count - количество опорных точек
time - фактор кривой, т.е. нормализированная величина (от 0.00 до 1.00)
x1, y1, z1 - искомая точка
x[ ], y[ ], z[ ] - опорные точки
r - полином, т.е. сама конструкция кривой

Оптимизация

Чтобы исключить факториалы и треугольники Паскаля, можно воспользоваться алгоритмом Де Кастельжо:
set k = 0

loop
	set i = 0
	
	loop
		set x[i] = ( 1.00 - time ) * x[i] + time * x[i + 1]
		set y[i] = ( 1.00 - time ) * y[i] + time * y[i + 1]
		set z[i] = ( 1.00 - time ) * z[i] + time * z[i + 1]
		
		set i = i + 1
		exitwhen i > count - k
	endloop
	
	set k = k + 1
	exitwhen k >= count - 1
endloop
В данном случае опорные точки нужно скопировать, чтобы сохранить основные
В чём преимущества первого метода по сравнению с этим алгоритмом мне не известны

Прикладываю карту с этими способами


`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
11
Мне необходимо было разобраться как динамически добавлять больше 4 опорных
Не очень проблематику понял. Можно поподробнее про подводные камни.
38
Безье - наше всё!
P.S. В wGeometry тоже есть Functions.bezier = function(p0, p1, p2, amount) и Functions.hermite = function(value1, tangent1, value2, tangent2, amount)

p.p.s 1.00 - time обычно выносят в переменную для оптимизации в языках, где нет оптимизации при компиляции
33
Надо тоже обмазаться вашим безьё, из каждого утюга о нём кричите
28
Не очень проблематику понял. Можно поподробнее про подводные камни.
тяжело было найти хоть где-либо пример полиномы для 5 опорных точек, везде только 4:
P0 * (1-t)^3 + P1 * t * (1-t)^2 + P2 * t^2 * (1-t) + P3 * t^3
у меня была попытка пихнуть сюда как-нибудь 5 опорную точку, пришлось изучать, оказывается там ещё треугольник паскаля нужен, ну и появился этот недоресурс
я с математикой не дружу, поэтому если ты и видишь в этом бесполезность, т.к. ты гений, миллиардер, плейбой, филантроп (завидую белой завистью), то для людей вроде меня может и не быть настолько бесполезным, естественно есть куча всяких наработок уже, опять же, хайв, который указан в самом начале и по сути на этом моменте страничку можно закрывать, ну и от ScorpioT1000 3д библиотека, где тоже оказывается есть безье
если вбить в поиск хгм или гугла по хгм слово безье, то можно наткнуться на мою старую статью в блоге с 3 точками, на работы в мдлвисе с анимациями и какие-то комментарии, где и удалось найти ссылку на хайв
27
Соглашусь с выше мнением. У Скорпа есть библиотека, но ей очень сложна воспользоваться из за очень непонятных параметров

Берги, давай)) сальтухи пеоны еаучатся делать красивые при разбеге
38
МрачныйВорон, а что непонятного. Есть множество точек в одномерном пространстве и есть volume (сила от 0 до 1 или больше). Для многомерного у векторов wGeometry есть метод или просто применить функцию к каждой компоненте векторов.
Гифка выше наглядно показывает силу (оно же время в его случае). Просто время в математике не значит физическое время, а скорее что угодно, равномерно наростающее

    -- Applies bezier spline interpolation
    --- @param p2 Vector3 point 2
    --- @param p3 Vector3 point 3
    --- @param amount current animation state, number between 0 and 1
    --- @return Vector3 result
    bezier = function(self, p2, p3, amount)
      return Vector3:new(
        Functions.bezier(self.x, p2.x, p3.x, amount),
        Functions.bezier(self.y, p2.y, p3.y, amount),
        Functions.bezier(self.z, p2.z, p3.z, amount)
      )
    end
27
Можно притяжение всех пеонов к звезде, только в 3d. Прежставим себе галактику. И все пеоны притягиваются к звезде, вращаясь хаотично, как молекулы газа. Пеоны друг от друга бьются еще, ударясь, вращаясь. и звезда растет при вхождении пеона в нее
38
С каждой новой степенью безья надо считать всё больше степени силы, что требует больше ресурсов, поэтому обычно сглаживают несколько точек последовательно. Типа для массива 1,2,3,4,5,...N мы сглаживаем 1,2,3, потом 2,3,4 итп так и получаются красивые графики, например www.highcharts.com/docs/chart-and-series-types/spline-chart
27
ScorpioT1000, я просто векторы не понимаю. Я думал там точки. Ладно, это тема исчерпана, тк я сейчас не за компом
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.