Eu estou tentando escrever um programa C ++ que leva as seguintes entradas do usuário para construir retângulos (entre 2 e 5): altura, largura, x-pos, y-pos. Todos esses retângulos existirão paralelos aos eixos xe y, ou seja, todas as suas arestas terão inclinações de 0 ou infinito.
Eu tentei implementar o que é mencionado nesta pergunta, mas não estou tendo muita sorte.
Minha implementação atual faz o seguinte:
// Gets all the vertices for Rectangle 1 and stores them in an array -> arrRect1
// point 1 x: arrRect1[0], point 1 y: arrRect1[1] and so on...
// Gets all the vertices for Rectangle 2 and stores them in an array -> arrRect2
// rotated edge of point a, rect 1
int rot_x, rot_y;
rot_x = -arrRect1[3];
rot_y = arrRect1[2];
// point on rotated edge
int pnt_x, pnt_y;
pnt_x = arrRect1[2];
pnt_y = arrRect1[3];
// test point, a from rect 2
int tst_x, tst_y;
tst_x = arrRect2[0];
tst_y = arrRect2[1];
int value;
value = (rot_x * (tst_x - pnt_x)) + (rot_y * (tst_y - pnt_y));
cout << "Value: " << value;
No entanto, não tenho certeza se (a) implementei o algoritmo ao qual vinculei corretamente, ou se fiz exatamente como interpretar isso?
Alguma sugestão?
Respostas:
ou, usando coordenadas cartesianas
(Com X1 sendo coordenado à esquerda, X2 sendo coordenado à direita , aumentando da esquerda para a direita e Y1 sendo a coordenação superior e Y2 sendo a coordenação inferior, aumentando de baixo para cima - se não é assim que seu sistema de coordenadas [por exemplo, a maioria dos computadores tem o Direção Y invertida], troque as comparações abaixo ) ...
Digamos que você tenha o Reto A e o Reto B. A prova é por contradição. Qualquer uma das quatro condições garante que nenhuma sobreposição possa existir :
Portanto, a condição para não sobreposição é
Portanto, uma condição suficiente para Sobreposição é o oposto.
A lei de De Morgan diz que
Not (A or B or C or D)
é o mesmo queNot A And Not B And Not C And Not D
usar De Morgan, temos
Isso é equivalente a:
RectA.Left < RectB.Right
] eRectA.Right > RectB.Left
] eRectA.Top > RectB.Bottom
] eRectA.Bottom < RectB.Top
]Nota 1 : É bastante óbvio que esse mesmo princípio pode ser estendido a qualquer número de dimensões.
Nota 2 : também deve ser bastante óbvio contar sobreposições de apenas um pixel, alterar o
<
e / ou o>
limite desse para a<=
ou a>=
.Nota 3 : Essa resposta, ao utilizar coordenadas cartesianas (X, Y), é baseada em coordenadas cartesianas algébricas padrão (x aumenta da esquerda para a direita e Y aumenta de baixo para cima). Obviamente, onde um sistema de computador pode mecanizar as coordenadas da tela de maneira diferente (por exemplo, aumentando Y de cima para baixo ou X Da direita para a esquerda), a sintaxe precisará ser ajustada de acordo /
fonte
fonte
B.height
deve serA.height
#undef min
e#undef max
, ou usando nomes de parâmetros diferentes.#define BETWEEN(value,min,max) \ (\ value > max ? max : ( value < min ? min : value )\ )
xOverlap
está em uma dimensão;rectOverlap
é bidimensional. Pode ser estendido para N dimensões usando um loop.fonte
É mais fácil verificar se um retângulo está completamente fora do outro, portanto, se é
à esquerda...
ou à direita ...
ou por cima ...
ou no fundo ...
do segundo retângulo, ele não pode colidir com ele. Portanto, para ter uma função que retorna um ditado booleano quando os retângulos colidem, simplesmente combinamos as condições por ORs lógicos e negamos o resultado:
Para já receber um resultado positivo ao tocar apenas, podemos alterar o "<" e ">" por "<=" e "> =".
fonte
Faça a si mesmo a pergunta oposta: como posso determinar se dois retângulos não se cruzam? Obviamente, um retângulo A completamente à esquerda do retângulo B não se cruza. Além disso, se A estiver completamente à direita. E da mesma forma, se A estiver completamente acima de B ou completamente abaixo de B. Em qualquer outro caso, A e B se cruzam.
O que se segue pode ter erros, mas estou bastante confiante sobre o algoritmo:
fonte
Suponha que você definiu as posições e tamanhos dos retângulos assim:
Minha implementação em C ++ é assim:
Um exemplo de chamada de função de acordo com a figura fornecida acima:
As comparações dentro do
if
bloco serão parecidas abaixo:fonte
Veja como isso é feito na API Java:
fonte
Na pergunta, você vincula a matemática para quando os retângulos estão em ângulos arbitrários de rotação. Se eu entendo um pouco sobre os ângulos da pergunta, interpreto que todos os retângulos são perpendiculares um ao outro.
Um conhecimento geral da área da fórmula de sobreposição é:
Usando o exemplo:
1) colete todas as coordenadas x (esquerda e direita) em uma lista, classifique-a e remova duplicatas
2) colete todas as coordenadas y (superior e inferior) em uma lista, classifique-a e remova as duplicatas
3) crie uma matriz 2D pelo número de intervalos entre as coordenadas x únicas * número de intervalos entre as coordenadas y exclusivas.
4) pinte todos os retângulos nessa grade, incrementando a contagem de cada célula em que ocorre:
5) Ao pintar os retângulos, é fácil interceptar as sobreposições.
fonte
fonte
Não pense nas coordenadas como indicando onde os pixels estão. Pense neles como estando entre os pixels. Dessa forma, a área de um retângulo 2x2 deve ser 4, não 9.
fonte
A maneira mais fácil é
Antes de tudo, lembre-se de que, nos computadores, o sistema de coordenadas está de cabeça para baixo. o eixo x é igual ao da matemática, mas o eixo y aumenta para baixo e diminui ao subir .. se o retângulo for desenhado do centro. se as coordenadas x1 forem maiores que x2 mais sua metade da largura. então significa que metade deles se tocarão. e da mesma maneira descendo + metade da sua altura. vai colidir ..
fonte
Digamos que os dois retângulos sejam retângulo A e retângulo B. Deixe seus centros serem A1 e B1 (as coordenadas de A1 e B1 podem ser facilmente encontradas), deixe as alturas Ha e Hb, largura seja Wa e Wb, seja dx o largura (x) distância entre A1 e B1 e dy é a altura (y) da distância entre A1 e B1.
Agora podemos dizer que podemos dizer que A e B se sobrepõem: quando
fonte
Eu implementei uma versão C #, ela é facilmente convertida em C ++.
fonte
Eu tenho uma solução muito fácil
sejam x1, y1 x2, y2, l1, b1, l2, sejam cordinados e comprimentos e larguras deles respectivamente
considere a condição ((x2
Agora, a única maneira de sobrepor esse retângulo é se o ponto diagonal de x1, y1 estiver dentro do outro retângulo ou, da mesma forma, o ponto diagonal de x2, y2 estiver dentro do outro retângulo. que é exatamente a condição acima implica.
fonte
A e B são dois retângulos. C seja seu retângulo de cobertura.
Ele cuida de todos os casos possíveis.
fonte
Isso é do exercício 3.28 do livro Introduction to Java Programming- Comprehensive Edition. O código testa se os dois retângulos são idênticos, se um está dentro do outro e se um está fora do outro. Se nenhuma dessas condições for atendida, as duas se sobrepõem.
** 3,28 (Geometria: dois retângulos) Escreva um programa que solicite ao usuário que insira as coordenadas x, y, largura e altura centrais de dois retângulos e determine se o segundo retângulo está dentro do primeiro ou se sobrepõe ao primeiro, como mostra a Figura 3.9. Teste seu programa para cobrir todos os casos. Aqui estão os exemplos de execuções:
Digite as coordenadas x, y, largura e altura do centro de r1: 2,5 4 2,5 43 Digite as coordenadas x, y, largura e altura do centro de r2: 1,5 5 0,5 3 r2 está dentro de r1
Digite o centro de r1 - coordenadas x, y, largura e altura: 1 2 3 5.5 Digite o centro de r2 - coordenadas x, largura e altura: 3 4 4.5 5 r2 sobrepõe r1
Digite o centro de r1 - coordenadas x, y, largura e altura: 1 2 3 3 Digite o centro de r1 - coordenadas x, largura e altura: 40 45 3 2 r2 não se sobrepõe a r1
fonte
fonte
Para aqueles que usam pontos centrais e meios tamanhos para seus dados retangulares, em vez dos x, y, w, h ou x0, y0, x1, x1 típicos, veja como fazê-lo:
fonte
fonte
Se os retângulos se sobrepuserem, a área de sobreposição será maior que zero. Agora vamos encontrar a área de sobreposição:
Se eles se sobrepuserem, a borda esquerda de overlap-rect será a
max(r1.x1, r2.x1)
borda direita e serámin(r1.x2, r2.x2)
. Portanto, o comprimento da sobreposição serámin(r1.x2, r2.x2) - max(r1.x1, r2.x1)
Então a área será:
Se
area = 0
então eles não se sobrepõem.Simples, não é?
fonte
"Se você executar as subtrações x ou y coordenadas correspondentes aos vértices dos dois voltados para cada retângulo, se os resultados forem o mesmo sinal, os dois retângulos não se sobrepõem aos eixos que" (desculpe, não sei se minha tradução está correta) )
Fonte: http://www.ieev.org/2009/05/kiem-tra-hai-hinh-chu-nhat-chong-nhau.html
fonte
Código Java para descobrir se os retângulos estão em contato ou se sobrepõem
...
...
fonte