#include "circulo.H"

#include <cmath>

#include "util.H"

/* Desenha o círculo compensando píxeis com relação largura/altura
   quadro.aspecto() do quadro quadro.  É uma implementação naïve.  Ver bons
   livros de computação gráfica para melhores métodos. */
void Circulo::desenhaEm(Quadro& quadro) const 
{
    // Posição do círculo:
    int l = posicao().linha();
    int c = posicao().coluna();
    double aspecto = quadro.aspecto();

    if(aspecto <= 1.0) {
        // Tamanho do ciclo de colunas para meio semi-círculo:
        int meio = arredonda<int>(raio() /
                                  sqrt(quadrado(aspecto) + 1));
        // Ciclo de colunas ("quartos" de círculo superior e inferior):
        for(int i = - meio; i != meio + 1; ++i) {
            Posicao ps(l - arredonda<int>(aspecto * sqrt(quadrado(raio())
                                                         - quadrado(i))),
                       c + i);
            quadro.pinta(ps);
            Posicao pi(l + arredonda<int>(aspecto * sqrt(quadrado(raio())
                                                         - quadrado(i))),
                       c + i);
            quadro.pinta(pi);
        }
        // Ciclo de linhas ("quartos" de círculo esquerdo e direito):
        for(int i = - arredonda<int>(aspecto * meio);
            i != arredonda<int>(aspecto * meio) + 1; ++i) {
            Posicao pe(l + i,
                       c - arredonda<int>(sqrt(quadrado(raio()) -
                                               quadrado(i / aspecto))));
            quadro.pinta(pe);
            Posicao pd(l + i,
                       c + arredonda<int>(sqrt(quadrado(raio()) -
                                               quadrado(i / aspecto))));
            quadro.pinta(pd);
        }
    } else {
        // Tamanho do ciclo de linhas para meio semi-círculo:
        int meio = arredonda<int>(raio() * quadrado(aspecto) /
                                  sqrt(quadrado(aspecto) + 1));
        // Ciclo de linhas ("quartos" de círculo esquerdo e direito):
        for(int i = - meio; i != meio + 1; ++i) {
            Posicao pe(l + i,
                       c - arredonda<int>(sqrt(quadrado(raio())
                                               - quadrado(i / aspecto))));
            quadro.pinta(pe);
            Posicao pd(l + i,
                       c + arredonda<int>(sqrt(quadrado(raio())
                                               - quadrado(i / aspecto))));
            quadro.pinta(pd);
        }
        // Ciclo de colunas ("quartos" de círculo superior e inferior):
        for(int i = - arredonda<int>(meio / aspecto);
            i != arredonda<int>(meio / aspecto) + 1; ++i) {
            Posicao ps(l - arredonda<int>(aspecto*sqrt(quadrado(raio())
                                                       - quadrado(i))),
                       c + i);
            quadro.pinta(ps);
            Posicao pi(l + arredonda<int>(aspecto*sqrt(quadrado(raio())
                                                       - quadrado(i))),
                       c + i);
            quadro.pinta(pi);
        }
    }
}