¿Cuál es la idea detrás de la definición de rectángulos con dos puntos? [cerrado]

14

No es que esto no tenga sentido, pero simplemente funciona de manera incómoda el 99% del tiempo.

A menudo, en los gráficos 2D, los rectángulos se inicializan, almacenan y manipulan como un par de puntos. En ningún idioma en particular,

class Rect:
   p1, p2: point

Tiene más sentido definir un rectángulo como dos valores x y dos valores y, como este:

class Rect
   xleft, xright: int
   ytop, ybottom: int

Con dos puntos, si en algún lugar del código fuente desea utilizar el valor y de la parte superior, debería decir rect.p1.y (hmmm, deténgase y piense, ¿es p1 o p2) pero con los cuatro valores como miembros de datos simples, es claro y directo: rect.ytop (¡no es necesario pensar!) El uso de dos puntos significa que al tratar con la vertical, hay que enredar la horizontal; hay una relación extraña entre elementos independientes.

¿Cómo surgió esta idea de dos puntos y por qué persiste? ¿Tiene algún beneficio sobre las coordenadas X e Y?

NOTA AGREGADA: esta pregunta se encuentra en el contexto de rectángulos alineados con X-Y, como en los administradores de ventanas y los kits de herramientas de GUI, no en el contexto de formas arbitrarias en la aplicación de dibujo y pintura.

    
pregunta DarenW 30.11.2010 - 21:47
fuente

16 respuestas

8

¿Ha considerado que es menos propenso a errores?

Si usas (Point1, Point2) es muy claro lo que estás especificando. Si proporciona 2 puntos, entonces el único error posible es que el usuario haya mezclado sus x e y al construir los puntos, ya que el orden de los puntos no importa.

Si suministra 4 enteros, entonces, si alguien no está prestando atención, puede que le proporcione (x1, x2, y1, y2) cuando desee (x1, y1, x2, y2) o viceversa. Además, algunas API como la estructura Rect de WCF definen un rectángulo como (x, y, ancho, alto) que podría causar confusión sobre lo que significa (1, 2, 3, 4). ¿Es eso (x, y, w, h) o (x1, y1, x2, y2) o (x1, x2, y1, y2)?

En general, (Point1, Point2) me parece un poco más seguro.

    
respondido por el MIA 01.12.2010 - 02:43
fuente
9

Siempre me ha gustado definir un rectángulo como un punto + ancho y alto, donde el punto es la esquina superior izquierda del rectángulo.

class Rect {
  float x, y;
  float width, height;
}

Y luego agregue los métodos que necesite para obtener las otras métricas. Al igual que la versión de Java

    
respondido por el Martin Wickman 30.11.2010 - 23:56
fuente
7

En realidad, un rectángulo no está definido por 2 puntos. Un rectángulo solo puede definirse por dos puntos si es paralelo a los ejes.

Hay varias formas de representar rectángulos paralelos a los ejes:

  1. Dos puntos diagonalmente opuestos
  2. Un punto de esquina, altura y anchura
  3. Punto central, media altura y anchura (poco común, pero a veces útil).
  4. Como dos coordenadas X y dos coordenadas Y

Para (1), muchas bibliotecas usan una convención para determinar qué dos puntos se usan: topLeft y bottomRight, por ejemplo.

La elección de la representación puede basarse en el propósito original de la definición del rectángulo, pero imagino que es a menudo arbitraria . Las representaciones son equivalentes en la información que llevan. Sin embargo, difieren en la facilidad con la que se pueden calcular las propiedades del rectángulo y la conveniencia con la que se pueden realizar las operaciones en el reectangle.

Los beneficios de la definición (1) sobre otros incluyen:

  • Consistencia de la API con otros polígonos, líneas, etc.
  • topLeft, bottomRight se puede pasar a cualquier método que acepte puntos
  • Los métodos de clase de puntos se pueden llamar en topLeft, bottomRight
  • La mayoría de las propiedades se pueden derivar fácilmente, por ejemplo. bottomLeft, topRight, width, height, center, diagonal length, etc.
