Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Bruno Augusto

Buscar array...

Recommended Posts

  Em 27/09/2010 at 01:23, 'Evandro Oliveira' disse:

Bruno, você já tem a composição das cores que 'te servem' e das cores 'a verificar'??

 

Mais ou menos. Eu encontrei dezenas de tabelas de cores RGB, sendo que na maior delas haviam mais de 1500 cores COM NOME.

 

Mas estavam ou embaralhadas ou organizadas entre "shades" ("categorias", digamos assim). Porém tais categorias eram, vez ou outra populadas, com cores completamente incondizentes com a categoria.

 

O que eu fiz foi manualmente (pois até então não tinha algoritimos para trabalhar) separar cada cor em sua categoria.

 

Depois que separei, fui fazer um pente-fino, com calma, e percebi várias inconsistências geradas, em parte pela tela do notebook que uso (é ridículo, um tom de azul visto de perto vira roxo visto de longe).

 

Outras vezes, mesmo à mesma distância, percebia diferenças de categorização entre quando fiz e quando refinei.

 

Pesquisei sobre e vi que esse é o comportamento natural do olho humano e que para minimizar estes efeitos deveria trabalhar com H S L/V/I

 

No fim, como cores finais tidas, estou apenas com as quase 360 puras da variação Hue, como disse acima.

 

  Em 27/09/2010 at 01:23, 'Evandro Oliveira' disse:

A diferença é que não existe 256 na decomposição d, mas 256 convertido em h nos remete a uma cor válida -> 000100

 

Você diz converter um RGB (depois de decomposto) em HSL, por exemplo?

 

Porque não existe lógica em computar o valor de um canal RGB que não existe em qualquer outro ColorSpace.

 

Eu até violei propositalmente todas as exceções que meu programa dispara para ver se é possível tal conversão.

 

De fato é, mas tanto 255 quanto 256 em RGB equivale a 0.921 radianos (52.76°).

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 26/09/2010 at 22:51, 'Bruno Augusto' disse:

Mas concorda comigo que isso é apenas metade da solução? Confesso que nunca havia ouvido falra em nada do que foi dito aqui, logo nem imaginava a solução seguindo essa lógica de pensamento.

 

Ainda não, não chegamos na metade ainda, mas estamos próximos. :D

 

  Em 26/09/2010 at 22:51, 'Bruno Augusto' disse:

Como ficaria a comparação dos canais de cor nessa árvore? Eu sei que existem "apenas" pouco menos de 360 "cores reais" (de 0 à 360° - sendo que começa e termina em vermelho)

 

Veja só:

 

Imagem Postada

 

 

Basicamente, temos 6 cores e todas as outras derivam dessas.

 

  Em 26/09/2010 at 22:51, 'Bruno Augusto' disse:

Como a AVL Tree trataria isso para, por exemplo, encontrar um marrom, que apesar de desde a pré-escola sabermos que é uma mistura de vermelho e verde, na realidade, é um descendente de vermelho?

 

Como fica fácil perceber na imagem anterior, temos uma variação de 60º para cada tonalidade e, se utilizarmos também o cálculo do chroma, teremos:

 

Imagem Postada

 

 

Voltando para nossa árvore, utilizaremos tanto a tonalidade quanto o chroma para chegar em:

 

Imagem Postada

 

Se estiver tudo bem até aqui, vamos finalizar nossa AVL para trabalhar com objetos em vez de inteiros.

 

PS: A árvore está espelhada para facilitar a visualização, a ramificação do lado esquerdo será invertida.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Depois de descobrir uma falha primária na minha linha de raciocínio, resolvi estudar a fundo o sistema de composição HSV e tive umas conclusões interessantes a respeito do sistema de angulação.

 

Tratando o croma como uma cônica, podemos posicionar qualquer cor (diferenciável a olho nu ou não) em um cone disposto no sistema de coordenadas cilíndrico.

 

O fator essencial para a existência de qualquer forma neste sistema é a existência de um raio R, representado pelo eixo polar. Quando raio não existe, R=0, não existe forma, no cilindro. Podemos, por consequência ignorar o valor do coeficiente angular φ.

 

O único valor que nos seria de interesse é o eixo longitudinal.

 

 

