Na tela, você pode facilmente desenhar um círculo usando o método ARC. Originalmente, o círculo também pode ser considerado uma elipse com igual largura e altura, mas não há como desenhar uma elipse em tela. Precisamos usar outros métodos para simulá -lo.
Primeiro de tudo, precisamos esclarecer os parâmetros necessários para desenhar uma elipse. O conhecimento geométrico básico nos diz que a elipse precisa das coordenadas centrais, largura, altura ou ângulo de rotação, mas isso pode ser evitado por enquanto, a rotação é relativamente fácil.
1. Use Lineto para desenhar uma elipse Você lê isso certo, Lineto, um método que é puramente usado para desenhar linhas retas, pode ser usado para desenhar elipses! ? Mas ele existe, mas o estilo de escrita é realmente incrível:função drawellipse (tela, o, oa, ob) {
// desenhe uma elipse, exemplo: var = nova matriz (150.150); Drawellipse (HB, b, 50,30);
com (tela) {
var x = o [0]+oa;
var y = O [1];
moveto (x, y);
for (var i = 0; i <= 360; i ++) {
var ii = i*math.pi/180;
var x = o [0]+oa*math.cos (ii);
var y = o [1] -ob*math.sin (ii);
lineto (x, y);
}
}
}
O princípio deste método é que um círculo possui 360 graus; portanto, use Lineto para fazer 260 vezes, desenhe os segmentos de linha de cada grau e, finalmente, conecte -os a uma elipse. Entre eles, a função trigonométrica cosseno senoidal precisa ser usada para cálculo.
Observe que o segundo parâmetro deste método é uma matriz, ou seja, as coordenadas centrais da elipse.
A idéia é muito estranha, e a elipse desenhada é relativamente suave. Mas não vale a pena usar - esse método requer 360 ciclos para cada elipse desenhado. Somente quando a elipse é desenhada é o menor teste do desempenho do navegador.
Nós só precisamos entender suas idéias
2. Use o arco para desenhar um círculo e escalar -o para uma elipse O texto original deste método está aqui, e a função principal é a seguinte:var canvas = document.getElementById ('mycanvas');
var context = Canvas.getContext ('2D');
var Centerx = 0;
var Centery = 0;
VAR raio = 50;
// Salvar estado
context.Save ();
// traduzir contexto
context.Translate (Canvas.width / 2, Canvas.Height / 2);
// escala de contexto horizontalmente
Context.Scale (2, 1);
// Desenhe um círculo que será esticado em um oval
context.BeginPath ();
Context.arc (Centerx, Centery, Radius, 0, 2 * Math.Pi, False);
// restaurar ao estado original
context.restore ()
Este método usa uma função de tela que eu não mencionei antes, ou seja, escala, que pode realizar o escala de tela. A escala tem duas direções: horizontal e vertical. O código aumenta a direção horizontal da tela, enquanto a direção vertical permanece inalterada. Então, o círculo desenhado pelo arco se transforma em uma elipse.
Esse método é muito maravilhoso à primeira vista, com poucos códigos, e os princípios são simples e fáceis de entender. Mas depois de analisá -lo, você encontrará suas óbvias deficiências, ou seja, é - impreciso! Por exemplo, preciso de uma elipse com 171 de largura e 56 de alta. Se definirmos o raio do arco para 28, o número subsequente de 171/28/2 será deprimido.
No entanto, existe um método de compromisso para sempre definir o raio do arco como 100 e, se não for suficiente, será aumentado e, se exceder, será reduzido. No entanto, ainda é impreciso.
3. Use Bezier Curveto Como senti que o método de escala acima é impreciso, eu realmente quero encontrar um método exato para desenhar elipses e finalmente o encontrei no StackOverflow:função drawellipse (ctx, x, y, w, h) {
var kappa = 0,5522848;
Ox = (W / 2) * Kappa, // Ponto de controle Horizontal Offset
oy = (h / 2) * kappa, // Offset vertical do ponto de controle
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 + box, ye, xm, ye);
ctx.beziercurveto (xm - ox, ye, x, ym + oy, x, ym);
ctx.closePath ();
ctx.stroke ();
}
Este método pode ser considerado perfeito. Ele dividiu uma elipse em 4 curvas bezier e as conectou a uma elipse. A largura e a altura final também são relativamente precisas e a sobrecarga é menor.
Mas esse método ainda tem suas desvantagens. Todo mundo olha para o parâmetro Kappa, e há um valor muito estranho. Acredito que muitas pessoas não entendem por que precisam aceitar esse valor antes que o especialista em geometria diga por que eles querem assumir esse valor - ainda não sei. E eu tinha um forte desejo de mudá -lo e ver quais foram as consequências.
Obviamente, meu impulso semelhante a pacientes com transtorno obsessivo-compulsivo não pode ser considerado como a desvantagem desse método. Sua verdadeira desvantagem é - por que você precisa usar 4 curvas bezier? Pessoalmente, acho que uma elipse é obviamente composta por duas curvas bezier, em vez de quatro. Essa idéia acabou me levando a encontrar a maneira mais perfeita de desenhar uma elipse.
4. Use duas curvas besel para desenhar uma elipse
Para entender se o método anterior pode ser simplificado, registrei especialmente uma conta de Stackoverflow para fazer perguntas. Como há fotos na pergunta, os pontos não podem ser transmitidos. Eu tive que usar minha proficiência em inglês apenas para responder às perguntas dos estrangeiros para ganhar pontos. Mas, no final, a boa sorte veio e responder a uma pergunta resolveu meu problema de pontos.
Eu levantei o problema do relacionamento entre a curva Besel e a Ellipse.
Para ser sincero, eu não entendi a maioria das respostas dos estrangeiros abaixo, mas felizmente ele forneceu uma página de amostra de código, o que me fez entender o princípio, e gostaria de agradecê -lo novamente. De acordo com a resposta dele, o método que encontrei para desenhar elipses é o seguinte:
//oval
CanvasRanderingContext2d.prototype.oval = função (x, y, largura, altura) {
var k = (largura/0,75)/2,
W = largura/2,
h = altura/2;
this.BeginPath ();
this.moveto (x, yh);
this.beziercurveto (x+k, yh, x+k, y+h, x, y+h);
this.beziercurveto (xk, y+h, xk, yh, x, yh);
this.ClosePath ();
devolver isso;
}
Este método é preciso e tem pouco código, e não há estranho e difícil de entender. Lembre -se disso, a proporção de coordenadas da largura da elipse para o ponto de controle da curva Besel que desenha a elipse é a seguinte:
O ponto de controle de Bessel x = (largura de elipse/0,75)/2 já está refletido no código.
Você pode testar os quatro métodos acima para desenhar uma elipse.
Se você encontrar uma maneira mais fácil, compartilhe -o e discuta.