Disco Codificador

Gonzalo Mena Mendoza

Dada una serie de (2^n) cadenas binarias n bits, dibujar el disco codificador de pistas concénticas correspondiente.

Referencias

[1]  Donald E. Knuth. "Generating All Possibilities", The Art of Computer Programming, Volumen 4, prefascículo 2a, [en línea], [versión del 31 de marzo de 2005]
<http://www-cs-faculty.stanford.edu/~knuth/news.html>
<http://www-cs-faculty.stanford.edu/~knuth/fasc2a.ps.gz>

[2]  Gonzalo Mena Mendoza. "Código Binario Gray", [en línea], [consulta 20 de abril de 2005]
<http://mena.com.mx/gonzalo/maestria/algor/CodigoBinarioGray.nb>

Se puede identificar la posición de un disco rotatorio que ha sido dividido en (2^n) partes utilizando n sensores, cada uno de los cuales tiene que distinguir entre el blanco y el negro de la pista concéntrica correspondiente.

La siguiente figura muestra el resultado deseado. Del lado izquierdo ese encuentra el disco para el órden lexicográfico de n = 4; y del lado derecho, el disco del código binario Gray respectivo[1].

Análisis

La construcción del disco codificador puede dividirse en las siguientes etapas:
1. Generación de las series binarias
2. Construcción de las pistas concéntricas
3. Separación de las pistas
4. Separación de los sectores
5. Generación de las etiquetas radiales.

Series Binarias

Orden Lexicográfico

OrdenLexicográfico[n_] :=  
      IntegerDigits[Range[0, (2^n) - 1], 2, n]

OrdenLexicográfico[3]

Código Gray

Se puede definir el Código Gray de la siguiente manera recursiva [2]:

CódigoGray[0] := {{}}
CódigoGray[n_] := 
      Join[
Map[Prepend[#, 0] &, 
          CódigoGray[n - 1]], 
Map[Prepend[#, 1] &, 
          Reverse[CódigoGray[n - 1]]]
]

CódigoGray[3]

Pistas

El problema principal consiste en dibujar las pistas codificadoras concéntricas. El disco de divide en (2^n) sectores, uno por elemento de la serie s. Para cada sector se dibujan n secciones de pista, cada una de las secciones corresponde a un dígito del elemento en cuestión. El dígito más significativo corresponde a la pista más interna.El 1 se representa con negro y el 0 con blanco. Para hacer más distingible la pista más significativa, se pueden comenzar a dibujar las pistas a partir de un radio r.

Pistas[s_,  n_,  r_] := {
Table[   
Table[  (* 
                    una sección de pista por dígito *) 
{
GrayLevel[
                        1 - s[[
                              i]][[
                            j]]],  
Disk[{0, 0}, 
                        j + r, {((2  π)/(2^n)) (i - 
                                1), ((2  π)/(2^n)) i}]
},
{j, n, 1,  -1}   
],
{i, 1, (2^n)}
],
{GrayLevel[1],  Disk[{0, 0}, r]}   
}
Pistas[s_] :=  
      Pistas[s,  (1/Log)[Length[s], 2], 1]

Pistas[OrdenLexicográfico[3]];
Show[Graphics[%], AspectRatio -> Automatic]

Aros Separadores

Es conveniente separar las pistas concéntricas para hacerlas más visibles.

Aros[n_, r_] := {GrayLevel[1], 
        Thickness[0.02], 
Table[
          Circle[{0, 0}, i + r], {i, 0, 
            n}]
}
Aros[n_]  :=  Aros[n, 1]

Aros[3]
Show[Graphics[%], AspectRatio -> Automatic,  
      Background -> GrayLevel[0]]

Radios

Así mismo, es conveniente separar los sectores.

Radios[n_, r_]:= {
Table[
Line[{{r Cos[((2  π)/(2^n)) i], 
                r Sin[((2  π)/(2^n)) i]}, {(n + 
                      r) Cos[((2  π)/(2^n)) i], (n + 
                      r) Sin[((2  π)/(2^n)) 
                      i]}}], 
{i, 1, 
            (2^n)}
], 
Circle[{0, 0}, r], 
        Circle[{0, 0}, n + r]   
}
Radios[n_]  :=  
      Radios[n, 1]

Radios[5];
Show[Graphics[%], AspectRatio -> Automatic]

Etiquetas

Texto Radial

Se requiere de una función que dibuje todos los elementos de una serie de manera radial.

Etiquetas[s_, m_, r_]:= {
Table[
Text[
TableForm[
                    s[[i + 1]], 
                    TableDirections -> {Row, Column}, 
                    TableSpacing -> 0]   ,  
{r Cos[((2  π)/m) i], 
                    r Sin[((2  π)/m) i]},   
{ 0,  0},   
{ Cos[((2  π)/m) i],  
                    Sin[((2  π)/m) i]}   
],
{i, 0, m - 1}
],
{GrayLevel[1],  
            Circle[{0, 0}, r  +  1]}   
}
Etiquetas[s_] :=  
      Etiquetas[s,  Length[s], Length[s[[1]]] + 2]

Etiquetas[
        OrdenLexicográfico[4]];
Show[Graphics[%], AspectRatio -> Automatic]

Diferencias entre elementos contiguos

Se quiere que para cada sector no sólo se muestre el valor numérico del elemento sino que entre sectores se muestren los dígitos que son diferentes entre elemento contiguos.

MostrarDiferencias[s_]:=
Flatten[
Table[   
{
Flatten[
Table[   
{If[   
\(\(s[\([i]\)]\)[\([j]\)] == \(\(RotateRight[
                                    s]\)[\([i]\)]\)[\([j]\)], 
\(s[\([i]\)]\)[\([j]\)], "*"\)
]} , 
{j, 1, 
                          Length[s[[1]]]}
]
],
s[[i]]   
},
{i, 1, Length[s]}
],
1
]

OrdenLexicográfico[3]
MostrarDiferencias[%]

Disco Codificador

La construcción del disco codificador se reduce a reunir las funciones anteriores.

DiscoCodificador[s_, 
        n_] := 
{
Pistas[
          s], 
Aros[n], 
Radios[
          n], 
Etiquetas[
          MostrarDiferencias[s]]
}
DiscoCodificador[s_] :=  
      DiscoCodificador[s,  (1/Log)[Length[s], 2]]

Resultado

n = 4;
\(\(Show[
GraphicsArray[{
Graphics[
DiscoCodificador[
                OrdenLexicográfico[
                  n]], 
AspectRatio -> Automatic, \ 
              TextStyle -> {FontSize -> 9}, 
              PlotLabel -> "Orden Lexicográfico"
], 
Graphics[
DiscoCodificador[
                CódigoGray[
                  n]], 
AspectRatio -> Automatic, \ 
              TextStyle -> {FontSize -> 9}, 
              PlotLabel -> "Código Gray"
]
}
]];\)\)