개요
HTML5의 캔버스는 타원을 그리는 방법을 직접 제공하지 않습니다. 다음은 여러 가지 그리기 방법을 요약한 것입니다. 각 방법에는 장단점이 있으므로 상황에 따라 선택해야 합니다. 각 메소드의 매개변수는 동일합니다:
1.context는 Canvas의 2D 그리기 환경 객체,
2.x는 타원 중심의 가로 좌표,
3.y는 타원 중심의 세로 좌표,
4.a는 타원의 가로 반축 길이,
5.b는 타원의 세로 반축 길이입니다.
모수방정식 방법
이 방법은 타원의 매개변수 방정식을 사용하여 타원을 그립니다
균일한 압축방식
이 방법은 수학에서 균일 압축의 원리를 사용하여 원을 타원으로 균일하게 압축합니다. 이론적으로 다음 코드는 일관되지 않은 선 너비를 발생시킵니다. 5일의 Simonleung 댓글을 참조하세요. 바닥. .
//------------타원을 그리는 균일한 압축 방법---------
//The method 원호법은 원을 그리는 데 사용되며
의 스케일과 결합됩니다. //가로 또는 세로 축 방향의 스케일(균일 압축)
//이 방법으로 그리는 타원의 가장자리는 두꺼울수록 두꺼워집니다. 장축의 끝부분에 가까울수록 장축 끝점의 선 너비는 정상 값입니다
//가장자리가 단축에 가까울수록 타원은 더 평평하고 얇아지며 균일해집니다. 이것이 스케일의 결과입니다
//이러한 단점은 고리(행성 후광)의 3차원 효과를 표현할 때
//매개변수 a의 경우와 같이 때로는 장점이 됩니다. 또는 b가 0이면 이 방법을 적용할 수 없습니다
function EvenCompEllipse(context, x, y, a, b)
{
context.save();
//a와 a 중 더 큰 것을 선택합니다. b를 원호 방법의 반경 매개변수로 사용
var r = (a > b) ? a : b
var ratioX = a / r; //가로 축 배율 비율
var ratioY = b; r; //세로축 배율
context.scale(ratioX, ratioY); //배율(균일 압축)
context.beginPath();
//타원의 왼쪽 끝점에서 시계 반대 방향으로 그립니다.
context.moveTo((x a) / ratioX, y / ratioY);
context.arc(x / ratioX , y / ratioY, r, 0, 2 * Math.PI);
context.closePath ();
context.Stroke();
context.restore();
};
3차 베지어 곡선 방법 1
3차 베지어 곡선으로 타원을 그리는 것은 실제 그림에서도 근사이고 이론으로도 근사입니다. 하지만 효율성이 높기 때문에 컴퓨터 벡터 그래픽에서 타원을 그리는 데 자주 사용되지만 구체적인 이론에 대해서는 잘 모르겠습니다. 근사화 정도는 두 제어점의 위치 선택에 달려 있습니다. 이 방법의 제어점 위치는 제가 직접 실험한 결과이며 정확도는 괜찮습니다.
context.save();
context.translate(x, y);
context.beginPath();
//타원의 세로축 하단부터 시계 반대 방향으로 그립니다.
context .moveTo(0, b);
context.bezierCurveTo(ox, b, a, oy, a, 0);
context.bezierCurveTo(a, -oy, ox, -b, 0 , -b) ;
context.bezierCurveTo(-ox, -b, -a, -oy, -a, 0);
context.bezierCurveTo(-a, oy, -ox, b, 0, b );
context.closePath();
context.Stroke();
context.restore();
};
3차 베지어 곡선 방법 2
이 방법은 StackOverFlow에서 게시물에 대한 답변으로 변경되었으며 정확도가 높으며 타원을 그릴 때 자주 사용하는 방법이기도 합니다.
ctx.beginPath();
//타원의 왼쪽 끝점에서 시작하여 시계 방향으로 4개의 3차 베지어 곡선을 그립니다.
ctx.moveTo(x - a, y);
ctx.bezierCurveTo ( x - a, y - oy, x - ox, y - b, x, y - b);
ctx.bezierCurveTo(x ox, y - b, x a, y - oy, x a, y);
ctx.bezierCurveTo(x a, y oy, x ox, y b, x, y b);
ctx.bezierCurveTo(x - ox, y b, x - a, y oy, x - a, y);
ctx.closePath();
ctx.Stroke();
};
래스터 방식
이 방법은 픽셀을 연산할 수 있는 캔버스의 특성을 바탕으로 그래픽의 기본 알고리즘을 사용하여 타원을 그릴 수 있는 방법입니다. 예를 들어 중간점 타원 그리기 알고리즘 등이 있습니다.한 가지 예는 정원 친구 "Doudou Gou"의 블로그 게시물 "HTML5 Canvas Improvement Class (1) - Raster Graphics (1) Midpoint Circle Drawing Algorithm"입니다. 이 방법은 비교적 "독창적"이며 뛰어난 유연성, 고효율 및 높은 정확도를 가지고 있지만 타원을 그리는 데 유용한 기능을 구현하는 것은 상대적으로 복잡합니다. 예를 들어 선 너비가 변경되면 알고리즘이 더 복잡해집니다. 원을 그리는 알고리즘이지만 타원을 그리는 알고리즘은 아래에서 참고할 수 있습니다.
요약
기본적으로 모든 방법은 디스플레이 해상도에 따라 제한되기 때문에 100% 정확도를 달성할 수 없습니다.
다른 그리기 소프트웨어에는 HTML5 캔버스와 같은 고유한 arc() scale() 메서드가 없습니다. 베지어 곡선은 일반적으로 대략적인 타원을 시뮬레이션하는 데 사용됩니다. 베지어 곡선을 사용하여 타원을 시뮬레이션하는 것과 관련하여
폴리선, 2차 또는 3차 베지어 곡선을 사용하여 타원형 호 그리기 정보를 참조할 수 있습니다.
arc() scale()은 이미 브라우저에 구현된 메소드이기 때문에 이론적 정확도가 가장 높으므로 효율성, 정확도, 사용 편의성 측면에서 최고입니다.arc() scale()로 타원을 그린 후 context.Stroke()와 context.restore() 두 메소드가 서로 다른 순서로 호출되는데 결과가 매우 흥미로울 것입니다. 일반적으로 복원()을 먼저 수행한 다음 스트로크()를 수행해야 합니다.
데모
다음은 래스터 방식 외에 타원 함수를 그리는 여러 가지 데모입니다. 데모 코드는 다음과 같습니다.