Как создать круг с кривыми Безье? - PullRequest
79 голосов
/ 14 ноября 2009

У нас есть начальная точка (x, y) и радиус круга. Также существует механизм, который может создать путь из точек кривой Безье.

Как создать круг, используя кривые Безье?

Ответы [ 9 ]

115 голосов
/ 09 января 2015

Как уже говорилось: нет точного представления круга с использованием кривых Безье.

Для завершения других ответов: для кривой Безье с n сегментами оптимальное расстояние до контрольных точек в том смысле, что середина кривой лежит на самой окружности, составляет (4/3)*tan(pi/(2n)) ,

formula for n segments

Так что для 4 очков это (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831.

4 point case

30 голосов
/ 12 ноября 2012

Включено в comp.graphics.faq

Выдержка:

Тема 4.04: Как мне подогнать кривую Безье к кругу?

Интересно, что кривые Безье могут приближаться к кругу, но не совсем подходит по кругу. Общее приближение состоит в том, чтобы использовать четыре Безье для моделирования круга, каждый с контрольными точками расстояние d = r * 4 * (sqrt (2) -1) / 3 от конечных точек (где r - радиус окружности) и в направлении, касающемся круг в конечных точках. Это обеспечит середины Безье на круге, и что первая производная непрерывна.
Радиальная погрешность в этом приближении составит около 0,0273% от радиус круга.

Michael Goldapp, "Приближение дуг окружности кубическим полиномы "Компьютерное геометрическое проектирование (№ 8 1991 с.227-238)

Тор Доккен и Мортен Дэлен, "Хорошие приближения кругов кривые Безье с непрерывной кривизной Дизайн (№ 7 1990 с. 33-41). http://www.sciencedirect.com/science/article/pii/016783969090019N (не бесплатная статья)

См. Также статью о неоплаченных документах по адресу http://spencermortensen.com/articles/bezier-circle/

.

Браузеры и элемент Canvas.

Обратите внимание, что некоторые браузеры используют кривые Безье для своей дуги рисования холста, Chrome использует (в настоящее время) четырехсекторный подход, а Safari использует восьмисекторный подход, разница заметна только при высоком разрешении, так как 0,0273% и также действительно видимым, только если дуги нарисованы параллельно и не в фазе, вы заметите, что дуги колеблются от истинного круга. Эффект также более заметен, когда кривая анимируется вокруг своего радиального центра, радиус 600px обычно является размером, в котором он будет иметь значение.

Некоторые API рисования не имеют истинного рендеринга дуг, поэтому они также используют кривые Безье, например, платформа Flash не имеет API рисования дуг, поэтому любые платформы, которые предлагают дуги, обычно используют один и тот же подход к кривой Безье.

Обратите внимание, что движки SVG в браузерах могут использовать другой метод рисования.

Другие платформы

Какую бы платформу вы не пытались использовать, стоит проверить, как выполняется дуговое рисование, чтобы вы могли прогнозировать подобные визуальные ошибки и адаптироваться.

22 голосов
/ 03 мая 2017

Ответы на вопрос очень хорошие, поэтому добавить нечего. Вдохновленный этим, я начал проводить эксперимент, чтобы визуально подтвердить решение, начиная с четырех кривых Безье, сократив число кривых до одной. Удивительно, но я обнаружил, что с тремя кривыми Безье круг выглядел достаточно хорошо для меня, но конструкция немного сложнее. На самом деле я использовал Inkscape, чтобы поместить черное приближение Безье шириной в 1 пиксель по красному кругу шириной в 3 пикселя (как в Inkscape). Для пояснения я добавил синие линии и поверхности, показывающие ограничивающие рамки кривых Безье.

Чтобы увидеть себя, я представляю свои результаты:

1-кривой график (который выглядит как капля, сжатая в углу, только для полноты): enter image description here

2-кривой график: enter image description here

3-кривой график: enter image description here

4-кривой график: enter image description here

(я хотел разместить здесь SVG или PDF, но это не поддерживается)

7 голосов
/ 01 мая 2016

Уже много ответов, но я нашел небольшую онлайн-статью с очень хорошим приближением кубического Безье к кругу. В единицах окружности с = 0,55191502449, где с - расстояние от точек пересечения оси вдоль касательных к контрольным точкам.

В качестве одного квадранта для единичного круга с двумя средними координатами, являющимися контрольными точками. (0,1),(c,1),(1,c),(1,0)

Радиальная ошибка составляет всего 0,019608%, поэтому мне просто нужно было добавить ее в этот список ответов.

Статью можно найти здесь Приблизительный круг с кубическими кривыми Безье

7 голосов
/ 06 февраля 2013

Другие ответы охватили тот факт, что истинный круг невозможен. Этот SVG-файл является аппроксимацией с использованием квадратичных кривых Безье и является ближайшей вещью, которую вы можете получить: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg

Вот один с кубическими кривыми Безье: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg

7 голосов
/ 14 ноября 2009

Это невозможно. Безье - это куб (по крайней мере ... чаще всего используется). Круг не может быть выражен точно с кубикой, потому что круг содержит квадратный корень в своем уравнении. Как следствие, вы должны приблизиться.

Чтобы сделать это, вы должны разделить свой круг на n-tants (например, квадранты, октанты). Для каждого n-тана вы используете первую и последнюю точку в качестве первой и последней кривой Безье. Многоугольник Безье требует двух дополнительных точек. Чтобы быть быстрым, я бы взял касательные к окружности для каждой крайней точки n-танта и выбрал две точки как пересечение двух касательных (так что в основном ваш многоугольник Безье является треугольником). Увеличьте количество n-tants, чтобы соответствовать вашей точности.

1 голос
/ 15 июля 2015

Я не уверен, стоит ли мне открывать новый вопрос, поскольку речь идет об аппроксимации, но меня интересует общая формула для получения контрольных точек для Безье любой степени, и я считаю, что она вписывается в этот вопрос. Все решения, которые я нашел в интернете, предназначены только для кубических кривых или платные, или я даже не понимаю (я не очень хорош в математике). Поэтому я решил попытаться решить это самостоятельно. Я изучал расстояние контрольной точки от центра круга в зависимости от заданного угла, и до сих пор я обнаружил, что:

enter image description here

Где N - количество контрольных точек для одной кривой, а α - угол дуги окружности.

Для квадратичной кривой ее можно упростить до l ≈ r + r * PI*0.1 * pow(α/90, 2) PI*0.1 скорее предположение - я не рассчитал идеальное значение, но оно довольно близко. Это работает достаточно хорошо для кривой с 1-2 контрольными точками, дающими погрешность радиуса около 0,2% для кубической кривой. Для кривых более высокой степени потеря точности заметна. С 3 контрольными точками кривая похожа на квадратичную, так что, очевидно, я что-то упускаю, но не могу понять, и этот метод в целом соответствует моим потребностям на данный момент. Вот демо .

0 голосов
/ 06 июня 2014

Извините, что вернул это из мертвых, но я нашел этот пост очень полезным, наряду с этой страницей, которая предлагает расширяемую формулу.

По сути, вы можете создать ближний круг, используя невероятно простую формулу, которая позволяет использовать любое количество кривых Безье в течение 4: Distance = radius * stepAngle / 3

Где Distance - это расстояние между контрольной точкой Безье и ближайшим концом дуги, радиус - это radius круга, а stepAngle - это угол между двумя концами дуги, представленный 2π / (количество кривых).

Итак, чтобы поразить его одним выстрелом: Distance = radius * 2π / (the number of curves) / 3

0 голосов
/ 12 октября 2013

Это тяжелое приближение, которое будет выглядеть разумным или ужасным в зависимости от разрешения и точности, но я использую sqrt (2) / 2 x radius в качестве контрольных точек. Я прочитал довольно длинный текст, как получается это число, и его стоит прочитать, но приведенная выше формула быстрая и грязная.

...