15 votes

trouver les angles 0-360

J'ai besoin d'aide pour une question de mathématiques : Je dois obtenir l'angle réel à partir de 0 degré en utilisant les coordonnées x et y. J'utilise ceci pour le moment :

Math.atan((x2-x1)/(y1-y2))/(Math.PI/180)

mais /(Math.PI/180) limite les résultats de -90 à 90 j'ai besoin de 0-360

note : J'utilise l'angle pour indiquer la direction :

  • 0=haut
  • 90=Droit
  • 135=45 degrés droite+bas
  • 180=down
  • 270=gauche
  • etc.

1voto

AnvarShakhmaev Points 11
angle = Math.atan(this.k) * 180 / Math.PI;
angle = 180 - (angle < 0 ? 180 + angle : angle);
angle = p2.Y > p1.Y || (p2.Y == p1.Y && p2.X > p1.X) ? 180 + angle : angle;

1voto

Jason FB Points 141

Voici deux solutions, une avec Math.atan (qui prend une FRACTION opposée/adjacente) et une avec Math.atan2 (qui prend DEUX ARGUMENTS)

Les solutions sont écrites en syntaxe ES6 (ES2015+), ironiquement, car la question est antérieure à ce javascript.

Notez que "à droite" correspond à 0° (=0 radian) ; vers le haut correspond à 90° (= PI/2) ; vers la gauche correspond à 180° (PI), et vers le bas correspond à 270° (PI*1,5).

angleGivenCoords(coord1,coord2) {
    // given two coords {x,y}, calculate the angle in radians with
    // right being 0° (0 radians)

    if (coord1.x === coord2.x) return (coord1.y > coord2.y ? Math.PI * 0.5 : Math.PI * 1.5)
    if (coord1.y === coord2.y) return (coord1.x > coord2.x ? Math.PI : 0 )

    let opposite = coord2.x - coord1.x
    let adjacent = coord1.y - coord2.y
    let adjustor = ((coord2.x < coord1.x && coord2.y < coord1.y) || (coord2.x < coord1.x && coord2.y > coord1.y)) ?  Math.PI : 0

    let res = Math.atan(opposite/adjacent) + adjustor

    if (res < 0) { res = res + Math.PI*2  }
    return res ;
  }

maintenant avec Math.atan2. remarquez qu'avec cette solution les clauses de garde en haut (coord1.x === coord2.x, (coord1.y === coord2.y)) sont inutiles

  angleGivenCoords(coord1,coord2) {
    // given two coords {x,y}, calculate the angle in radians with
    // left being 0° (0 radians)
    let opposite = coord2.x - coord1.x
    let adjacent = coord1.y - coord2.y
    let res = Math.atan2(adjacent, opposite)
    if (res < 0) { res = res + Math.PI*2  }
    return res ;
  }

(J'ai essayé de garder les noms de variables 'opposé' et 'adjacent' par respect pour la trigonométrie).

Veuillez noter qu'il s'agit ici de ma suite de tests écrite en Jest. Notez également que la fonction ci-dessus renvoie des radians et que mon code (qui n'est pas montré ici) contient une simple Trig.degreesToRadians() comme vous pouvez vous y attendre.

 it('for right 0°', () => {
    let coord1 = {x: 500, y: 500},
      coord2 = {x: 600, y: 500}
    expect(Trig.angleGivenCoords(coord1,coord2)).toEqual(Trig.degreesToRadians(0))
  })

  it('for up-right 45°', () => {
    let coord1 = {x: 500, y: 500},
      coord2 = {x: 600, y: 400}
    expect(Trig.angleGivenCoords(coord1,coord2)).toEqual(Trig.degreesToRadians(45))
  })

  it('for 90° up', () => {
    let coord1 = {x: 500, y: 500},
      coord2 = {x: 500, y: 400}
    expect(Trig.angleGivenCoords(coord1,coord2)).toEqual(Trig.degreesToRadians(90))
  })

  it('for 135° up to left', () => {
    let coord1 = {x: 500, y: 500},
      coord2 = {x: 400, y: 400}
    expect(Trig.angleGivenCoords(coord1,coord2)).toEqual(Trig.degreesToRadians(135))
  })

  it('for 180° to left', () => {
    let coord1 = {x: 500, y: 500},
      coord2 = {x: 400, y: 500}
    expect(Trig.angleGivenCoords(coord1,coord2)).toEqual(Trig.degreesToRadians(180))
  })

  it('for 225° to to bottom left', () => {
    let coord1 = {x: 500, y: 500},
      coord2 = {x: 400, y: 600}
    expect(Trig.angleGivenCoords(coord1,coord2)).toEqual(Trig.degreesToRadians(225))
  })

  it('for 270° to the bottom', () => {
    let coord1 = {x: 500, y: 500},
      coord2 = {x: 500, y: 600}
    expect(Trig.angleGivenCoords(coord1,coord2)).toEqual(Trig.degreesToRadians(270))
  })

  it('for 315° to the bottom', () => {
    let coord1 = {x: 500, y: 500},
      coord2 = {x: 600, y: 600}
    expect(Trig.angleGivenCoords(coord1,coord2)).toEqual(Trig.degreesToRadians(315))
  })

0voto

Pour 0=haut,90=droite,180=bas,270=gauche etc (x=x2-x1,y=y2-y1)

vous pouvez utiliser la formule :

f(x,y)=180-90*(1+sign(y))* (1-sign(x^2))-45*(2+sign(y))*sign(x)

-(180/pi())*sign(x*y)*atan((abs(y)-abs(x))/(abs(y)+abs(x)))

0voto

Leventete Points 1

Donc avec une seule décision (j'espère que cette affreuse notation basique l'explique) :

SI x = 0 ALORS

360degree = 270 - (SIGN(x) + 1) * 90

ELSE

360degree = MOD(180 + (SIGN(y) + 1) * 90 + ATAN(x/y) , 360)

ENDIF

pour dessiner un cercle complet du nord de 0 degré à 360 degrés dans le sens des aiguilles d'une montre :

x=SIN(0à360) y=COS(0à360)

Merci, Lev

-1voto

syava Points 394
function angle(x1,y1,x2,y2)
{
eangle = Math.atan((x2-x1)/(y1-y2))/(Math.PI/180)
if ( angle > 0 )
{
  if (y1 < y2)
    return angle;
  else
    return 180 + angle;
} else {
  if (x1 < x2)
    return 180 + angle;
  else
    return 360 + angle;
}
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X