Este snippet de pilha desenha um retângulo branco com alias em um fundo preto, com parâmetros para suas dimensões, posição, ângulo e dimensões da grade:
<style>html *{font-family:Consolas,monospace}input{width:24pt;text-align:right;padding:1px}canvas{border:1px solid gray}</style><p>grid w:<input id='gw' type='text' value='60'> grid h:<input id='gh' type='text' value='34'> w:<input id='w' type='text' value='40'> h:<input id='h' type='text' value='24'> x:<input id='x' type='text' value='0'> y:<input id='y' type='text' value='0'> θ:<input id='t' type='text' value='12'>° <button type='button' onclick='go()'>Go</button></p>Image<br><canvas id='c'>Canvas not supported</canvas><br>Text<br><textarea id='o' rows='36' cols='128'></textarea><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script>function toCart(t,a,n,r){return{x:t-n/2,y:r/2-a}}function vtx(t,a,n){return{x:n.x+t*Math.cos(a),y:n.y+t*Math.sin(a)}}function sub(t,a){return{x:t.x-a.x,y:t.y-a.y}}function dot(t,a){return t.x*a.x+t.y*a.y}function inRect(t,a,n,r){var e=sub(a,t),o=sub(a,n),l=sub(a,r),i=dot(e,o),v=dot(e,l);return i>0&&i<dot(o,o)&&v>0&&v<dot(l,l)}function go(){var t=parseInt($("#gw").val()),a=parseInt($("#gh").val()),n=parseFloat($("#w").val()),r=parseFloat($("#h").val()),e={x:parseFloat($("#x").val()),y:parseFloat($("#y").val())},o=Math.PI*parseFloat($("#t").val())/180,l=Math.sqrt(n*n+r*r)/2,i=Math.atan2(r,n),v=vtx(l,o+i,e),h=vtx(l,o+Math.PI-i,e),u=vtx(l,o-i,e),x=$("#c");x.width(t).height(a).prop({width:t,height:a}),x=x[0].getContext("2d");for(var s="",c=0;a>c;c++){for(var f=0;t>f;f++)inRect(toCart(f+.5,c+.5,t,a),v,h,u)?(s+="..",x.fillStyle="white",x.fillRect(f,c,1,1)):(s+="XX",x.fillStyle="black",x.fillRect(f,c,1,1));a-1>c&&(s+="\n")}$("#o").val(s)}$(go)</script>
A representação do texto tem XX
onde houver um pixel preto na imagem e ..
onde houver um pixel branco. (Parece esmagado se eles são X
e .
.)
Escreva um programa que utilize a representação de texto de um retângulo produzido pelo Snippet e produza a largura e a altura aproximadas do retângulo, ambas dentro de ± 7% da largura e altura reais .
Seu programa deve trabalhar para efetivamente todos os retângulos possíveis que podem ser desenhados pelo snippet, com as restrições que:
- A largura e a altura do retângulo são 24 no mínimo.
- A largura e a altura da grade são 26 no mínimo.
- O retângulo nunca toca nem sai dos limites da grade.
Portanto, o retângulo de entrada pode ter qualquer rotação, posição e dimensões, e a grade pode ter quaisquer dimensões, desde que as três restrições acima sejam atendidas. Observe que, exceto para as dimensões da grade, os parâmetros do snippet podem ser flutuantes.
Detalhes
- Tome o retângulo de texto bruto como entrada ou o nome do arquivo de um arquivo que contém o retângulo de texto bruto (via stdin ou linha de comando). Você pode assumir que o retângulo de texto tem uma nova linha à direita.
- Você pode assumir o retângulo de texto é feita a partir de quaisquer dois distintos ASCII imprimíveis caracteres que não sejam
X
e.
se desejado. (As novas linhas devem permanecer novas.) - Emita a largura e a altura medidas como números inteiros ou flutuantes para stdout em qualquer ordem (já que não há como determinar qual delas realmente foi com qual parâmetro). Qualquer formato que mostra claramente as duas dimensões é fino, por exemplo
D1 D2
,D1,D2
,D1\nD2
,(D1, D2)
, etc. - Em vez de um programa, você pode escrever uma função que leva o retângulo de texto como uma string ou o nome do arquivo e imprime o resultado normalmente ou o retorna como uma string ou lista / tupla com dois elementos.
- Lembre-se disso
XX
ou..
é um 'pixel' do retângulo, não dois.
Exemplos
Ex. 1
Parâmetros: grid w:60 grid h:34 w:40 h:24 x:0 y:0 θ:12
(padrões do snippet)
Entrada
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX....XXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............XXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX........................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX....................................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..........................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..........................................................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX....................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX........................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Saídas de exemplo
40 24
24 40
[40.0, 24.0]
42.8, 25.68
(+ 7%)37.2, 22.32
(-7%)
Ex. 2
Parâmetros: grid w:55 grid h:40 w:24.5 h:24 x:-10.1 y:2 θ:38.5
Entrada
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX......XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXX..................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX......................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX............................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..............................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX......................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXX..................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXX......................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX................................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXX............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX......................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX....................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXX................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX......................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..........................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX......................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX..........XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXX......XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Saídas de exemplo
24.0 24.5
25.68 26.215
(+ 7%)22.32 22.785
(-7%)
Pontuação
O código mais curto em bytes vence. O desempate é o posto mais votado.
Respostas:
Matlab, 226 bytes
A idéia é simples: primeiro tento descobrir quanto o retângulo foi girado e depois giro a imagem de forma que o retângulo fique na vertical. Então, apenas 'somar' todos os pixels nas colunas da linha de maneira sutil e tentar contar quantas somas estão acima da média (limiar simples) para determinar a largura e a altura. Este método simples funciona de maneira surpreendentemente confiável.
Como posso detectar o ângulo?
Eu apenas tento cada passo (um grau cada) e soma ao longo das colunas e obtém um vetor de somas. Quando o retângulo está na vertical, idealmente, eu deveria obter apenas duas mudanças repentinas nesse vetor de somas. Se o quadrado estiver na ponta, as alterações serão muito graduais. Então, eu apenas uso a primeira derivada e tento minimizar o número de 'saltos'. Aqui você pode ver um gráfico do critério que estamos tentando minimizar. Observe que você pode ver os quatro mínimos que correspondem às quatro orientações possíveis na vertical.
Pensamentos adicionais: não tenho certeza do quanto isso poderia ser praticado, pois a pesquisa exaustiva de ângulos ocupa muitos caracteres e duvido que você possa conseguir isso tão bem com métodos de otimização integrados, porque, como você pode ver, existem muitos mínimos locais que não estamos procurando. Você pode facilmente melhorar a precisão (para grandes fotos), escolhendo um tamanho menor passo para o ângulo e só procurar 90 ° em vez de 360 ° para que você poderia substituir
0:360
com0:.1:90
ou somehting assim. De qualquer forma, para mim, o desafio foi mais encontrar um algoritmo robusto do que jogar golfe, e tenho certeza de que as entradas das linguagens de golfe deixarão minha apresentação muito para trás =)PS: Alguém realmente deve derivar uma linguagem de golfe do Matlab / Octave.
Saídas
Exemplo 1:
Exemplo 2:
Código
Golfe:
Ungolfed:
fonte
CJam,
68 6564 bytesIsso pode ser jogado um pouco mais ..
Como funciona
A lógica é bastante simples, se você pensar sobre isso.
Tudo o que precisamos das
X.
combinações de entrada são 3 coordenadas de dois lados adjacentes. Aqui está como os obtemos:First
Em qualquer orientação do retângulo, o primeiro de
.
toda a entrada será um dos cantos. Por exemplo..Aqui, a primeira
.
é na 2 ª linha, 8 th coluna.Mas não é isso, temos que fazer alguns ajustes e adicionar a largura da
.
corrida nessa linha às coordenadas para obter a coordenada da extremidade certa.Second
Se transpormos o retângulo acima (girado em novas linhas), o canto inferior esquerdo ocupará o lugar da etapa acima. Mas aqui, não compensamos o
.
comprimento da execução, pois gostaríamos de obter a coordenada inferior esquerda da aresta de qualquer maneira (que na forma transposta ainda será a primeira encontrada.
)Rest two
Para as duas coordenadas restantes, simplesmente giramos horizontalmente o retângulo e executamos os dois passos acima. Um dos cantos aqui será comum dos dois primeiros.
Depois de obter todos os 4, simplesmente fazemos algumas contas simples para obter as distâncias.
Agora, esse não é o método mais preciso, mas funciona bem dentro da margem de erro e para todas as orientações possíveis do retângulo.
Expansão do código (pouco desatualizado)
Experimente online aqui
fonte
-2
. O erro é de cerca de 28%. Tentei uma abordagem semelhante (foi minha ideia inicial, antes de ver a sua), e obtê-la com precisão o suficiente acaba sendo mais complicada do que o esperado, principalmente se os lados estiverem próximos da horizontal / vertical. Funciona muito bem se estiverem mais próximos da diagonal. Eu acho que isso requer mais lógica (por exemplo, também procurando por extremos na direção diagonal) ou uma abordagem totalmente diferente..
ajuste de largura na segunda coordenada, em vez de na primeira. Fixará. Deve ser uma solução curta.Python 3,
347337 bytesIsso ficou mais difícil do que eu esperava. Trabalho em progresso...
Define uma função que
f
toma a string como argumento e imprime o resultado em STDOUT.Pitão,
87848281757271 bytes(POSSÍVELMENTE INVÁLIDO, INVESTIGANDO QUANDO EU CHEGO EM CASA)
WayAinda muito longo. Basicamente, um porto do anterior. Distância.a
euclidiana de Pyth . Recebe entrada via STDIN e fornece saída via STDOUT. Espera que o caractere não retângulo seja minúsculox
(bem, qualquer coisa com valor ASCII 98 ou mais).Algoritmo
Ambos usam o mesmo algoritmo. Basicamente, começo com uma matriz que contém o centro de massa da área do retângulo. Em seguida, adiciono três pontos à matriz de todos os pontos do retângulo, sempre escolhendo aquele com a soma máxima de distâncias aos pontos já presentes na matriz. O resultado é sempre três pontos nos diferentes cantos do retângulo. Calculo então todas as três distâncias entre esses três pontos e tomo os dois mais curtos.
fonte
[33.0, 59.0]
vez de[40, 24]
e em[39.0, 54.0]
vez de[24.0, 24.5]
.Python 2, 342 bytes
Isso inspirou-se no algoritmo de @ Pietu1998. É preciso a idéia de determinar um canto como o ponto mais distante do centro, mas difere a partir daí:
Portanto, o código segue esta sequência:
r
de pontos de retângulo.1.0
é adicionado às distâncias porque os cálculos de distância originais usam índices de pixels. Por exemplo, se você tiver 5 pixels, a diferença entre o índice do último e do primeiro pixel será de apenas 4, o que precisa de compensação no resultado final.Precisão é muito boa. Para os dois exemplos:
fonte
Python 2, 272 bytes
Postando isso como uma resposta separada, pois é um algoritmo completamente diferente do meu anterior:
Essa abordagem não identifica os cantos. É baseado na observação de que o tamanho (largura e altura) da caixa delimitadora e a área do retângulo girado são suficientes para determinar a largura e a altura do retângulo.
Se você observar um esboço, é bastante fácil calcular a largura (
wb
) e a altura (hb
) da caixa delimitadora comw
/h
o tamanho do retângulo ep
o ângulo de rotação:wb
ehb
pode ser extraído diretamente da imagem. Também podemos extrair rapidamente a área totala
do retângulo contando o número de..
pixels. Como estamos lidando com um retângulo, isso nos dá a equação adicional:Portanto, temos 3 equações com 3 incógnitas (
w
,h
ep
), o que é suficiente para determinar as incógnitas. A única chatice é que as equações contêm funções trigonométricas e, pelo menos com minha paciência e habilidades matemáticas, o sistema não pode ser facilmente resolvido analiticamente.O que implementei é uma busca de força bruta pelo ângulo
p
. Uma vezp
dada, as duas primeiras equações acima se tornam um sistema de duas equações lineares, que podem ser resolvidasw
eh
:Com esses valores, podemos comparar
w * h
com a área medida do retângulo. Os dois valores seriam idealmente iguais em algum momento. É claro que isso não vai acontecer na matemática de ponto flutuante.O valor de
w * h
diminui à medida que o ângulo aumenta. Então começamos no ângulo 0.0 e, em seguida, incrementamos o ângulo em pequenos passos até que a primeira vezw * h
seja menor que a área medida.O código possui apenas duas etapas principais:
A precisão da saída é boa para retângulos em que a largura e a altura são significativamente diferentes. Fica um pouco duvidoso com retângulos quase quadrados e girados perto de 45 graus, apenas eliminando o obstáculo de 7% no exemplo de teste 2.
O bitmap do exemplo 2, na verdade, parece um pouco estranho. O canto esquerdo parece desconfiado. Se eu adicionar mais um pixel no canto esquerdo, ambos parecerão melhores (para mim) e fornecerão uma precisão muito melhor para esse algoritmo.
fonte