respondido por el Kramii 01.12.2010 - 00:39
fuente
6

Bueno, p1: Point y p2: Point van a tener dos coordenadas int en ellas de todos modos, ¿así que su clase no es lo mismo?

Y si almacena esos dos puntos como objetos de primera clase Point , ¿no obtiene un poco más de utilidad de ellos? En la mayoría de los sistemas de coordenadas gráficos que conozco, los puntos se subclasifican de esta manera para crear una jerarquía de objetos: point -> circle -> ellipse y así sucesivamente.

Entonces, si crea un objeto que no usa la clase Point , se ha divorciado de ese objeto del resto de la jerarquía de clases.

    
respondido por el Robert Harvey 30.11.2010 - 21:52
fuente
5

Por eso me gusta TRect de Delphi. Se define como un registro variante (estructura de unión en lenguaje C) que puede interpretarse como un punto TopLeft y un punto BottomRight, o enteros superior, izquierdo, inferior y derecho, lo que sea más conveniente en este momento.

    
respondido por el Mason Wheeler 30.11.2010 - 22:33
fuente
4

Seguramente si define su rectángulo como:

class Rect
{
    Point bottomLeft;
    Point topRight;
}

entonces sabrás de inmediato qué punto es cuál.

Incluso mejor sería agregar propiedades adicionales que le permitieran manipular el rectángulo de cualquier forma que necesitara para su aplicación. Esto simplemente actualizaría la estructura de datos subyacente.

Al agregar una transformación a la forma, puedes orientar tu rectángulo de la forma que quieras. Aún necesitaría un recuadro delimitador alineado con el eje para las comprobaciones rápidas de aceptación / rechazo :)

Sin embargo, si su modelo permite rectángulos en cualquier orientación sin aplicar una transformación, entonces "abajo a la izquierda" y "arriba a la derecha" no tienen significado, lo que lleva de nuevo a "p1" y "p2" (o algo equivalente).

    
respondido por el ChrisF 01.12.2010 - 00:07
fuente
2

creo que tiene más sentido que un rectángulo se represente con una extensión x y y un punto; Incluso podría hacer que la ubicación apunte al centro del rectángulo para que sea independiente de la rotación.

¡pero probablemente fue más fácil codificarlo como dos puntos!

    
respondido por el Steven A. Lowe 30.11.2010 - 21:56
fuente
2

No me gusta porque hemos lanzado un grado potencial de libertad, que esencialmente permite una rotación arbitraria. Un rectángulo 2D general tiene cinco incógnitas (grados de libertad). Podríamos especificarlos como las coordenadas de un punto, las longitudes de los dos lados que forman un vértice con este punto y el ángulo desde la horizontal de la primera línea (suponiendo que el otro tiene un ángulo 90 grados mayor). También se podría usar un número infinito de otras posibilidades, pero hay cinco cantidades independientes que deben especificarse. Algunas opciones conducirán a un álgebra más fácil que otras, dependiendo de lo que se haga con ellas.

    
respondido por el Omega Centauri 01.12.2010 - 01:21
fuente
1

¿No es exactamente lo mismo que 2 puntos? ¿Cómo es esto incómodo? La mayoría de las rutinas de dibujo requieren puntos, no componentes x / y separados.     

respondido por el GrandmasterB 30.11.2010 - 21:54
fuente
1

Definir rectángulos como pares de puntos le permite reutilizar el punto como un vértice para otra forma. Sólo un pensamiento ...

    
respondido por el RobotHumans 30.11.2010 - 22:53
fuente
1

Creo que es principalmente para establecer la uniformidad entre todas las primitivas de forma.

Claro que puede definir un rectángulo de muchas maneras diferentes, pero ¿cómo define un triángulo, una estrella o un círculo de manera que pueda usar estructuras de datos similares?

Todos los polígonos se pueden definir por sus puntos, con un poco de lógica para determinar qué hacer con los puntos.

