베 지어 곡선으로 원을 만드는 방법은 무엇입니까?


답변:


139

이미 말했듯이, Bezier 곡선을 사용한 원의 정확한 표현은 없습니다.

다른 답을 완성하려면 : n세그먼트가있는 베 지어 곡선 의 경우 곡선의 중간이 원 자체에 있다는 의미에서 제어점까지 의 최적 거리는입니다 (4/3)*tan(pi/(2n)).

n 세그먼트에 대한 공식

따라서 4 점의 경우 (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831.

4 점 케이스


2
최적의 거리를 기준으로 어떤 종류의 메트릭을 최적화하고 있습니까? 3 차 베 지어 곡선이 있는 대략적인 원에 표시된대로 가능한 가장 낮은 최대 드리프트는 다른 값에 의해 달성됩니다. 귀하의 경우에 "최적"이 무엇을 의미하는지 또는 공식이 어떻게 파생되었는지를 정의하는 링크를 제공 할 수 있습니까?
스마

1
@Suma 이것은 약간의 거리에 최적이 아닙니다. 원에 곡선의 중간을 갖는 것이 최적 입니다. 그리고 다른 기준을두면 확실히 더 나아질 수 있습니다.
Kpym

2
확인. "곡선의 중간이 원 자체에 놓 이도록 제어점까지의 거리"라는 말을 바꿔 보겠습니다. 나는 이것을 유효한 결정 (충분히 좋고 계산하기 쉬움)이라고 생각하지만, 그것을 최적이라고 부르지는 않을 것입니다 (적어도 그것이 최적의 의미를 쓰지 않고서는 아닙니다).
Suma

1
예, 이것은 최대 편차가 + 0.027 %이고 최소 편차가 -0 대 실제 원이기 때문입니다. 실제 원보다 더 클수록 C를 0.027 %의 절반으로 이동하여 더 나은 근사치를 얻을 수 있습니다. 그래도 원의 중간 점을 원한다면 이것이 확실히 할 수있는 방법입니다.
Tatarize dec

2
@ legends2k TikZ와 함께 LaTeX를 사용하여 PNG로 변환 할 PDF를 생성합니다.
Kpym

35

comp.graphics.faq에 포함됨

발췌 :

주제 4.04 : 원에 베 지어 곡선을 맞추는 방법은 무엇입니까?

흥미롭게도 Bezier 곡선은 원에 가깝지만 원에 완벽하게 맞지는 않습니다. 일반적인 근사치는 4 개의 베 지어를 사용하여 원을 모델링하는 것입니다. 각각은 제어점이 끝점에서 d = r * 4 * (sqrt (2) -1) / 3 거리에 ​​있고 (여기서 r은 원 반경) 끝점에서 원에 접하는 방향. 이렇게하면 베 지어의 중간 점이 원 위에 있고 1 차 도함수가 연속적임을 확인할 수 있습니다.
이 근사치의 반경 오차는 원 반경의 약 0.0273 %입니다.

Michael Goldapp, "입방 다항식에 의한 원호 근사"Computer Aided Geometric Design (# 8 1991 pp.227-238)

Tor Dokken 및 Morten Daehlen, "곡률 연속 베 지어 곡선에 의한 원의 근사치"Computer Aided Geometric Design (# 7 1990 pp. 33-41). http://www.sciencedirect.com/science/article/pii/016783969090019N (비 무료 기사)

또한 http://spencermortensen.com/articles/bezier-circle/ 에서 유료화되지 않은 기사를 참조하십시오.

브라우저 및 캔버스 요소.

일부 브라우저는 캔버스 그리기 아크에 베 지어 곡선을 사용하고, Chrome은 (현재) 4 섹터 접근 방식을 사용하고 Safari는 8 섹터 접근 방식을 사용하며, 그 차이는 0.0273 %로 인해 고해상도에서만 눈에 띄며, 호가 평행하고 위상이 맞지 않을 때만 실제로 볼 수 있으며 호가 실제 원에서 진동하는 것을 알 수 있습니다. 이 효과는 곡선이 방사형 중심을 중심으로 움직일 때 더 두드러집니다. 600px 반경은 일반적으로 차이를 만드는 크기입니다.

특정 드로잉 API에는 실제 아크 렌더링이 없으므로 Bezier 곡선도 사용합니다. 예를 들어 Flash 플랫폼에는 아크 드로잉 API가 없으므로 아크를 제공하는 모든 프레임 워크는 일반적으로 동일한 Bezier 곡선 접근 방식을 사용합니다.

브라우저 내의 SVG 엔진은 다른 그리기 방법을 사용할 수 있습니다.

기타 플랫폼

사용하려는 플랫폼이 무엇이든 아크 드로잉이 어떻게 수행되는지 확인하는 것이 가치가 있으므로 이와 같은 시각적 오류를 예측하고 적응할 수 있습니다.


감사합니다. 대체하겠습니다.
ocodo

31

질문에 대한 답이 매우 좋으므로 추가 할 사항이 거의 없습니다. 그것에 영감을 받아 저는 4 개의 베 지어 곡선으로 시작하여 곡선의 수를 1 개로 줄이면서 솔루션 을 시각적으로 확인 하는 실험을 시작했습니다. 놀랍게도 3 개의 베 지어 곡선을 사용하면 원이 나에게 충분 해 보이지만 구성이 약간 까다 롭다는 것을 알았습니다 . 실제로 Inkscape를 사용하여 빨간색 3 픽셀 너비의 원 위에 검정색 1 픽셀 너비의 베 지어 근사치를 배치했습니다 (잉크 스케이프에서 생성 한대로). 명확하게하기 위해 Bézier 곡선의 경계 상자를 보여주는 파란색 선과 표면을 추가했습니다.

자신을보기 위해 내 결과를 제시합니다.

1- 커브 그래프 (완전 함을 위해 모서리에 눌린 방울 모양) :여기에 이미지 설명 입력

2- 곡선 그래프 :여기에 이미지 설명 입력

3 곡선 그래프 :여기에 이미지 설명 입력

4 곡선 그래프 : 여기에 이미지 설명 입력

(SVG 또는 PDF를 여기에 넣고 싶었지만 지원되지 않습니다)


1
이제 svg는 html 코드 조각으로 포함될 수 있습니다. 예를
TS

1
@TS : 제가 가지고 있던 SVG로 그래픽을 교체하려고했을 때, 올해 초에 도난당한 USB 스틱으로 그래픽을 잃어 버렸다는 것을 깨달았습니다. 시간이 허락한다면 조만간 다시 만들어 보겠습니다. 그러나 SVG를 XML 코드로 추가 할 수 있고 그래픽으로 표시되지 않는 경우 여기에서는 의미가 없습니다.
U. Windl

브라우저가 svg를 지원하는 경우 "Run Code Snippet"을 클릭하자마자 이미지가 렌더링됩니다 (분명히 해당 버튼은 모바일 버전의 stackoverflow에서 사용할 수 없습니다 ...). 내가 연결 한 답변을 참조하십시오.
TS

1
@TS : 더 긴 파일의 경우 너무 추한 IMHO입니다.
U. Windl

9

이미 많은 답변을 받았지만 원의 입방 베 지어 근사치가 매우 좋은 작은 온라인 기사를 찾았습니다. 단위 원의 관점에서 c = 0.55191502449 여기서 c는 접선을 따라 제어점까지의 축 교차점에서 거리입니다.

두 개의 중간 좌표가 제어점 인 단위 원에 대한 단일 사분면으로. (0,1),(c,1),(1,c),(1,0)

방사형 오류는 0.019608 %에 불과하므로이 답변 목록에 추가해야했습니다.

이 기사는 여기에서 찾을 수 있습니다. 3 차 베 지어 곡선이있는 대략적인 원


5
이 읽게 우수한 논문 에 유래의에 의해 베 지어 곡선에 마이크 'POMAX'Kamermans을 . 읽을만한 가치가 있습니다! :-)
markE

1
@markE이 주제에 대해 내가 본 "가장 우수한"논문 중 하나 인 링크에 대해 대단히 감사합니다. 자세히
살펴볼

1
따라서 0.019608 % 오류를 사용하면 반경이 원에서 2551 픽셀을 넘을 때 4 픽셀 오류가 발생합니다. 여기서 우리는 솔리드 반 픽셀 오류 (그래픽 엔진이 픽셀을 변경하는 위치) 인 경우 0.027253 %가 아닙니다. 1835 픽셀에서 2 픽셀에 오류가 발생합니다!
Tatarize

@Tatarize이 기사는 오류 측정 방법을 지정하지 않습니다. 최대 방사형 드리프트? 0 <= t <= 1 곡선을 따라 오류가 최소화되어 0 <= pheta <= Pi / 2 at t = 0 = 1/2 = 1 = pheta = 0 = Pi / 4 = Pi / 4 오류는 0.019608 %이고 t = ~ 0.1822 & t = ~ 0.8177의 0.019608 % (기호?)이지만이 지점에서 t는 pheta와 같지 않습니다. 오류에 각도 드리프트가 포함됩니까? . 4 픽셀은 정확하거나 정확하지 않을 수 있습니다. 이 오류는 따라서 <2pix 조사해야합니다 질문의 R = 2551을 많이에 대한 오류, 분산 될 수있다
Blindman67

주어진 조정이 호선 위의 최대 오류가 호선 아래의 최대 오류와 같도록 충분히 아래로 포인트를 이동한다는 오류 곡선을 보았을 것입니다. 즉, 모든 오류가 양수가 아니도록 곡선을 약간 변경합니다. 이 조정은 최대 오차 4 점으로 원호 선을 4 번 교차한다는 것을 의미합니다. 원래 지정된 선에 2 개의 점이있을 때, 즉 t = .25 및 t = .75입니다. 조정을 통해 t = .125, t = .375 t = .625 t = .875에 있어야합니다. 이것은 우리가 14px에서 변경되는 앤티 앨리어싱이 아닌 단색 픽셀을 사용하고 있다고 가정합니다.
Tatarize

8

불가능합니다. 베 지어는 입방체입니다 (적어도 ... 가장 일반적으로 사용되는 것은). 원은 방정식에 제곱근을 포함하기 때문에 3 차로 정확하게 표현할 수 없습니다. 결과적으로 근사치가 필요합니다.

이렇게하려면 원을 n-tant (egquadrants, octants)로 나누어야합니다. 각 n-tant에 대해 첫 번째와 마지막 점을 베 지어 곡선의 첫 번째와 마지막 점으로 사용합니다. 베 지어 다각형에는 두 개의 추가 점이 필요합니다. 빠르게하기 위해, 저는 n-tant의 각 극단 점에 대한 원의 접선을 취하고 두 점을 두 접선의 교차점으로 선택합니다 (기본적으로 Bezier 다각형이 삼각형이되도록). 정밀도에 맞게 n-tant 수를 늘리십시오.


4
길이가 0 인 무한한 수의 베 지어 곡선을 사용하는 한 가능합니다. 그것은 기본적으로 무한한 수의 점이거나 오히려 호 곡선입니다.
Tatarize dec


7

코드를 찾는 사람들에게 :

https://jsfiddle.net/nooorz24/2u9forep/12/

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

function drawBezierOvalQuarter(centerX, centerY, sizeX, sizeY) {
    ctx.beginPath();
    ctx.moveTo(
        centerX - (sizeX),
        centerY - (0)
    );
    ctx.bezierCurveTo(
        centerX - (sizeX),
        centerY - (0.552 * sizeY),
        centerX - (0.552 * sizeX),
        centerY - (sizeY),
        centerX - (0),
        centerY - (sizeY)
    );
    ctx.stroke();
}

function drawBezierOval(centerX, centerY, sizeX, sizeY) {
    drawBezierOvalQuarter(centerX, centerY, -sizeX, sizeY);
    drawBezierOvalQuarter(centerX, centerY, sizeX, sizeY);
    drawBezierOvalQuarter(centerX, centerY, sizeX, -sizeY);
    drawBezierOvalQuarter(centerX, centerY, -sizeX, -sizeY);
}

function drawBezierCircle(centerX, centerY, size) {
    drawBezierOval(centerX, centerY, size, size)
}

drawBezierCircle(200, 200, 64)
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

이를 통해 4 개의 베 지어 곡선으로 만들어진 원을 그릴 수 있습니다. JS로 작성되었지만 다른 언어로 쉽게 번역 가능

노트

꼭 필요한 경우가 아니라면 SVG 경로를 사용하여 원을 그려야하는 경우 베 지어 곡선을 사용하지 마십시오. 경로에서 Arc2 개의 반원을 만드는 데 사용할 수 있습니다 .

SVG의 호 경로로 원 그리기


매우 도움이됩니다. 감사합니다! 4 개의 세그먼트를 순서대로 가져 오려면 무엇을 변경해야합니까? 경로를 따라 텍스트를 작성해야하지만 이제 4 개의 세그먼트 주위에 흩어져 있습니다
Alexa

1

이것이 근사화에 관한 것이기 때문에 새 질문을 열어야할지 모르겠지만 어떤 정도의 Bezier에 대한 제어점을 얻는 일반 공식에 관심이 있으며이 질문에 적합하다고 생각합니다. 내가 웹에서 찾은 모든 솔루션은 입방 곡선 전용이거나 유료이거나 이해하지 못합니다 (나는 수학을 잘하지 못합니다). 그래서 나는 이것을 스스로 해결하기로 결정했습니다. 주어진 각도에 따라 원의 중심에서 제어점까지의 거리를 연구했으며 지금까지 다음과 같은 사실을 발견했습니다.

여기에 이미지 설명 입력

N단일 곡선에 대한 제어점의 수는 어디 이며 α원호 각도입니다.

2 차 곡선의 경우 다음과 같이 단순화 할 수 있습니다. l ≈ r + r * PI*0.1 * pow(α/90, 2) The PI*0.1is a just a guess-I did n't compute perfect value but it 's very close. 이것은 3 차 곡선에 대해 0.2 % 반경 오차를 제공하는 1-2 개의 제어점이있는 곡선에서 상당히 잘 작동합니다. 더 높은 수준의 곡선의 경우 정확도 손실이 눈에.니다. 3 개의 제어점을 사용하면 곡선이 2 차와 비슷해 보이므로 분명히 뭔가를 놓쳤지만 알아낼 수 없으며이 방법은 일반적으로 현재 내 요구에 적합합니다. 여기에 데모가 있습니다.


? 어떤 소프트웨어 당신이 이미지를 만드는 데 사용합니까
키안 Sijianhao

1
내 데모 + 수학 쓰기 패널의 스크린 샷 (또는 이름이 번역됨) win 7 + MS Paint
Paweł Audionysos

0

죽은 사람에게서 이걸 되 찾아서 미안하지만이 게시물은 확장 가능한 공식을 만드는 데이 페이지 함께이 습니다.

기본적으로 4 개 이상의 베 지어 곡선을 사용할 수있는 매우 간단한 공식을 사용하여 가까운 원을 만들 수 있습니다. Distance = radius * stepAngle / 3

Distance베 지어 제어점과 호의 가장 가까운 끝 사이의 거리는 어디 입니까? 반경은 radius원 의 거리 입니다.stepAngle 2π / (곡선 수)로 표시되는 호의 두 끝 사이의 각도입니다.

따라서 한 번에 맞추려면 : Distance = radius * 2π / (the number of curves) / 3


1
이것은 원의 가장 근사치가 아닙니다. 가장 좋은 것은입니다 Distance = (4/3)*tan(pi/2n). 많은 수의 호의 경우 거의 동일합니다. 왜냐하면 tan(pi/2)~pi/2n예를 들어 n=4(가장 많이 사용되는 경우) 공식이 제공 Distance=0.5235...하지만 최적의 것은 Distance=0.5522... (따라서 ~ 5 % 오류가 있습니다).
Kpym

-2

해상도와 정밀도에 따라 합리적이거나 끔찍하게 보이는 무거운 근사치이지만 sqrt (2) / 2 x 반경 을 제어점으로 사용합니다. 나는 그 숫자가 어떻게 파생되는지 다소 긴 텍스트를 읽었으며 읽을 가치가 있지만 위의 공식은 빠르고 더러운 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.