En este artículo, veremos cómo obtener el cuadro delimitador de diferentes formas. Usaremos P5.js, que es un entorno de programación creativa de Javascript framework y está muy inspirado en Processing.
Cuadro delimitador: un cuadro delimitador es básicamente un rectángulo que limita una forma de manera más técnica, es el rectángulo con el área de superficie más pequeña posible que delimita la forma. Un cuadro delimitador puede tener rotación (llamado cuadro delimitador global ), pero en este artículo, nos centraremos en los cuadros delimitadores alineados con el eje (formas AABB) que tienen rotación cero en ellos (también llamado cuadro delimitador local )
Nota: un cuadro delimitador para una forma es el rectángulo con el área de superficie más pequeña posible que limita la forma.
Motivo para calcular el cuadro delimitador: un cuadro delimitador actúa como un contenedor de una forma y tiene varias aplicaciones en aplicaciones gráficas (sobre todo utilizadas por bibliotecas GUI para máscaras de widgets). Dado que un cuadro delimitador contiene la forma, si cualquier otra forma no se cruza con el cuadro delimitador, tampoco se cruza con la forma interna, por lo que los cuadros delimitadores se usan mucho en los motores de Física (como Box2D) para Detección de colisión de fase amplia.
Base para p5.js: este es el código base (normalmente para cada código p5.js).
<!-- Our main HTML file! --> <html> <head> <script src="https://cdn.jsdelivr.net/npm/p5"></script> <script src="sketch.js"></script> </head> <body> </body> </html>
Nota: ¡Solo cambiaremos script.js en cada iteración, y el archivo HTML necesariamente permanecerá intacto!
- Encontrar el cuadro delimitador de una elipse:
/* p5.js Sketch for finding and drawing
bounding-box of an ellipse*/
function
setup(){
createCanvas(480, 360);
}
// Draws bounding-box around the
// given ellipse!
function
drawBBox(x0, y0, r1, r2){
// Draw only the outline
// of the rectangle
noFill();
// Draw the outline in red
stroke(255, 0, 0);
rect(x0-r1, y0-r2, 2*r1, 2*r2);
}
function
draw() {
let x0 = width/2, y0 = height/2;
let r1 = 180, r2 = 100;
// Note that `ellipse` takes in
// diameters not radii!
ellipse(x0, y0, 2*r1, 2*r2);
drawBBox(x0, y0, r1, r2);
// We don't want to draw this
// over and over again
noLoop();
}
Producción:
- Encontrar el cuadro delimitador de un círculo: es lo mismo que una elipse , ya que un círculo es solo un caso especial de una elipse con los mismos radios (mismo semieje mayor y semieje menor).
- Encontrar el cuadro delimitador de un segmento de línea
/* p5.js Sketch for finding and drawing
bounding-box of a line-segment*/
function
setup() {
createCanvas(480, 360);
}
// Draws bounding-box around the
// given line-segment!
function
drawBBox(x1, y1, x2, y2) {
stroke(255, 0, 0);
noFill();
let x = min(x1, x2), y = min(y1, y2);
let w = max(x1, x2) - x, h = max(y1, y2) - y;
rect(x, y, w, h);
}
function
draw() {
let x1 = 280, y1 = 80, x2 = 180, y2 = 280;
line(x1, y1, x2, y2);
drawBBox(x1, y1, x2, y2);
noLoop();
}
Producción:
- Encontrar el cuadro delimitador de un triángulo: Encontrar el cuadro delimitador de un triángulo es muy similar a encontrar el cuadro delimitador para un segmento de línea.
/* p5.js Sketch for finding and drawing
bounding-box of a triangle*/
function
setup() {
createCanvas(480, 360);
}
// Draws bounding-box around the
// given triangle!
function
drawBBox(x1, y1, x2, y2, x3, y3) {
stroke(255, 0, 0);
noFill();
let x = min(x1, x2, x3), y = min(y1, y2, y3);
let w = max(x1, x2, x3) - x, h = max(y1, y2, y3) - y;
rect(x, y, w, h);
}
function
draw() {
let x1 = 240, y1 = 80, x2 = 140;
let y2 = 280, x3 = 340, y3 = 280;
triangle(x1, y1, x2, y2, x3, y3);
drawBBox(x1, y1, x2, y2, x3, y3);
noLoop();
}
Producción:
- Encontrar el cuadro delimitador de un polígono: un triángulo es un polígono, y si encontramos el cuadro delimitador de un triángulo , entonces encontrar el cuadro delimitador para el polígono no debería ser ninguna dificultad. Solo tenemos que generalizar para que podamos tener cualquier número de vértices y listo.
/* p5.js sketch for finding and drawing
bounding-box of a polygon*/
function
setup() {
createCanvas(480, 360);
}
// Draws bounding-box around
// the given polygon!
function
drawBBox(x, y) {
stroke(255, 0, 0);
noFill();
let rx = min(x), ry = min(y);
let w = max(x) - rx, h = max(y) - ry;
rect(rx, ry, w, h);
}
function
draw(){
/* Vertices for a star-polygon (decagon) */
let x = [240, 268, 334, 286, 298,
240, 182, 194, 146, 212];
let y = [80, 140, 150, 194, 260,
230, 260, 194, 150, 140];
beginShape();
for
(let i = 0; i < x.length; ++i)
vertex(x[i], y[i]);
fill(255, 217, 0);
// If you don't CLOSE it then it'd
// draw a chained line-segment
endShape(CLOSE);
drawBBox(x, y);
noLoop();
}
Producción:
Encontrar Bounding-Boxes es una parte importante de las aplicaciones de visualización. También en aplicaciones dinámicas como los juegos, no se puede calcular la detección de colisión de cápsulas en cada fotograma sin que esto suponga una penalización en el rendimiento. Entonces, antes de cualquier verificación de colisión compleja, se realiza una verificación de fase amplia para la salida anticipada que devuelve falso tan pronto como se determina que la forma no colisiona con la otra forma. Si se pasa la verificación de fase amplia, entonces viene la fase estrecha donde ocurre la detección de colisión real (OOBB, SAT, cápsula, elipsoide, etc.). Por lo tanto, encontrar el cuadro delimitador es una parte importante de muchas aplicaciones ricas en gráficos por varias razones.