Podemos estabelecer algumas relações que ajudarão na aplicabilidade dos recursos (que serão destilados pelo JBN [eu é que não vou fazer!]).

 

R -> equivale à saturação

φ -> equivale ao hue

L -> equivale à luminosidade

 

Tratando o croma como um cone de base invertida (o "bico" para baixo) temos:

 

Quando L = 0, não há R, nem φ e a cor é preta.

 

Quando R = 0, não há φ. Temos uma escala de cinza referente a L.

 

Quando R = 1, L também é igual a 1 e dependemos exclusivamente de φ para definir uma cor, que será pura.

 

A regra acima dita que L cresce proporcionalmente a R para todo L <= R

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ah! Danado, se eu tivesse atentado esses dois gráficos na Wikipedia antes... Estava tão focado nos algoritimos de conversão inter ColorSpaces que passou batido.

 

Só não entendi o segundo. De onde veio o cubo do Chroma? Ele está "dentro" do gráfico da Matiz? Foi isso que me pareceu. Mas daí vi o branco, e como ele não pertence ao Matiz e sim à Luminosidade fiquei na dúvida.

 

Então toda "estrutura" dos nós da AVL se baseará nesses pontos-chave, definido pelas "bolinhas" sendo esses valores a base para busca, certo?

 

Agora, para o Evandro.

 

Não sei como seria possível esse Sistema no HSL. Testando minuciosamente percebi que para ser preto a cor tem ter até apenas 2% de Saturação e não única e exclusivamente zero.

 

Para ser branco tem de ter 98.5% à 100% de Luminosidade para ser branco.

 

E 50% de Saturação e 100% de Luminosidade para ser pura (cores do gráfico circular acima, de ângulos definidos)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Modelo cônico de base única (como eu propus)

http://www.ncsu.edu/scivis/lessons/colormodels/hexacone-6.jpg

 

A imagem deriva δφ/δR, restando apenas a integração no eixo longitudinal ʃ(L0-L1).

 

Girando a imagem no HUE, (Integrando ʃ(φ0-φ2π) ), temos um cone invertido.

 

O modelo bicônico, citado por você presente na wikipedia, atende efetivamente ao seu questionamento sobre 50% de luminosidade e 100% de saturação (e não o contrário...

  Citar

E 50% de Saturação e 100% de Luminosidade para ser pura (cores do gráfico circular acima, de ângulos definidos)

...)

 

http://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/HSL_color_solid_dblcone_chroma_gray.png/197px-HSL_color_solid_dblcone_chroma_gray.png

 

  Citar

Só não entendi o segundo. De onde veio o cubo do Chroma? Ele está "dentro" do gráfico da Matiz? Foi isso que me pareceu. Mas daí vi o branco, e como ele não pertence ao Matiz e sim à Luminosidade fiquei na dúvida.

Basta girar o cubo na base preto-branco e você tem o mesmo gráfico do último link que eu postei.

 

Quanto à rigorosidade das cores, varia uma porcentagem da acuidade e educação visual de quem enxerga e o tipo de mídia utilizado (qualidade do monitor, projetor, definição de impressão, etc.)

 

Quantas cores você conseguiu destilar exatamente?

 

Existe um padrão de cores p/ web chamado Websafe que se propõe a utilizar cores que possam ser utilizadas - com segurança - em qualquer tipo de mídia, limitada ou não.

 

A sua variação se dá de 51 em 51 valores na escala RGB medida em decimais. Através de algoritmos semelhantes ao que você quer chegar, os dispositivos aproximam qualquer cor de uma das 216 (6³) cores disponíveis.

 

http://en.wikipedia.org/wiki/Web_colors#Web-safe_colors

 

Note que o cone que lhe passei na primeira imagem, segue os padrões websafe.

 

O propósito disso é reduzir ainda mais a sua paleta diminuindo o número de procuras na sua árvore, além de gerar/utilizar um padrão (já existente).

 

Edit Apenas para reforçar, note como a saturação aponta para 240 enquanto a luminosidade equivale exatamente à metade (120).

http://img267.imageshack.us/img267/2591/semttulo1ae.jpg

 

É de vital importância entender essa relação no cone (seja ele duplo ou não) para fins de utilização correta do mapa.

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 27/09/2010 at 19:15, 'Evandro Oliveira' disse:

