Dado un ángulo y dimensiones, encontrar una coordenada a lo largo del perímetro de un rectángulo

StackOverflow https://stackoverflow.com/questions/1026763

  •  06-07-2019
  •  | 
  •  

Pregunta

Estoy escribiendo un guión donde los iconos de girar alrededor de un determinado eje (o de origen).He sido capaz de hacer este trabajo para la rotación de los iconos alrededor de una elipse, pero también quiero que se muevan alrededor del perímetro de un rectángulo de una cierta anchura, la altura y el origen.

Estoy haciendo de esta manera porque mi actual código de tiendas de todas las coordenadas en un array con cada uno de los ángulos entero como la clave, y la reutilización de este código sería mucho más fácil trabajar con.

Si alguien me podría dar un ejemplo de un 100x150 rectángulo, eso sería genial.

EDITAR: para aclarar, rotando me refiero a mover alrededor del perímetro (o en órbita) de una forma.

¿Fue útil?

Solución

Que usted sabe el tamaño del rectángulo y usted tiene que dividir el ángulo completo de intervalo en cuatro diferentes, para saber si un rayo desde el centro del rectángulo se cruza a la derecha, arriba, izquierda o en la parte inferior del rectángulo.

Si el ángulo es:-atan(d/w) < alfa < atan(d/w) el rayo cruza el lado derecho del rectángulo.A continuación, ya que saben que el x-desplazamiento desde el centro del rectángulo, el lado derecho es d/2, el desplazamiento dy dividido por d/2 es tan(alfa), por lo que

dy = d/2 * tan(alfa)

Manejaría esta al igual con los otros tres intervalos de ángulo.

Ok, aquí va.Usted tiene un rectángulo con ancho w y profundidad d.En el medio tiene el punto del centro, cp.Supongo que usted quiere para calcular P, para diferentes valores del ángulo alfa.

alt text

He dividido el rectángulo en cuatro áreas diferentes, o el ángulo de los intervalos (1 a 4).El intervalo que he mencionado anteriormente es la primera a la derecha.Espero que esto tenga sentido para usted.

En primer lugar usted necesita para calcular el ángulo de intervalos, estos se determina completamente por w y d. Dependiendo de lo que el valor de alfa tiene, calcular P en consecuencia, es decir,si el "rayo" de CP a P cruza la parte superior, inferior, derecha o a la izquierda del rectángulo.

Saludos

Otros consejos

Esto fue hecho y verificado para funcionar en el reloj inteligente Pebble, pero modificado para ser pseudocódigo:

struct GPoint {
  int x;
  int y;
}

// Return point on rectangle edge.  Rectangle is centered on (0,0) and has a width of w and height of h
GPoint getPointOnRect(int angle, int w, int h) {
  var sine = sin(angle), cosine = cos(angle);   // Calculate once and store, to make quicker and cleaner
  var dy = sin>0 ? h/2 : h/-2;                  // Distance to top or bottom edge (from center)
  var dx = cos>0 ? w/2 : w/-2;                  // Distance to left or right edge (from center)
  if(abs(dx*sine) < abs(dy*cosine)) {           // if (distance to vertical line) < (distance to horizontal line)
    dy = (dx * sine) / cosine;                  // calculate distance to vertical line
  } else {                                      // else: (distance to top or bottom edge) < (distance to left or right edge)
    dx = (dy * cosine) / sine;                  // move to top or bottom line
  }
  return GPoint(dx, dy);                        // Return point on rectangle edge
}


Use:
rectangle_width  = 100;
rectangle_height = 150;
rectangle_center_x = 300;
rectangle_center_y = 300;
draw_rect(rectangle_center_x - (rectangle_width/2), rectangle_center_y - (rectangle_center_h/2), rectangle_width, rectangle_height);
GPoint point = getPointOnRect(angle, rectangle_width, rectangle_height);
point.x += rectangle_center_x;
point.y += rectangle_center_y;
draw_line(rectangle_center_x, rectangle_center_y, point.x, point.y);

Una manera simple de hacer esto usando un ángulo como parámetro es simplemente recortar los valores X e Y usando los límites del rectángulo. En otras palabras, calcule la posición como si el icono girara alrededor de una trayectoria circular o elíptica, luego aplique esto:

(Suponiendo un rectángulo alineado al eje centrado en (0,0), con la longitud del eje X de XAxis y la longitud del eje Y de YAxis):

if (X > XAxis/2)    
         X = XAxis/2;

if (X < 0 - XAxis/2)
         X = 0 - XAxis/2;

if (Y > YAxis/2)    
         Y = YAxis/2;

if (Y < 0 - YAxis/2)    
         Y = 0 - YAxis/2;

El problema con este enfoque es que el ángulo no será del todo exacto y la velocidad a lo largo del perímetro del rectángulo no será constante. Modelar una elipse que oscula el rectángulo en sus esquinas puede minimizar el efecto, pero si está buscando una órbita suave, de velocidad constante & "; &"; este método no será adecuado.

Si crees que te refieres a rotar como la tierra gira alrededor del sol (no la auto-rotación ... ¿entonces tu pregunta es sobre cómo deslizarse a lo largo de los bordes de un rectángulo?)

Si es así, puedes probar esto:

# pseudo coode
for i = 0 to 499
  if i < 100:  x++
  else if i < 250: y--
  else if i < 350: x--
  else y++

  drawTheIcon(x, y)

Actualización: (vea el comentario a continuación)

para usar un ángulo, una línea será

y / x = tan(th)       # th is the angle

las otras líneas son simples ya que son horizontales o verticales. así, por ejemplo, es x = 50 y puedes poner eso en la línea de arriba para obtener el y. hazlo para la intersección de la línea horizontal y la línea vertical (por ejemplo, el ángulo es de 60 grados y dispara " NorthEast " ... ahora tienes dos puntos. Entonces el punto que está más cerca de el origen es el que golpea primero el rectángulo).

Utilice una matriz de transformación 2D . Muchos lenguajes (por ejemplo, Java) lo admiten de forma nativa (busque AffineTransformation); de lo contrario, escriba una rutina para hacer la rotación usted mismo, una vez, depúrela bien y úsela para siempre. Debo tener cinco de ellos escritos en diferentes idiomas.

Una vez que pueda hacer la rotación simplemente, encuentre la ubicación en el rectángulo haciendo line-line intersección . Encuentre el centro del icono en órbita intersecando dos líneas:

  1. Un rayo desde su centro de rotación en el ángulo que desee
  2. Uno de los cuatro lados, delimitado por el ángulo que desee (los cuatro cuadrantes).

Dibuja un boceto en un trozo de papel con un rectángulo y un centro de rotación. Primero traduzca el rectángulo al centro en el origen de su sistema de coordenadas (recuerde los parámetros de traducción, necesitará invertir la traducción más adelante). Gire el rectángulo para que sus lados estén paralelos a los ejes de coordenadas (mismo motivo).

Ahora tiene un triángulo con ángulo conocido en el origen, el lado opuesto tiene una longitud conocida (la mitad de la longitud de un lado del rectángulo) y ahora puede:

- resuelve el triángulo

- deshacer la rotación

- deshacer la traducción

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top