Я приношу вибаченя за те, що відкрив достатньо стару тему, і вибачайте за правила які я порушую...
На російській я повідомлення писати не буду (не хочете не бачити - видаляйте)
я ж для вас пишу дослідження які провів.
я досить молодий програміст, мій стаж тільки 1 рік
і починаючи з грудня 2009 року я вивчав криві Безьє
Питання, як провести сплайн з кубічних кривих через N точок... ой як непросте.
але воно розв'язане уже більше 10ти років тому.
Компанія Adobe в славнозвісному CorelDraw продемонструвала хороший результат. Нажаль Adobe тримає свої коди в таємниці, тому до цього розв'язка доступу немає.
Потрібно крутись своїми силами.
Взагалі кажучи якщо точок буде 4 то це задача перетворюється в примітивну:
беремо матрицю Бернштейна з множиною коефіцієнтів (t0=0 , t1 , t2 , t4=1) і справа записуємо координати точок через які бажаємо провести криву
Якщо зведемо ліву матрицю до одиничної, то отримаємо контрольні точки, які потрібно взяти для того щоб крива проходила через 4 точки.
Q і - це контрольні точкий які ми отримаємо
це реаліцованно в файлі: Matrix_Ber.rar (знизу)
але якщо точок більше 4х що тоді?
Переважно такі програми, які не мають алгоритму CorelDraw беруть всі точки через які провели мишкою, розріджують алгоритмом Дугласа-Пеккера (це алгоритм який будує ламану по послідовності точок)
а далі проводить через точки ланцюга алгоритм який в цьому пості уже згадувався, і запропонований тут -
http://www.antigrain.com/research/bezie ... ERPOLATIONВідповідно до ступеня згладжування алгоритмом Дугласа-Пеккера, отримаємо порівняну не дуже ввелику кількість кривих і в той же час все гладко.
Ну але алгоритм далеко не ідеальний - спробуйте провести ідеально прямокутник ... завжди отримаєте щось назразок овалу
в файлі lastik.rar ви побачите реалізацію цього алгоритму в якості олівця
але от те що ви говорите "Красиво проходить через точки" математично можна сформуювати так:
побудувати криву таким чином, щоб сумма відстаней від точок до кривої, була мінімальна
питання: як знайти дистанцію до кривої?
ну це питання не таке і складне, можна різними способами... але мені найкраще себе показав алгоритм (чисельними методами):
виписати рівнняня дистанції, до кривої і потім його розвз'язувати.
Якщо ви вважаєте що рівняння дистанції до кривої дуже складне - ви помиляєтесь.
(просто потрібно зробити кілька підстановок, я це рівняння розвязав сам без чиєї небуть допомоги)
Якщо ви вважаєте, що рівнняня 6го степеня. Я ввас втішу - ні, це рівнняня 5ї степені
(рівнняня не парних степенів завжди має хоч 1 розв'язок, рівнняня парних може не мати дійсних коренів.
А дистанція вона то завжди існує, тобто це рівняння обовзязково непарної степені
)
ну виписувати його я не буду, но повірте наслово дуже просто виглядає. Але рішити 5ту степінь потрібно тільки Чисельними Методами з деяким коефіцієнтом точності.
Я на той час мав і інші способи розвязку (також сам вигадував)
В файлі Min_D.rar (знахоження дистанції від точки до кривої)
В файлі BZMin_Time.rar - тестовий приклад (перевіряв на швидкодію алгоритм чисельних методів)
Чисильними методами я навіть рішив як можна знайти перетин кривої і Еліпса
Згодом я цю ідею використав для ластіка, який витирає олівець.
Файл: bz_&_elipse.rar
Між іншим я на гуглив був один математичний алгоритм (
http://www.immsp.kiev.ua/publications/a ... 4_2004.pdf) , розібрався в ньому і зараз можу продемонструвати в файлі: Iteration.rar
це деякий Ітераційний алгоритм, в основі брати Матриці Точок, Матрицу Берштейна і звести до матриці яку можна буде мінімізувати методом Гауса.
В результаті отримаємо деяку систему з 4х невідомих... цими невідомими і буде знечення координат контрольних точок.
Алгоритм складається з двох частин, перший - побудова кривої з зазделегідь взятими коефіцієгтами t. Другий етам мінімізувати по коефіцієнтах (іншими словами знайти мінімальну, відстать)
от тільки недолік поки цього алгоритму , це те що він проводить всьоголише одну криву.
Але оскільки все зводиться до деякої системи:
a11 p1.x + a12 p2.x = R1
a21 p1.x + a12 p2.x = R2
то з відси видно, що можна зафіксувати одну з точок і рішити цю систему для однієї з точок.
Одже відповідно можна спробувати ділити ланцюг на право-побудовані точки, і ліво-побудовані точки.
Реалізації цієї ідеї я поки не маю.
PS: якби цей пост нагуглив би раніше, тоді би відповів своєчасно