Podemos estabelecer algumas relações que ajudarão na aplicabilidade dos recursos (que serão destilados pelo JBN [eu é que não vou fazer!]).

Na verdade, Evandro, tudo o que precisamos é de um hash map.

 

A implementação de um Hash Map, normalmente, é muito mais complexa do que uma AVL devido ao algorítimo do hash e questões como resolução de colisão.

 

Porém, para nossa felicidade, não precisaremos lidar com isso nesse problema específico.

 

Um Map nada mais é que uma estrutura de dados que armazena um par K => V, onde K é a chave e V é um valor para a chave (ou uma lista de valores).

 

Em um Map, jamais teremos duas chaves que representam o mesmo valor e, exatamente nesse ponto, que está a complexidade do Hash Map que é criar um algorítimo de cálculo de hash com a menor possibilidade de colisão possível.

 

No nosso caso, precisamos do seguinte:

 

Imagem Postada

 

Como conseguimos isso ?

 

Simples, nosso hash será calculado com base no radiano da tonalidade:

 

Vejamos:

 

#B0171F http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 356

#E066FF http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 287

#6C7B8B http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 210

#00C78C http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 162

#32CD32 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 120

#FFFF00 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 60

#838B83 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 120

 

xrad = x * 180º/π

 

Nosso hash:

 

hash(x) = 6 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Se hue for indefinido (tons de cinza)

hash(x) = ( x * 180º/π ) % 6 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Se hue >= 0

 

Dessa forma:

 

0 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivados de vermelho

1 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivados de amarelo

2 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivados de verde

3 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivados de ciano

4 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivados de azul

5 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivados de violeta

 

Calculando:

 

#B0171F http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 356

( (x * 180º/π) % 6) => ( (356º * 180º/π) % 6) => 6.2133721370998 % 6 => 0 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivado de Vermelho

 

 

#E066FF http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 287

( (x * 180º/π) % 6) => ( (287º * 180º/π) % 6) => 5.0090949532237 % 6 => 5 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivado de Violeta

 

 

#6C7B8B http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 210

( (x * 180º/π) % 6) => ( (210º * 180º/π) % 6) => 3.6651914291881 % 6 => 3 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivado de Ciano

 

 

#00C78C http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 162

( (x * 180º/π) % 6) => ( (162º * 180º/π) % 6) => 2.8274333882308 % 6 => 2 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivado de Verde

 

 

#32CD32 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 120

#838B83 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 120

( (x * 180º/π) % 6) => ( (120º * 180º/π) % 6) => 2.0943951023932 % 6 => 2 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivado de Verde

 

 

#FFFF00 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Hue: 60

( (x * 180º/π) % 6) => ( (60º * 180º/π) % 6) => 1.0471975511966 % 6 => 1 http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Derivado de Amarelo

 

 

 

Dessa forma temos a chave do nosso Map e podemos utilizar nossa AVL para localizar rapidamente uma determinada cor em um grupo qualquer.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Nota: Para quem estiver acompanhando o tópico, por curiosidade ou aprendizado, o operador "%" remete à sua função lógica (programação) que é o operador módulo/resto, e não à aplicação matemática (porcento), que poderia gerar confusão.

 

Estamos fazendo:

 

resto_da_divisão(x, 6);

e não

 

porcento_de(6, x);

João, muito prática a implementação. 2 Perguntas, eu tiro o HUE pelo par RGB? Existe alguma maneira de fazer 2(ou mais) AVL's convergirem para o mesmo objeto?

 

No caso, se eu compreendi corretamente, teremos 7 AVL's (Uma para cada HUE base e uma para tons de cinza). Seria possível fazer 4 AVL's primárias (CMYK like) e as ramificações das RGB se "cruzarem" no caminho, exatamente como acontece com o arco HUE?

 

Edit Utilizando apenas a escala Websafe(216), removendo os tons de cinza (6), teríamos 35 itens por árvore. Removendo o item de topo e dividindo as ramificações teríamos 17 "pra cada lado", correto?

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 28/09/2010 at 13:51, 'Evandro Oliveira' disse:

João, muito prática a implementação. 2 Perguntas, eu tiro o HUE pelo par RGB? Existe alguma maneira de fazer 2(ou mais) AVL's convergirem para o mesmo objeto?

 

Sim, o cálculo é feito assim:

 

