Задача — при рисовании freeform (как в Paint'е) чтобы получалась линия не "дерганная", а сглаженная.
По-русски, видимо, это будет интерполяция кривой при большом количестве точек? Или рисовалки, в которых получаются "плавные" линии, просто бОльшую часть точек игнорируют?
Господа, ткните носом, пожалуйста — куда смотреть?
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Задача — при рисовании freeform (как в Paint'е) чтобы получалась линия не "дерганная", а сглаженная. ЗХ>По-русски, видимо, это будет интерполяция кривой при большом количестве точек? Или рисовалки, в которых получаются "плавные" линии, просто бОльшую часть точек игнорируют?
ЗХ>Господа, ткните носом, пожалуйста — куда смотреть?
Здравствуйте, Кодт, Вы писали:
ЗХ>>Задача — при рисовании freeform (как в Paint'е) чтобы получалась линия не "дерганная", а сглаженная. ЗХ>>По-русски, видимо, это будет интерполяция кривой при большом количестве точек? Или рисовалки, в которых получаются "плавные" линии, просто бОльшую часть точек игнорируют?
К>Ключевые слова: antialiasing, McSeem2, antigrain geometry
Подозреваю, что вопрос не об этом. Вопрос о том, как аппроксимировать набор точек с шумом последовательностью гладких кривых или одной кривой большого порядка. В AGG такого нет пока что.
Можно, например, предложить для начала вот это: http://astronomy.swin.edu.au/~pbourke/curves/bezier/
/*
General Bezier curve
Number of control points is n+1
0 <= mu < 1 IMPORTANT, the last point is not computed
*/
XYZ Bezier(XYZ *p,int n,double mu)
{
int k,kn,nn,nkn;
double blend,muk,munk;
XYZ b = {0.0,0.0,0.0};
muk = 1;
munk = pow(1-mu,(double)n);
for (k=0;k<=n;k++) {
nn = n;
kn = k;
nkn = n - k;
blend = muk * munk;
muk *= mu;
munk /= (1-mu);
while (nn >= 1) {
blend *= nn;
nn--;
if (kn > 1) {
blend /= (double)kn;
kn--;
}
if (nkn > 1) {
blend /= (double)nkn;
nkn--;
}
}
b.x += p[k].x * blend;
b.y += p[k].y * blend;
b.z += p[k].z * blend;
}
return(b);
}
Но здесь каждая точка требует O(N^2) вычислений. То есть, для всей кривой будет O(N^2 * K).
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, Кодт, Вы писали:
ЗХ>>Задача — при рисовании freeform (как в Paint'е) чтобы получалась линия не "дерганная", а сглаженная. ЗХ>>По-русски, видимо, это будет интерполяция кривой при большом количестве точек? Или рисовалки, в которых получаются "плавные" линии, просто бОльшую часть точек игнорируют?
ЗХ>>Господа, ткните носом, пожалуйста — куда смотреть?
К>Ключевые слова: antialiasing, McSeem2, antigrain geometry
Умный, да?
AGG-ом я пользуюсь уже полгода
Но тут другая задача — понадобилось мне сделать очень простенький граф. редактор (по сути — только freehand рисование). И вот в нем нужна эта самая плавность. То есть — если в Paint'e карандашиком рисовать — линия получается "дерганная", а, скажем, в Corel Draw — плавная дуга. Меня интересует не уровень одного пиксела (ступеньки), а общая картинка.
Понятно объяснил? Или нарисовать, что я имею в виду?
Здравствуйте, McSeem2, Вы писали:
MS>Здравствуйте, Кодт, Вы писали:
ЗХ>>>Задача — при рисовании freeform (как в Paint'е) чтобы получалась линия не "дерганная", а сглаженная. ЗХ>>>По-русски, видимо, это будет интерполяция кривой при большом количестве точек? Или рисовалки, в которых получаются "плавные" линии, просто бОльшую часть точек игнорируют?
К>>Ключевые слова: antialiasing, McSeem2, antigrain geometry
MS>Подозреваю, что вопрос не об этом. Вопрос о том, как аппроксимировать набор точек с шумом последовательностью гладких кривых или одной кривой большого порядка.
MS>Можно, например, предложить для начала вот это:
Ага, про Безье знаю. Просто думал, может чего проще есть?
ЗЫ: пользуясь случаем хочу принести публичную благодарность автору AGG от Радиоастрономического Института Академии Наук Украины за неоценимую помощь его библиотеки в отображении сканов радиотелескопов УРАН-1 и др.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Ага, про Безье знаю. Просто думал, может чего проще есть?
Безье не работает толком. Во-первых, жутко тормозно, во-вторых, скорее всего не то, что надо, в-третьих, проблемы с числовой стабильностью. Выражение double munk = pow(1.0 — mu, (double)n); при больших степенях и mu близким к 1 банально обращатся в 0. http://www.antigrain.com/stuff/general_bezier2.zip
Хотя, конечно колбасит ее весьма забавно.
Надо что-то простое, типа эмуляции притяжения. В химическом скетчере я сделал "легкое" сглаживание для лассо:
И вообще, можно тривиально усреднять соседние точки (отдельно по X и Y), после чего пройтись по результату кубическим сплайном, если есть желание.
Сейчас проверю — интересно. Тем более, пятница-вечер. Работа не вааще не прет...
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, McSeem2, Вы писали:
ЗХ>>Ага, про Безье знаю. Просто думал, может чего проще есть?
MS>Безье не работает толком. Во-первых, жутко тормозно, во-вторых, скорее всего не то, что надо, в-третьих, проблемы с числовой стабильностью. Выражение double munk = pow(1.0 — mu, (double)n); при больших степенях и mu близким к 1 банально обращатся в 0. MS>http://www.antigrain.com/stuff/general_bezier2.zip MS>Хотя, конечно колбасит ее весьма забавно.
Во! поэтому и не хотелось Безье!
MS>Надо что-то простое, типа эмуляции притяжения. В химическом скетчере я сделал "легкое" сглаживание для лассо:
Глянул сейчас в скетчере — это уже "почти". Но все равно несколько угловато.
MS>И вообще, можно тривиально усреднять соседние точки (отдельно по X и Y), после чего пройтись по результату кубическим сплайном, если есть желание.
О! Слово "сплайн" мне знакомо... Вот это уже похоже ближе к телу.
MS>Сейчас проверю — интересно. Тем более, пятница-вечер. Работа не вааще не прет...
Здравствуйте, McSeem2, Вы писали:
MS>http://antigrain.com/stuff/bspline3.zip
MS>Идея проста — усредняем кординаты трех точек и записываем результат во временный буфер. Для крайних точек усредняем только две.
MS>Повторяем операцию N раз.
MS>Мы убрали высокочастотный шум, но не добавили новых точек для гладкости. Добавляем при помощи любой интерполяции, например, bspline.
Вот это уже совсем почти-почти то что надо. Проблема — при быстром рисовании (получается большая ломанная из небольшого кол-ва точек) интерполирующая линия далековато от ломанной...
Как это можно поправить?
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Вот это уже совсем почти-почти то что надо. Проблема — при быстром рисовании (получается большая ломанная из небольшого кол-ва точек) интерполирующая линия далековато от ломанной... ЗХ>Как это можно поправить?
Можно попробовать тривиальный метод. Дробим длинные сегменты на более короткие. Сейчас проверю.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
ЗХ>Вот это уже совсем почти-почти то что надо. Проблема — при быстром рисовании (получается большая ломанная из небольшого кол-ва точек) интерполирующая линия далековато от ломанной... ЗХ>Как это можно поправить?