Programing

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

lottogame 2020. 9. 23. 08:04
반응형

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


시작점 (x, y)과 원 반경이 있습니다. 베 지어 곡선 점에서 경로를 생성 할 수있는 엔진도 있습니다.

베 지어 곡선을 사용하여 원을 어떻게 만들 수 있습니까?


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

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

n 세그먼트에 대한 공식

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

4 점 케이스


comp.graphics.faq에 포함됨

발췌 :

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

흥미롭게도 베 지어 곡선은 원에 가깝지만 원에 완벽하게 맞지는 않습니다. 일반적인 근사치는 4 개의 베 지어를 사용하여 원을 모델링하는 것입니다. 각각 제어점은 끝점 (여기서 r은 원 반경)에서 거리 d = r * 4 * (sqrt (2) -1) / 3이고 끝점에서 원에 접하는 방향. 이렇게하면 베 지어의 중간 점이 원 위에 있고 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 엔진은 다른 그리기 방법을 사용할 수 있습니다.

기타 플랫폼

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


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

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

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

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

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

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

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


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

To do this, you have to divide your circle in n-tants (e.g.quadrants, octants). For each n-tant, you use the first and last point as the first and last of the Bezier curve. The Bezier polygon requires two additional points. To be fast, I would take the tangents to the circle for each extreme point of the n-tant and choose the two points as the intersection of the two tangents (so that basically your Bezier polygon is a triangle). Increase the number of n-tants to fit your precision.


The other answers have covered the fact that a true circle is not possible. This SVG file is an approximation using Quadratic Bezier curves, and is the closest thing you can get: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg

Here's one with Cubic Bezier curves: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg


Many answers already but I found a small online article with a very good cubic bezier approximation of a circle. In terms of unit circle c = 0.55191502449 where c is the distance from the axis intercept points along the tangents to the control points.

As a single quadrant for the unit circle with the two middle coordinates being the control points. (0,1),(c,1),(1,c),(1,0)

The radial error is just 0.019608% so I just had to add it to this list of answers.

The article can be found here Approximate a circle with cubic Bézier curves


To people who are just looking for code:

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>

This allows to draw circle that is made out of 4 Bezier curves. Written in JS but can easily be translated to any other language


I'm not sure if i should open new question since this is about aproximation but I'm interested in general formula to get control points for Bezier of any degree and I believe it fits within this question. All solutions I found on the web are only for cubic curves or are paid or I don't even understand (I'm not very good at math). So I decided try to solve this on my own. I was study distance of the control point from center of a circle dependent on given angle and so far I found that:

여기에 이미지 설명 입력

Where N is number of control points for single curve and α is circle arc angle.

For quadratic curve it can be simplified to l ≈ r + r * PI*0.1 * pow(α/90, 2) The PI*0.1 is rather a guess - I didn't calculate perfect value but it's pretty close. This works reasonably good for curve with 1-2 control points giving radius error about 0.2% for cubic curve. For higher degree curves loss of accuracy is noticable. With 3 control points curve look similar to quadratic so obviously I'm miss something but I can't figure it out and this method generally fits my needs for now. Here is demo.


Sorry to bring this one back from the dead, but I found this post very helpful along with this page in coming up with an expandable formula.

Basically, you can create a near circle using an incredibly simple formula that allows you to use any number of Bezier curves over 4: Distance = radius * stepAngle / 3

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

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


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

참고 URL : https://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%c3%a9zier-curves

반응형