Кривая Безье строится по четырем точкам: две основные точки (p0, p1) и две опорные (p0_hr, p1_hl).
Для того, чтобы построить на кривой дополнительную точку p2 в какой-то момент t, где t изменяется от 0 до 1 и представляет собой соотношение положения строящейся точки p2 к общей длине кривой, нужно проделать следующие вычисления:
Имеющиеся исходные данные:
- координаты точек p0 и p1
- координаты правой опорной точки для p0 – р0_hr
- координаты левой опорной точки для p1 – p1_hl
- соотношение t
Нужно найти:
- координаты для новой точки p2
- координаты двух ее опорных точек (левой и правой)
- новые координаты для опорных точек p0_hr и p1_hl
Разобьем отрезки [p0, p0_hr], [p0_hr, p1_hl] и [p1_hl, p1] точками t1, t2 и t3 в соотношении t по их длине.
Координаты построенных точек можно определить с помощью векторной математики, ведь координаты точки в пространстве – это вектор из начала координат (0,0,0) в эту точку.
На примере точки t1:
Имея исходные вектора (p0) и (p0_hr), можно получить вектор (v1), как разность (p0) и (p0_hr):
1 |
v1 = p0_hr - p0 |
Имея исходное соотношение t, можно получить вектор (v2):
1 |
v2 = v1 * t |
Сумма векторов (v2) и (p0) даст нужный вектор t1:
1 |
t1 = v2 + p0 |
И все вместе:
1 |
t1 = p0 + (p0_hr - p0) * t |
Аналогично для точек t2 и t3:
1 2 |
t2 = p0_hr + (p1_hl - p0_hr) * t t3 = p1_hl + (p1 - p1_hl) * t |
Полученные точки t1 и t3 – это координаты новых положений опорных точек для p0 и p1.
Нам осталось получить координаты точки p2 и двух ее опорных точек.
Соединим точки t1, t2 и t2, t3 отрезками. Теперь можно получить опорные точки для p2, исходя из все того же соотношения t.
1 2 |
p2_hl = t1 + (t2 - t1) * t p2_hr = t2 + (t3 - t2) * t |
Осталось найти координаты самой точки p2.
На отрезке, соединяющем точки p2_hl и p2_hr искомая точка p2 будет находится все по тому же соотношению t.
1 |
p2 = p2_hl + (p2_hr - p2_hl) * t |
Выражения для нахождения всех нужных точек получены. Наконец мы можем оставить математику и написать функцию для нахождения дополнительной точки на кривой Безье со всеми необходимыми опорными точками.
1 2 3 4 5 6 7 8 |
def new_bezier_point(p0, p0hr, p1hl, p1, t): t1 = p0 + (p0hr - p0) * t t2 = p0hr + (p1hl - p0hr) * t t3 = p1hr + (p1 - p1hl) * t p2hl = t1 + (t2 - t1) * t p2hr = t2 + (t3 - t2) * t p2 = p2hl + (p2hr - p2hl) * t return [t1, p2hl, p2, p2hr, t3] |
Теперь добавим на кривую Безье новую точку и установим полученные координаты точек.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
p0co = p0.co p0hr = p0.handle_right p1co = p1.co p1hl = p1.handle_left new_data = new_bezier_point(p0co, p0hr, p1hl, p1co, 0.3) bpy.ops.curve.subdivide(1) p0.handle_right_type = 'FREE' p0.handle_right = new_data[0] p1.handle_left_type = 'FREE' p1.handle_left = new_data[4] p2.co = new_data[2] p2.handle_left_type = 'FREE' p2.handle_right_type = 'FREE' p2.handle_left = new_data[1] p2.handle_right = new_data[3] |