public function getHue(){
$max = max( array( $this->r , $this->g , $this->b ) );
$min = min( array( $this->r , $this->g , $this->b ) );
$diff = $max - $min;

if ( $diff != 0 ){
	switch ( $max ){
		case $this->r:
			if ( $this->g >= $this->b ){
				return 60 * ( ( $this->g - $this->b ) / $diff );
			} else {
				return 60 * ( ( $this->g - $this->b ) / $diff ) + 360;
			}
		case $this->g:
			return 60 * ( ( $this->b - $this->r ) / $diff ) + 120;
		case $this->b:
			return 60 * ( ( $this->r - $this->g ) / $diff ) + 240;
	}
} else {
	return null;
}
}

 

  Em 28/09/2010 at 13:51, 'Evandro Oliveira' disse:

No caso, se eu compreendi corretamente, teremos 7 AVL's (Uma para cada HUE base e uma para tons de cinza). Seria possível fazer 4 AVL's primárias (CMYK like) e as ramificações das RGB se "cruzarem" no caminho, exatamente como acontece com o arco HUE?

 

Sim,

 

Na verdade, eu terminei a implementação de todo o código já fazem vários dias, estou postando de pouquinho para facilitar a compreensão.

 

Mas a ideia é que possamos fazer isso sim, seja utilizando CMYK ou a paleta PANTONE (por exemplo).

 

Assim que fechar a questão do Map, postarei a implementação da AVL já orientada a objetos e as interfaces para um objeto Comparable e também a implementação do Map.

 

Com essas implementações, faremos uma adaptação para busca por proximidade, que finaliza a solução do problema.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

De onde veio a conclusão desse módulo 6? Testes intensivos de sua parte ou conclusões de outros trabalhos já conhecidos?

 

Sobre esse mapeamento, porque não foram incluídos o Laranja e o Rosa (que apesar de estar entre o Roxo/Violeta e a segunda aparição de vermelho, ainda possui tonalidades bem distintas)?

 

Sobre a pergunta do Evandro, do CMYK-like, apesar de o padrão CMYK não ser lá muito bem definido, tanto que há até uma citação na Wikipedia quanto a implementação de um algoritimo de conversão CMYK-RGB, qual seria o problema em, dada a cor a ser testada, convertê-la para HSL e comparar com essa mesma AVL?

 

Não será uma detecção perfeita pela própria limitação do CMYK-RGB (eu não consegui uma forma de fazer CMYK-HSL, então, passo por RGB primeiro), mas ainda assim, funcional. Ou não?

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 29/09/2010 at 12:51, 'Bruno Augusto' disse:

De onde veio a conclusão desse módulo 6? Testes intensivos de sua parte ou conclusões de outros trabalhos já conhecidos?

 

É uma aproximação, ao meu modo de ver, bastante eficiente (pelo menos até onde quero chegar), se a margem de erro de 4.5% for grande demais para seu objetivo você pode ajustar o algorítimo.

 

  Em 29/09/2010 at 12:51, 'Bruno Augusto' disse:

Sobre esse mapeamento, porque não foram incluídos o Laranja e o Rosa (que apesar de estar entre o Roxo/Violeta e a segunda aparição de vermelho, ainda possui tonalidades bem distintas)?

 

Como eu disse para o Evandro, você pode utilizar as 6 cores que eu usei, 4 ou N cores básicas, isso é indiferente. Você decide quantas quer utilizar.

 

Estou apenas demonstrando como resolver o problema e, para facilitar os cálculos, estou utilizando essas 6 (por isso rad(x)%6).

 

EDIT:

 

Não sei se perceberam, mas essas 6 cores, na verdade, são: RGBCMY + K

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Citar

Não sei se perceberam, mas essas 6 cores, na verdade, são: RGBCMY + K

Perfeitamente, por isso "cunhei" o termo CMYK-like. Continuaríamos a trabalhar no formato RGB/HSL mas, como dividimos em árvores, precisaríamos de uma árvore para a escala de cinza (agiliza muito), daí a separação do blacK, gerando um sistema parecido(like) com CMYK.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim, a escala de cinza fica na "posição 6" do nosso Map, qualquer cor que o Hue for indefinido (null) ele estará nessa posição.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Hmmmmm..... Interessante.

 

