Explicação Método Math atan2

Pessoal…
preciso de uma breve explicação:
graças ao usuário entanglement, consegui o código abaixo, que retorna o ângulo da tangente de 3 vértices de uma imagem (triângulo).
Devo passar o valor das coordenadas (x,y) de cada vértices do triângulo , ou seja, 3 vértices, como parametros…
Só não entendi, onde insiro esses parametros… fiz uns testes mas deu valor negativo. Gostaria de uma explicação como funciona o código, ou onde devo informar as coordenadas (x,y)?

class Ponto {   
    public double x;   
    public double y;   
    public Ponto (double x, double y) { this.x = x; this.y = y; }   
}   
  
class Angulos {   
  
    public static double calcularAngulo (Ponto p1, Ponto p2, Ponto p3) {   
        Ponto p1t = new Ponto (p1.x - p2.x, p1.y - p2.y);   
        Ponto p3t = new Ponto (p3.x - p2.x, p3.y - p2.y);   
    double alfa = Math.atan2 (p1t.y, p1t.x);   
        double beta = Math.atan2 (p3t.y, p3t.x);   
        return alfa - beta;   
    }   
    public static double[] calcularAngulos (Ponto... pontos) {   
        if (pontos.length < 3) {   
            return new double[0];   
        }   
        double[] angulos = new double[pontos.length];   
        int i;   
        for (i = 0; i < pontos.length - 2; ++i) {   
            angulos[i] = calcularAngulo (pontos[i], pontos[i+1], pontos[i+2]);   
        }   
        angulos[i] = calcularAngulo (pontos[i], pontos[i+1], pontos[0]);   
        i++;   
        angulos[i] = calcularAngulo (pontos[i], pontos[0], pontos[1]);   
        return angulos;   
    }   
  
    public static void main (String[] args) {   
        double[] angulos = calcularAngulos (new Ponto (0, 0), new Ponto (1, 0), new Ponto (0.5, Math.sqrt   
  
(3.0) / 2));   
        for (int i = 0; i < angulos.length; ++i) {   
             System.out.printf ("%.2f graus %n", Math.toDegrees (angulos[i]));   
        }   
    }   
}  

class Ponto {
    public double x;
    public double y;
    public Ponto (double x, double y) { this.x = x; this.y = y; }
}

class Angulos {
 
    public static double calcularAngulo (Ponto p1, Ponto p2, Ponto p3) {
        Ponto p1t = new Ponto (p1.x - p2.x, p1.y - p2.y);
        Ponto p3t = new Ponto (p3.x - p2.x, p3.y - p2.y);
	double alfa = Math.atan2 (p1t.y, p1t.x);
        double beta = Math.atan2 (p3t.y, p3t.x);
        return alfa - beta;
    }
    public static double[] calcularAngulos (Ponto... pontos) {
        if (pontos.length < 3) {
            return new double[0];
        }
        double[] angulos = new double[pontos.length];
        int i;
        for (i = 0; i < pontos.length - 2; ++i) {
            angulos[i] = calcularAngulo (pontos[i], pontos[i+1], pontos[i+2]);
        }
        angulos[i] = calcularAngulo (pontos[i], pontos[i+1], pontos[0]);
        i++;
        angulos[i] = calcularAngulo (pontos[i], pontos[0], pontos[1]);
        return angulos;
    }

    public static void main (String[] args) {
        double[] angulos = calcularAngulos (new Ponto (0, 0), new Ponto (1, 0), new Ponto (0.5, Math.sqrt 

(3.0) / 2));
        for (int i = 0; i < angulos.length; ++i) {
             System.out.printf ("%.2f graus %n", Math.toDegrees (angulos[i]));
        }
    }
}

Pode ser que o ângulo dê valor negativo porque os pontos tenham sido entrados em uma determinada ordem; se você inverter a ordem dos pontos, o ângulo que era contado em um determinado sentido (horário ou anti-horário) será contado no sentido contrário e ficará com o valor positivo, em vez de negativo.

Para simplificar: pegue os valores retornados por esse método, e pegue o valor absoluto (Math.abs).

Ai você não vai ter ângulos negativos.

Dica: ler a documentação não machuca ninguém, assim como revirar seus livros de trigonometria e geometria analítica.

Math.atan2

[quote=bezier curve]Pode ser que o ângulo dê valor negativo porque os pontos tenham sido entrados em uma determinada ordem; se você inverter a ordem dos pontos, o ângulo que era contado em um determinado sentido (horário ou anti-horário) será contado no sentido contrário e ficará com o valor positivo, em vez de negativo.

Para simplificar: pegue os valores retornados por esse método, e pegue o valor absoluto (Math.abs).

Ai você não vai ter ângulos negativos.

Dica: ler a documentação não machuca ninguém, assim como revirar seus livros de trigonometria e geometria analítica.

Math.atan2[/quote]

