Added by , published
Алгоритмы, Наработки и Способности
Способ реализации:
vJass
Тип:
Алгоритм

Кривая Безье

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

Зачем?

Это очень простая вещь на самом деле и тем не менее позволяет легко создавать сложные траектории снарядов, которые всем попадались на глаза
Мне необходимо было разобраться как динамически добавлять больше 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
В данном случае опорные точки нужно скопировать, чтобы сохранить основные
В чём преимущества первого метода по сравнению с этим алгоритмом мне не известны

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


`
LOADING AD...
2
Голосов: 2
1 month ago
2
Голосов: 2
О, круто.. дальше развиваешься
2
Голосов: 2
1 month ago
2
Голосов: 2
Мне необходимо было разобраться как динамически добавлять больше 4 опорных
Не очень проблематику понял. Можно поподробнее про подводные камни.
3
Голосов: 3
1 month ago
3
Голосов: 3
Безье - наше всё!
P.S. В wGeometry тоже есть Functions.bezier = function(p0, p1, p2, amount) и Functions.hermite = function(value1, tangent1, value2, tangent2, amount)

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

Берги, давай)) сальтухи пеоны еаучатся делать красивые при разбеге
3
Голосов: 3
1 month ago
Edited by ScorpioT1000
3
Голосов: 3
МрачныйВорон, а что непонятного. Есть множество точек в одномерном пространстве и есть 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
2
Голосов: 2
1 month ago
Edited by MpW
2
Голосов: 2
Можно притяжение всех пеонов к звезде, только в 3d. Прежставим себе галактику. И все пеоны притягиваются к звезде, вращаясь хаотично, как молекулы газа. Пеоны друг от друга бьются еще, ударясь, вращаясь. и звезда растет при вхождении пеона в нее
3
Голосов: 3
1 month ago
Edited by ScorpioT1000
3
Голосов: 3
С каждой новой степенью безья надо считать всё больше степени силы, что требует больше ресурсов, поэтому обычно сглаживают несколько точек последовательно. Типа для массива 1,2,3,4,5,...N мы сглаживаем 1,2,3, потом 2,3,4 итп так и получаются красивые графики, например www.highcharts.com/docs/chart-and-series-types/spline-chart
2
Голосов: 2
1 month ago
2
Голосов: 2
ScorpioT1000, я просто векторы не понимаю. Я думал там точки. Ладно, это тема исчерпана, тк я сейчас не за компом
2
Голосов: 2
3 weeks ago
2
Голосов: 2
скоро и до вычислений с числом Грэма дойдете(чисто для себя). Так держать 🙃🙃🙃
0
Голосов: 0
2 weeks ago
0
Голосов: 0
тяжело было найти хоть где-либо пример полиномы для 5 опорных точек
А можешь пояснить зачем больше 4 точек нужно? Хочется просто понять проблему целиком, которая может возникнуть.
rsfghd:
т.к. ты гений, миллиардер, плейбой, филантроп
Вообще не понял почему это под моим коментарием :D
0
Голосов: 0
2 weeks ago
0
Голосов: 0
А можешь пояснить зачем больше 4 точек нужно? Хочется просто понять проблему целиком, которая может возникнуть.
Никакой проблемы не возникает от 4 и меньше точек, просто за счёт большего количества опорных точек можно сильнее влиять на кривую, делая её более разнообразной
2
Голосов: 2
2 weeks ago
2
Голосов: 2
В далёком 2021 делал для кого-то примеры того, как использовать Безье в варе.
Пример кубической Безье. xgm.guru/files/100/319649/comments/525358/Bezier_example_1.w3m
Тут рабочий просто "бежит" по кривой построенной на основе 4-х точек.
Пример квадратичной Безье. xgm.guru/files/100/319649/comments/525358/Bezier_example_2.w3m
Тут рабочий движется к пехотинцу по воздуху. Из опорных точек можно установить только ту, что в воздухе, указав её высоту и расположение на линии между пехотинцем и рабочим.
0
Голосов: 0
2 weeks ago
0
Голосов: 0
росто за счёт большего количества опорных точек
А почему ты решил увеличивать степень полинома? Почему бы не связать на границе две кривые по координатам и производной/ным? Я сам плохо разбираюсь в такой аппроксимации , могу специфики не понимать.
0
Голосов: 0
2 weeks ago
0
Голосов: 0
Koladik, как разделить нечётное количество точек на кривые? Например 5 на 2?
0
Голосов: 0
2 weeks ago
0
Голосов: 0
Koladik, как разделить нечётное количество точек на кривые? Например 5 на 2?
Точки от 1 до 3 описываешь одним полиномом, от 3 до 5 вторым, оба 3-тей степени. На третей точке связка по производной и координате. Я не математик, просто предположение.
0
Голосов: 0
2 weeks ago
0
Голосов: 0
Koladik, и если понадобится динамическое количество точек ты будешь бегать между квадратичной и кубической кривой?
0
Голосов: 0
2 weeks ago
0
Голосов: 0
Koladik, и если понадобится динамическое количество точек ты будешь бегать между квадратичной и кубической кривой?
Там только на краях проблемы возникают. Так, что да. В любом случае придется всю кривую пересчитывать, если вдруг лишняя точка появится.
0
Голосов: 0
2 weeks ago
0
Голосов: 0
Koladik, в этом случае надо будет пересчитать только по 3 точки в обе стороны
обычно сглаживают несколько точек последовательно. Типа для массива 1,2,3,4,5,...N мы сглаживаем 1,2,3, потом 2,3,4 итп
0
Голосов: 0
2 weeks ago
0
Голосов: 0
по 3 точки в обе стороны
Я так понимаю, он говорит про общий случай динамических массивов, что если точки появляются по середине.
To leave a comment please sign in to the site.