>  기사  >  웹 프론트엔드  >  HTML5 Canvas_html5 튜토리얼 팁에서 타원을 그리는 4가지 방법

HTML5 Canvas_html5 튜토리얼 팁에서 타원을 그리는 4가지 방법

WBOY
WBOY원래의
2016-05-16 15:47:041851검색

개요

HTML5의 캔버스는 타원을 그리는 방법을 직접 제공하지 않습니다. 다음은 여러 가지 그리기 방법을 요약한 것입니다. 각 방법에는 장단점이 있으므로 상황에 따라 선택해야 합니다. 각 메소드의 매개변수는 동일합니다:

1.context는 Canvas의 2D 그리기 환경 객체,
2.x는 타원 중심의 가로 좌표,
3.y는 타원 중심의 세로 좌표,
4.a는 타원의 가로 반축 길이,
5.b는 타원의 세로 반축 길이입니다.

모수방정식 방법

이 방법은 타원의 매개변수 방정식을 사용하여 타원을 그립니다

코드 복사
코드는 다음과 같습니다. 다음은 다음과 같습니다.

//------------파라메트릭 방정식을 사용하여 타원 그리기---------
//함수 매개변수 x와 y는 타원의 중심이고, a와 b는 각각 타원의 수평 및 수직 반축입니다.
//수직 반축의 길이는 0이 될 수 없습니다. 동시에
//이 방법의 단점은 lineWidth가 넓을 때 타원이 더 작아진다는 것입니다.
//타원 내부의 장축 끝이 더 날카롭고 매끄럽지 않으며 효율성이 떨어집니다.
function ParamEllipse(context, x, y, a, b)
{
//max는 1과 같습니다. 주축 값 a와 b 중 더 큰 값으로 나눕니다.
//i 각 사이클마다 1/max씩 증가하여 정도의 증가를 나타냅니다.
//이렇게 하면 각 사이클에서 경로(호)가 1픽셀에 가까워질 수 있습니다
var step = (a > b) ? : 1 / b;
context.beginPath();
context.moveTo(x a, y); //타원에서 왼쪽 끝점에서 그리기 시작
for (var i = 0; i < 2 * Math.PI; i = step)
{
//매개변수 방정식은 x = a * cos(i), y = b * sin(i),
//매개변수는 i입니다. , 도(라디안)를 나타냄
context.lineTo(x a * Math.cos(i), y b * Math.sin(i));
}
context.closePath();
context .스트로크();
};

균일한 압축방식

이 방법은 수학에서 균일 압축의 원리를 사용하여 원을 타원으로 균일하게 압축합니다. 이론적으로 다음 코드는 일관되지 않은 선 너비를 발생시킵니다. 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차 베지어 곡선으로 타원을 그리는 것은 실제 그림에서도 근사이고 이론으로도 근사입니다. 하지만 효율성이 높기 때문에 컴퓨터 벡터 그래픽에서 타원을 그리는 데 자주 사용되지만 구체적인 이론에 대해서는 잘 모르겠습니다. 근사화 정도는 두 제어점의 위치 선택에 달려 있습니다. 이 방법의 제어점 위치는 제가 직접 실험한 결과이며 정확도는 괜찮습니다.

코드를 복사하세요
코드는 다음과 같습니다.

//---------삼차 베지어 곡선을 사용하여 타원 1 시뮬레이션------------
//이 방법은 lineWidth가 더 넓고 타원이 더 평평할 때
//장축 끝이 더 날카롭고 매끄럽지 않은 현상도 발생합니다
function BezierEllipse1(context, x, y, a , b)
{
//핵심은 bezierCurveTo
의 두 제어점 설정입니다. //0.5와 0.6은 두 개의 핵심 계수입니다(이 함수의 실험에서 얻음)
var ox = 0.5 * a,
oy = 0.6 * b;

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에서 게시물에 대한 답변으로 변경되었으며 정확도가 높으며 타원을 그릴 때 자주 사용하는 방법이기도 합니다.

복사 코드 코드는 다음과 같습니다.
//---------삼차 베지어 곡선을 사용하여 타원 2 시뮬레이션----- -- ---
//이 방법을 사용하면 선폭이 넓어지고 타원이 평평해지면
//장축이 납작해지는 현상도 발생합니다. 끝이 더 날카롭고 부드럽지 않음
//이 방법은 이전 베지어 방법보다 정확하지만 효율성이 약간 떨어집니다
function BezierEllipse2(ctx, x, y, a, b)
{
var k = .5522848 ,
ox = a * k, // 수평 제어점 오프셋
oy = b * k // 수직 제어점 오프셋;

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% 정확도를 달성할 수 없습니다.

사실 가장 좋은 방법은 arc() scale()입니다. 캔버스 그리기 라이브러리 KineticJS는 이 방법을 사용합니다.

다른 그리기 소프트웨어에는 HTML5 캔버스와 같은 고유한 arc() scale() 메서드가 없습니다. 베지어 곡선은 일반적으로 대략적인 타원을 시뮬레이션하는 데 사용됩니다. 베지어 곡선을 사용하여 타원을 시뮬레이션하는 것과 관련하여

폴리선, 2차 또는 3차 베지어 곡선을 사용하여 타원형 호 그리기 정보를 참조할 수 있습니다.

arc() scale()은 이미 브라우저에 구현된 메소드이기 때문에 이론적 정확도가 가장 높으므로 효율성, 정확도, 사용 편의성 측면에서 최고입니다.

arc() scale()로 타원을 그린 후 context.Stroke()와 context.restore() 두 메소드가 서로 다른 순서로 호출되는데 결과가 매우 흥미로울 것입니다. 일반적으로 복원()을 먼저 수행한 다음 스트로크()를 수행해야 합니다.

데모

다음은 래스터 방식 외에 타원 함수를 그리는 여러 가지 데모입니다. 데모 코드는 다음과 같습니다.



코드 복사코드는 다음과 같습니다.







注意,要成功运行代码,需要支持HTML5的Canvas的浏览器。
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.