bezier curve, realmente, documentação e livros, ajudam e muito, inclusive já li uma pá deles… até pelo fato que descobri que podem existir valor negativos… isso irá depender de qual quadrante a tangente esta tocando… o angulo será negativo…
só que ainda não consegui entender como o código funciona…
se tivessem os comentarios das linhas do código seria mais fácil entender…
certo?

// Classe Ponto. Apenas armazena coordenadas X e Y.
class Ponto {   
    public double x;   
    public double y;   
    public Ponto (double x, double y) { this.x = x; this.y = y; }   
}   

// Classe Angulos. Provê métodos de cálculos de ângulos.
class Angulos {   
    // Método calcularAngulo. Calcula ângulo entre 3 pontos. Se p1 for chamado de "A", p2 for chamado de "O" e
    // p3 for chamado de "B", então estamos calculando o ângulo AÔB.
    public static double calcularAngulo (Ponto p1, Ponto p2, Ponto p3) {   
        Ponto p1t = new Ponto (p1.x - p2.x, p1.y - p2.y); // Vetor p1t indo de P2 até P1
        Ponto p3t = new Ponto (p3.x - p2.x, p3.y - p2.y); // Vetor p3t indo de P2 até P3
        double alfa = Math.atan2 (p1t.y, p1t.x); // Ângulo de p1t em relação ao eixo das abcissas
        double beta = Math.atan2 (p3t.y, p3t.x); // Ângulo de p3t em relação ao eixo das abcissas
        return alfa - beta;                      // Ângulo de p1t em relação à p3t
    }

    // Método calularAngulos. Calcula todos os ângulos de um polígono formado por uma sequencia de pontos.
    public static double[] calcularAngulos (Ponto... pontos) {
        // Só existem polígonos a partir de 3 pontos (triângulo, quadrilátero, pentágono,...),
        // não tem um "diângulo", por exemplo
        if (pontos.length < 3) {   
            return new double[0];   
        }
        // O polígono que tem n lados tem n ângulos
        double[] angulos = new double[pontos.length];   
        int i;
        // Primeiro vamos calcular até n-2 ângulos pois podemos generalizar a fórmula para pegarmos 3 pontos em
        // sequencia no array
        for (i = 0; i < pontos.length - 2; ++i) {
            angulos[i] = calcularAngulo (pontos[i], pontos[i+1], pontos[i+2]);   
        }
        // Os 2 últimos ângulos são casos em que devemos fornecer os índices para ser calculado certo.
        angulos[i] = calcularAngulo (pontos[i], pontos[i+1], pontos[0]); // Penúltimo, último e PRIMEIRO
        i++;
        angulos[i] = calcularAngulo (pontos[i], pontos[0], pontos[1]);  // Último, PRIMEIRO e SEGUNDO
        return angulos;   
    }
  
    // Programa para testar as classes Ponto e Angulo
    public static void main (String[] args) {
        double[] angulos = calcularAngulos (new Ponto (0, 0), new Ponto (1, 0), new Ponto (0.5, Math.sqrt(3.0) / 2));   
        for (int i = 0; i < angulos.length; ++i) {
             System.out.printf ("%.2f graus %n", Math.toDegrees (angulos[i]));   
        }   
    }   
}  

[quote=alexandrehdk] // Classe Ponto. Apenas armazena coordenadas X e Y. //... // [/quote]

muito obrigado alexandrehdk, era disso que eu precisa para entender melhor o código…
só uma dúvida:
eu tendo o valor dos vértices de um sistema de coordenada (x,y) de um triângulo, no caso os 3 pontos de cada vértice em relaçao a o plano carteziano x,y
Esses parametros… para eu chegar ao valor do ângulo de cada vértice eu passo os parametros para a seguinte linha???

double[] angulos = calcularAngulos (new Ponto (0, 0), new Ponto (1, 0), new Ponto (0.5, Math.sqrt(3.0) / 2));

é isso???
não entendi bem isso pq foi utilizado uma raiz apenas em um ponto: new Ponto (0.5, Math.sqrt(3.0) / 2), por isso não sei se é o local certo para passagem de parametros.

Nessa linha de invocação do método calcularAngulos você está passando 3 pontos, que são instanciados pouco antes de serem usados. Um nas coordenadas (0,0), outro nas coordenadas (0,1) e outro nas coordenadas (0.5, (raiz de 3)/2). Você poderia fazer algo assim (dá no mesmo):

Ponto ponto1 = new Ponto(0, 0);
Ponto ponto2 = new Ponto(1, 0);
Ponto ponto3 = new Ponto(0.5, Math.sqrt(3.0) / 2);
double[] angulos = calcularAngulos(ponto1, ponto2, ponto3);

Obs: Pelo jeito do código, os valores calculados de ângulos que ficarão no array angulos são:
angulos[0] = ângulo do ponto2
angulos[1] = ângulo do ponto3
angulos[2] = ângulo do ponto1