GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Como calcular os pontos de um angulo?


#1

Suponhamos que eu tenho um ponto e queria calcular o angulo dele em relação a outro
x1 = 0, y1 = 0
x2 = 10, y2 = 2
Como na imagem

Que fórmula usar?

Agora suponhamos que apareça outro ponto com o mesmo angulo em direção ao x1,y1. Como calcular o x e y desse ponto? x3, y3


#2

Primeiro de tudo. Pontos são a representação de locais no espaço. Portanto, não existe angulos entre pontos.
Você pode estar considerando o vetor formado pelo deslocamento do ponto em relação ao (0,0). Pelo seu desenho parece ser isso mesmo.

Nesse caso, o menor angulo entre dois vetores (pois existem 2 ângulos possíveis) é dado pelo arco-cosseno do produto escalar, dividido pelo produto do tamanho dos dois vetores.

angulo = arccos(a.b / ||a|||b||);
angulo = Math.acos(ax*bx+ay*by / sqr(ax*ax + ay*ay)sqrt(bxbx + by*by));

E para obter um ponto na mesma direção e sentido de um ponto qualquer, basta multiplicar x e y por um valor positivo qualquer. Se o valor for negativo, você obtém um ponto no sentido oposto.

Se você está tendo que fazer contas desse tipo, eu sugiro fortemente que você estude o conceito de vetores, e implemente uma classe que represente um vetor.

Para mais informações:
Ponto V! - O uso de vetores nos jogos


#3

Não tenho tanto conhecimento de matemática quanto o Vinícius, mas já fiz algo assim:

// verifica qual o "quadrante" que o ponto 2 (x2, y2) está
// em relação ao ponto 1 (x1, y1). O ponto 1 é tratado como a "origem" do
// sistema de coordenadas.
private static int detectarQuadrante(
        double x1, double y1,
        double x2, double y2 ) {
    if ( ( x2 > x1 && y2 > y1 ) ||
            ( x2 > x1 && y2 == y1 ) ||
            ( x2 == x1 && y2 > y1 ) ||
            ( x2 == x1 && y2 == y1 ) )
        return 1;
    if ( ( x2 < x1 && y2 > y1 ) )
        return 2;
    if ( ( x2 < x1 && y2 < y1 ) ||
            ( x2 == x1 && y2 < y1 ) ||
            ( x2 < x1 && y2 == y1 ) )
        return 3;
    return 4;
}
// dependendo do quadrante relativo, obtém
// o valor do ângulo que deve ser incrementado.
private static int gerarIncrementoAngulo(
        double x1, double y1,
        double x2, double y2 ) {
    int q = detectarQuadrante( x1, y1, x2, y2 );
    if ( q == 1 ) {
        return 0;
    } else if ( q == 2 ) {
        return 90;
    } else if ( q == 3 ) {
        return 180;
    } else {
        return 270;
    }
}
// obtém o grau relativo entre o ponto 1 e o ponto 2
public static double obtemGrauRelativo(
        double x1, double y1,
        double x2, double y2 ) {
    double x = 0;
    double y = 0;
    if ( x2 > x1 )
        x = x2 - x1;
    else
        x = x1 - x2;
    if ( y2 > y1 )
        y = y2 - y1;
    else
        y = y1 - y2;
    return gerarIncrementoAngulo( x1, y1, x2, y2 ) +
            Math.toDegrees( Math.atan2( y, x ) );
}

Todo esse código pode ser melhorado e como já disse não tenho tanto conhecimento quanto o Vini.
Note que um dos pontos é sempre tratado como a "origem" do sistema de coordenadas para calcular o ângulo.
Não é a forma mais inteligente de se fazer, mas para o que você precisa (se é que eu entendi direito), vai ajudar.

Faltou falar, o retorno do ângulo é em grau.

[]´s




#4

Sim, sempre que falamos em ângulos, estamos falando em pelo menos dois segmentos de retas.

Dois segmentos de retas também tem sempre dois ângulos possíveis.
Um ângulo x, menor. E um angulo y, maior, que vale 360-x graus. É o ângulo complementar.

Eu realmente aconselho criar uma classe de vetores, ou usar a que eu já tenho no artigo, que postei para você.
Muitos calculos matemáticos ficam simplesmente triviais com ela.


#5

Você disse aqui:
E para obter um ponto na mesma direção e sentido de um ponto qualquer, basta multiplicar x e y por um valor positivo qualquer. Se o valor for negativo, você obtém um ponto no sentido oposto.

Se eu tenho um ponto na posição x = 3000 e y = 3000. Se eu quiser adicionar um ponto a frente, é só eu multiplicar esses valores.

Se eu multiplicar isso ai por 1,1 eu recebo 3300 em x e 3300 em y.
Só que isso é um ponto muito longe do original.
Porem, se eu tivesse x,y = 10,10 e multiplicasse por 1,1 ia ter
x,y = 11,11
Esse ponto criado está de bom tamanho.
Vou ter que fazer uma funcao pra colocar um ponto numa distancia padrão então?

Quero que a distancia entre os pontos criados seja de 5.
Multiplicar por 1,1 nao ia funcionar se a coordenada fosse 3000 ou 10.

Alguma dica?

-------------- EDITADO --------------

Fiz algo assim

QTDAFRENTE = 5;
x = 3000
y = 286

x *= calculaPontoFixo(x) / 100;
y *= calculaPontoFixo(y) / 100;

calculaPontoFixo(ponto) {
resultado;
novoPonto = ponto + QTDAFRENTE;
resultado = novoPonto * 100 / ponto;
return resultado;
}

Consegui o que eu queria.

Eu queria colocar um ponto sempre a frente do outro de tantos em tantos pixels por exemplo, dai essa função funcionou no papel, agora vo pro java.

---------------- EDITADO EDITADO -------------------

¬¬
Na verdade eu to tentando descobrir pela porcentagem q eu tenho q multiplicar
Ou Seja essa função INUTIL QUE EU FIZ, no fim sempre me retorna o x + QTDAFRENTE

AIUAHIUAHIAUHAIU




#6

A dica que eu te dou é ler o artigo de vetores que eu te passei.

Para deixar numa distância de 5 de um vetor com outro, usando as classes que te passei, você varia assim:

Vector2D ponto1 = new Vector2D(3000, 3000);
Vector2D distancia = new Vector2D(ponto1);
distancia.normalize().multiplyMe(5);
Vector2D ponto2 = ponto1.add(distancia);

Sem gambi.

Do jeito que você está fazendo, você está forçando o cálculo e olhando para o resultado final. Isso pode parecer dar certo, mas pode ser um desastre para novos conjuntos de valores de x e y, pois isso criará um vetor com nova inclinação.
O ideal é estudar um pouquinho da teoria de vetores, pois ela deixa trivial problemas desse tipo:

a) Achar pontos colineares (o que você está fazendo);
b) Calcular a trajetória entre dois pontos (direção e distância);
c) Calcular o ângulo entre dois vetores, ou entre o vetor e o eixo x;
d) Girar pontos;
e) Calcular posições relativas de objetos;

Vetores ainda podem ser aplicados com facilidade para modelar situações físicas (trajetória de bola, força de jatos), podem ser usados para testes de campo de visão, ou para fazer desenho mesmo.


#7