타원형 모양을 그리는 기본 기능이없는 것 같습니다. 또한 나는 달걀 모양을 찾고 있지 않습니다.
2 개의 베 지어 곡선으로 타원을 그릴 수 있습니까? 누군가 그것에 능숙 했습니까?
내 목적은 눈을 그리고 실제로 호를 사용하는 것입니다. 미리 감사드립니다.
해결책
따라서 scale ()은 다음 모든 모양의 크기를 변경합니다. Save ()는 이전 설정을 저장하고 복원은 크기 조정없이 새 모양을 그리는 설정을 복원하는 데 사용됩니다.
Jani 덕분에
ctx.save();
ctx.scale(0.75, 1);
ctx.beginPath();
ctx.arc(20, 21, 10, 0, Math.PI*2, false);
ctx.stroke();
ctx.closePath();
ctx.restore();
답변
업데이트 :
- 크기 조절 방법이 획 너비 모양에 영향을 줄 수 있음
- 스케일링 방법을 올바르게 수행하면 획 너비를 그대로 유지할 수 있습니다.
- canvas에는 Chrome이 이제 지원하는 타원 메서드가 있습니다.
- JSBin에 업데이트 된 테스트 추가
JSBin 테스트 예제 (비교를 위해 다른 사람의 답변을 테스트하도록 업데이트 됨)
- 베 지어-직사각형 및 너비 / 높이를 포함하는 왼쪽 상단을 기준으로 그리기
- 중심이있는 베 지어-중심 및 너비 / 높이를 기준으로 그리기
- 호 및 스케일링-원 그리기 및 스케일링을 기반으로 그리기
- Deven Kalra의 답변 참조
- 2 차 곡선-2 차로 그리기
- 테스트는 똑같이 그려지지 않는 것 같습니다. 구현 일 수 있습니다.
- 참조 oyophant의 대답을
- Canvas Ellipse-W3C 표준 ellipse () 메서드 사용
- 테스트는 똑같이 그려지지 않는 것 같습니다. 구현 일 수 있습니다.
- 참조 Loktar의 대답을
실물:
대칭 타원을 원하면 항상 반경 너비의 원을 만든 다음 원하는 높이로 크기를 조정할 수 있습니다 ( 편집 : 획 너비 모양에 영향을 미침-acdameli의 답변 참조), 타원을 완전히 제어하려면 베 지어 곡선을 사용하는 한 가지 방법이 있습니다.
<canvas id="thecanvas" width="400" height="400"></canvas>
<script>
var canvas = document.getElementById('thecanvas');
if(canvas.getContext)
{
var ctx = canvas.getContext('2d');
drawEllipse(ctx, 10, 10, 100, 60);
drawEllipseByCenter(ctx, 60,40,20,10);
}
function drawEllipseByCenter(ctx, cx, cy, w, h) {
drawEllipse(ctx, cx - w/2.0, cy - h/2.0, w, h);
}
function drawEllipse(ctx, x, y, w, h) {
var kappa = .5522848,
ox = (w / 2) * kappa, // control point offset horizontal
oy = (h / 2) * kappa, // control point offset vertical
xe = x + w, // x-end
ye = y + h, // y-end
xm = x + w / 2, // x-middle
ym = y + h / 2; // y-middle
ctx.beginPath();
ctx.moveTo(x, ym);
ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
//ctx.closePath(); // not used correctly, see comments (use to close off open path)
ctx.stroke();
}
</script>
답변
다음은 다른 솔루션의 단순화 된 버전입니다. 표준 원을 그리고 이동하고 크기를 조정 한 다음 스트로크합니다.
function ellipse(context, cx, cy, rx, ry){
context.save(); // save state
context.beginPath();
context.translate(cx-rx, cy-ry);
context.scale(rx, ry);
context.arc(1, 1, 1, 0, 2 * Math.PI, false);
context.restore(); // restore to original state
context.stroke();
}
답변
답변
베 지어 곡선 접근 방식은 단순한 타원에 적합합니다. 더 많은 제어를 위해 루프를 사용하여 x 및 y 반경 (반지름, 반경?)에 대해 다른 값으로 타원을 그릴 수 있습니다.
rotationAngle 매개 변수를 추가하면 타원이 임의의 각도로 중심을 중심으로 회전 할 수 있습니다. 루프가 실행되는 범위 (var i)를 변경하여 부분 타원을 그릴 수 있습니다.
이 방법으로 타원을 렌더링하면 선에있는 모든 점의 정확한 x, y 위치를 결정할 수 있습니다. 이것은 다른 물체의 위치가 타원의 위치와 방향에 따라 달라지는 경우에 유용합니다.
다음은 코드의 예입니다.
for (var i = 0 * Math.PI; i < 2 * Math.PI; i += 0.01 ) {
xPos = centerX - (radiusX * Math.sin(i)) * Math.sin(rotationAngle * Math.PI) + (radiusY * Math.cos(i)) * Math.cos(rotationAngle * Math.PI);
yPos = centerY + (radiusY * Math.cos(i)) * Math.sin(rotationAngle * Math.PI) + (radiusX * Math.sin(i)) * Math.cos(rotationAngle * Math.PI);
if (i == 0) {
cxt.moveTo(xPos, yPos);
} else {
cxt.lineTo(xPos, yPos);
}
}
여기에서 대화식 예제를 참조하십시오 : http://www.scienceprimer.com/draw-oval-html5-canvas
답변
타원을 안정적으로 재현하려면 4 개의 베 지어 곡선 (및 매직 넘버)이 필요합니다. 여길 봐:
www.tinaja.com/glib/ellipse4.pdf
두 베 지어는 타원을 정확하게 재현하지 못합니다. 이를 증명하기 위해 동일한 높이와 너비로 위의 두 가지 베 지어 솔루션 중 일부를 시도해보십시오. 이상적으로는 원에 가깝지만 그렇지 않습니다. 그들은 여전히 타원으로 보이며 그들이해야 할 일을하고 있지 않다는 것을 증명합니다.
다음은 작동해야하는 것입니다.
코드는 다음과 같습니다.
function ellipse(cx, cy, w, h){
var ctx = canvas.getContext('2d');
ctx.beginPath();
var lx = cx - w/2,
rx = cx + w/2,
ty = cy - h/2,
by = cy + h/2;
var magic = 0.551784;
var xmagic = magic*w/2;
var ymagic = h*magic/2;
ctx.moveTo(cx,ty);
ctx.bezierCurveTo(cx+xmagic,ty,rx,cy-ymagic,rx,cy);
ctx.bezierCurveTo(rx,cy+ymagic,cx+xmagic,by,cx,by);
ctx.bezierCurveTo(cx-xmagic,by,lx,cy+ymagic,lx,cy);
ctx.bezierCurveTo(lx,cy-ymagic,cx-xmagic,ty,cx,ty);
ctx.stroke();
}
답변
비 균일 스케일링을 사용해 볼 수도 있습니다. X 및 Y 스케일링을 제공 할 수 있으므로 X 또는 Y 스케일링을 다른 것보다 크게 설정하고 원을 그리면 타원이 생깁니다.
답변
나는 너무 일반적인 타원을 원하지 않고 더 큰 반축과 타원의 편심 데이터 만 가진 사람들 을 위해이 코드 (부분적으로 Andrew Staroscik에 의해 제시됨)를 약간 수정 했습니다 (궤도를 그리는 천문 자바 스크립트 장난감에 적합) 예를 들어).
이제 단계를 조정 i
하여 도면의 정밀도를 높일 수 있음을 기억하십시오 .
/* draw ellipse
* x0,y0 = center of the ellipse
* a = greater semi-axis
* exc = ellipse excentricity (exc = 0 for circle, 0 < exc < 1 for ellipse, exc > 1 for hyperbole)
*/
function drawEllipse(ctx, x0, y0, a, exc, lineWidth, color)
{
x0 += a * exc;
var r = a * (1 - exc*exc)/(1 + exc),
x = x0 + r,
y = y0;
ctx.beginPath();
ctx.moveTo(x, y);
var i = 0.01 * Math.PI;
var twoPi = 2 * Math.PI;
while (i < twoPi) {
r = a * (1 - exc*exc)/(1 + exc * Math.cos(i));
x = x0 + r * Math.cos(i);
y = y0 + r * Math.sin(i);
ctx.lineTo(x, y);
i += 0.01;
}
ctx.lineWidth = lineWidth;
ctx.strokeStyle = color;
ctx.closePath();
ctx.stroke();
}