Quanto a aproximação, sem problemas, era só curiosidade mesmo.

 

So far, so good...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ok Bruno,

 

Lamento novamente pela demora, muita correria por aqui.

 

Vejamos,

 

IObject.php

 

  Mostrar conteúdo oculto

 

Object.php

 

  Mostrar conteúdo oculto

 

Comparable

 

  Mostrar conteúdo oculto

 

NodeBalance.php

 

  Mostrar conteúdo oculto

 

Node.php

 

  Mostrar conteúdo oculto

 

AVLNode.php

 

  Mostrar conteúdo oculto

 

AVLTree.php

 

  Mostrar conteúdo oculto

 

Color.php

 

  Mostrar conteúdo oculto

 

RGB.php

 

  Mostrar conteúdo oculto

 

Shade.php

 

  Mostrar conteúdo oculto

 

Shades.php

 

  Mostrar conteúdo oculto

 

 

Usando

<?php
$list = array(
new RGB( 0 , 0 , 0 , 'Black' ),
new RGB( 128 , 0 , 0 , 'Dark Red' ),
new RGB( 255 , 0 , 0 , 'Red' ),
new RGB( 255 , 0 , 255 , 'Pink' ),
new RGB( 0 , 128 , 128 , 'Teal' ),
new RGB( 0 , 128 , 0 , 'Green' ),
new RGB( 0 , 255 , 0 , 'Bright Green' ),
new RGB( 0 , 255 , 255 , 'Turquoise' ),
new RGB( 0 , 0 , 128 , 'Dark Blue' ),
new RGB( 128 , 0 , 128 , 'Violete' ),
new RGB( 0 , 0 , 255 , 'Blue' ),
new RGB( 192 , 192 , 192 , 'Gray 25%' ),
new RGB( 128 , 128 , 128 , 'Gray 50%' ),
new RGB( 128 , 128 , 0 , 'Dark Yellow' ),
new RGB( 255 , 255 , 0 , 'Yellow' ),
new RGB( 255 , 255 , 255 , 'White' ),
);

$shades = new Shades();
$shades->map( new Shade( 'vermelho'	,	0 ) );
$shades->map( new Shade( 'amarelo'	, 60 ) );
$shades->map( new Shade( 'verde'	, 123 ) );
$shades->map( new Shade( 'ciano'	, 180 ) );
$shades->map( new Shade( 'azul'		, 240 ) );
$shades->map( new Shade( 'violeta'	, 300 ) );
$shades->map( new Shade( 'cinza'	, null ) );

foreach ( $list as $rgb ){
$shades->insert( $rgb );
}

 

Saída

Inserindo #000000 como cinza
Inserindo #800000 como vermelho
Inserindo #FF0000 como vermelho
Inserindo #FF00FF como violeta
Inserindo #008080 como ciano
Inserindo #008000 como verde
Inserindo #00FF00 como verde
Inserindo #00FFFF como ciano
Inserindo #000080 como azul
Inserindo #800080 como violeta
Inserindo #0000FF como azul
Inserindo #C0C0C0 como cinza
Inserindo #808080 como cinza
Inserindo #808000 como amarelo
Inserindo #FFFF00 como amarelo
Inserindo #FFFFFF como cinza

A partir desse momento, se tudo tiver sido compreendido, começamos a discutir o algorítimo para melhorar a busca por proximidade e escreveremos nosso próprio heap.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, demorei para postar por estar terminando outra etapa tão importante quanto do sistema.

 

Analisei todos os codigos e surgiram um monte algumas dúvidas. Vou listá-las:

 

No Construtor de AVLNode, o tipo de $value poderia ser Countable, tornando desnecesária a Exception manualmente disparada?

 

Não entendi muito bem os métodos de rotação.

 

Em RGB::compare(), o tipo do parâmetro não deveria ser Color?

 

Em Shade, o que seria static $PI dentro do construtor?

 

Em Shades::insert(), vale a mesma da primeira pergunta, mas sendo o tipo Color

 

Por fim, porquê Shades::search() está vazio? É temporário (próxima etapa)?

 

Sobre as saídas, visualmente algumas cores não batem, como por exemplo #FF00FF

(fuchsia, rosa ou magenta).

 

Para resolver isso possa adicionar novas Shades, com outros ângulos?

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.