Las bibliotecas gráficas operan principalmente en estos polígonos en términos de vértices y bordes, por lo que los puntos y las líneas entre ellos, todos los cálculos funcionan en estas dos características, bueno eso y facetas, pero eso es solo una función de los bordes.

    
respondido por el Orbling 30.11.2010 - 22:56
fuente
1

En dos dimensiones, almacenar un rectángulo como dos puntos es más claro que definir una esquina y un ancho y una altura en particular. Considere el ancho o la altura negativos, o los cálculos necesarios para determinar cada opción del otro.

Realizar rotaciones en un rectángulo definido por puntos también es mucho más sencillo que uno definido con un punto más ancho y alto.

Espero que la encapsulación haga que esta diferenciación no sea importante como usuario de la clase.

Un rectángulo debe definirse como tres puntos para que estén bien definidos en 3 dimensiones. No estoy completamente seguro del requisito para definir un rectángulo en 4 o más dimensiones.

    
respondido por el Armand 01.12.2010 - 00:49
fuente
1

Es completamente arbitrario. Necesitas cuatro piezas de información para dibujar un rectángulo. El diseñador de la biblioteca decidió representarlo con dos puntos (cada uno con una coordenada x-y), pero podría haberlo hecho fácilmente con x / y / w / h o arriba / abajo / izquierda / derecha.

Supongo que la verdadera pregunta del OP es: ¿por qué se hizo esta elección en particular?

    
respondido por el Barry Brown 01.12.2010 - 03:38
fuente
1

La elección de los parámetros solo es importante para los diseñadores / codificadores de bajo nivel.

Los usuarios de alto nivel solo deben pensar en:

  • IsPointInRect
  • área
  • Intersección (o recorte)
  • HasOverlap (igual que Intersection.Area > 0)
  • Unión (se convierte en una lista de rectángulos)
  • Resta (una lista de rectángulos que representan el mismo conjunto de puntos que está en el rect A pero no en el rect B)
  • Transformar
    • Cambios en X e Y
    • Rotación (0, 90, 180, 270)
    • Escalado en X e Y (ver nota)
  • Sintaxis simple para las propiedades Xmin, Xmax, Ymin, Ymax, Width, Height para que el usuario no necesite saber la elección exacta de los parámetros.

Nota: para minimizar la pérdida de precisión durante la transformación de escala, a veces es apropiado implementar una segunda clase Rect que utiliza coordenadas de punto flotante, de modo que los resultados intermedios se puedan almacenar con precisión en una secuencia de transformaciones y Solo redondeado a entero en el último paso.

    
respondido por el rwong 01.12.2010 - 07:35
fuente
0

Como dice @Steven, creo que debería ser en términos de un punto (x, y) y un vector de tamaño (w, h). Eso es porque es fácil caer en una ambigüedad. Supongamos que tiene el siguiente rectángulo relleno que comienza en el punto (0,0).

  012
0 XXX
1 XXX
2 XXX

Claramente, su ancho y alto son (3,3), pero ¿cuál es su segundo punto? ¿Es (2,2) o (3,3)?

Esta ambigüedad puede causar todo tipo de problemas.

Aprendí de manera difícil hace años que es mejor pensar en las coordenadas gráficas como las líneas entre los píxeles, no como las líneas en las que están en . De esa manera no hay ambigüedad.

    
respondido por el Mike Dunlavey 30.11.2010 - 22:29
fuente
0
Pa(x,y)*-----------------------------------*Pb(x,y)
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
Pc(x,y)*-----------------------------------*Pd(x,y)

Podemos definir tanto Pb como amp; Pc así:

  

Pb (Pd (x), Pa (y))

y

  

Pc (Pa (x), Pd (y))

Por lo tanto, no es necesario definir los cuatro puntos debido a la simetría

    
respondido por el Darknight 01.12.2010 - 01:32
fuente

Lea otras preguntas en las etiquetas