Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problemilla Matemático

Iniciado por tewe76, 09 de Junio de 2005, 12:18:17 PM

« anterior - próximo »

tewe76

 Las mates no son lo mío, a ver si me podéis ayudar...

Tengo estas dos funciones:
Function DDRGBInicializa(PrimarySurface As DirectDrawSurface7)
'inicializa los valores para DDRGB basándose en el pixelformat
'de primarysurface (en nuestro caso será el PrimaryBuffer)
Dim PixelFormat As DDPIXELFORMAT
Dim Mask As Long
Dim ZeroBitCount As Long
Dim OneBitCount As Long
PrimarySurface.GetPixelFormat PixelFormat
'Red
Mask = PixelFormat.lRBitMask
ZeroBitCount = 0 ' Count zero bits
Do While (Mask And 1) = 0
   ZeroBitCount = ZeroBitCount + 1: Mask = Mask \ 2 ' Shift right
Loop
OneBitCount = 0 ' Count one bits
Do While (Mask And 1) = 1
   OneBitCount = OneBitCount + 1: Mask = Mask \ 2 ' Shift right
Loop
DDRGBRedShiftRight = 2 ^ (8 - OneBitCount) ' Shift right 8-OneBitCount bits
DDRGBRedShiftLeft = 2 ^ ZeroBitCount ' Shift left ZeroBitCount bits
'Green
Mask = PixelFormat.lGBitMask
ZeroBitCount = 0 ' Count zero bits
Do While (Mask And 1) = 0
   ZeroBitCount = ZeroBitCount + 1: Mask = Mask \ 2 ' Shift right
Loop
OneBitCount = 0 ' Count one bits
Do While (Mask And 1) = 1
   OneBitCount = OneBitCount + 1: Mask = Mask \ 2 ' Shift right
Loop
DDRGBGreenShiftRight = 2 ^ (8 - OneBitCount) ' Shift right 8-OneBitCount bits
DDRGBGreenShiftLeft = 2 ^ ZeroBitCount ' Shift left ZeroBitCount bits
'Blue
Mask = PixelFormat.lBBitMask
ZeroBitCount = 0 ' Count zero bits
Do While (Mask And 1) = 0
   ZeroBitCount = ZeroBitCount + 1: Mask = Mask \ 2 ' Shift right
Loop
OneBitCount = 0 ' Count one bits
Do While (Mask And 1) = 1
   OneBitCount = OneBitCount + 1: Mask = Mask \ 2 ' Shift right
Loop
DDRGBBlueShiftRight = 2 ^ (8 - OneBitCount) ' Shift right 8-OneBitCount bits
DDRGBBlueShiftLeft = 2 ^ ZeroBitCount ' Shift left ZeroBitCount bits
End Function

Function DDRGB(Red As Integer, Green As Integer, Blue As Integer) As Long
'le pasamos R, G y B (de 8bits) y devuelve un RGB 16bits
DDRGB = (Red \ DDRGBRedShiftRight) * DDRGBRedShiftLeft + _
   (Green \ DDRGBGreenShiftRight) * DDRGBGreenShiftLeft + _
   (Blue \ DDRGBBlueShiftRight) * DDRGBBlueShiftLeft
End Function


y necesito sacar los valores R,G y B a partir del valor DDRGB(R,G,B) (vamos, la función inversa de DDRGB)

Sé que:
Conseguir RGB a partir de RGB(R, G, B)
iR = lColor Mod 256
iG = (lColor \ 256) Mod 256
iB = lColor \ 65536

pero no sé cómo aplicarlo a mi caso (aunque me da en la nariz que es sencillo, pero ya digo que las mates no son lo mío).

Gracias
Tewe
www.TAPAZAPA.com : Funny and easy to play games for all ages! - Fairy Match - Brain Crash
www.LaRebelionDelBiberon.com : Experiencias de unos padres primerizos

Zaelsius

 
1) VB Sux :P

2) Quizá algo así:

rojo = ( PixelFormat.lRBitMask AND Red ) * DDRGBRedShiftRight
verde = ( PixelFormat.lGBitMask AND Green ) * DDRGBGreenShiftRight
azul = ( PixelFormat.lBBitMask AND Blue ) * DDRGBBlueShiftRight

tewe76

 
Citarrojo = ( PixelFormat.lRBitMask AND Red ) * DDRGBRedShiftRight
verde = ( PixelFormat.lGBitMask AND Green ) * DDRGBGreenShiftRight
azul = ( PixelFormat.lBBitMask AND Blue ) * DDRGBBlueShiftRight
Hombre, pero justamente Red, Green y Blue son los valores que necesito :(

Yo quiero, igual que de "lColor= RGB(R, G, B )"
puedo sacar
"iR = lColor Mod 256
iG = (lColor \ 256) Mod 256
iB = lColor \ 65536"
, de "lColor= DDRGB(R, G, B )"
sacar
"iR = ????
iG = ????
iB = ????"

Venga, ¿quién es el siguiente? :)
Tewe
www.TAPAZAPA.com : Funny and easy to play games for all ages! - Fairy Match - Brain Crash
www.LaRebelionDelBiberon.com : Experiencias de unos padres primerizos

Zaelsius

 ups, sustituye Red, Blue y Green por el entero con el color

edit:

o sea, esto


rojo = ( PixelFormat.lRBitMask AND Color ) * DDRGBRedShiftRight
verde = ( PixelFormat.lGBitMask AND Color ) * DDRGBGreenShiftRight
azul = ( PixelFormat.lBBitMask AND Color ) * DDRGBBlueShiftRight

tewe76

 Zae, tu solución no sirve :(

A ver, haciendo pruebas, me he dado cuenta de que:
DDRGB(255,0,0)=63488=lRBitMask
DDRGB(0,255,0)=2016=lGBitMask
DDRGB(0,0,255)=31=lBBitMask

En el fondo, creo que es simplemente:
BITS:
15 14 13 12 11   10 09 08 07 06 05   04 03 02 01 00
ROJO                        VERDE                       AZUL

Es decir, en los bits 15-11 está el valor de rojo (multiplicándolo * 2^3), en los bits 10-05 está el valor de verde (multiplicándolo * 2^2) y en los bits 04-00 está el valor de azul (multiplicándolo * 2^3)
Vamos, que mi problema se reduce a extraer 3 grupos de bits. Pero ojo, tened en cuenta que uso VB, no me sirven funciones de C.

Mis conocimientos de operaciones binarias son muy básicos. ¿Alguna idea?
Tewe
www.TAPAZAPA.com : Funny and easy to play games for all ages! - Fairy Match - Brain Crash
www.LaRebelionDelBiberon.com : Experiencias de unos padres primerizos

senior wapo

 Lo mio no es el Visual Basic, pero vamos:

en inicializa:

mascaraRojo = ( 2 ^ onebitcount  ) - 1     <== usa onebitcount del rojo
mascaraAzul = ( 2 ^ onebitcount  ) - 1      <== usa onebitcount del azul
mascaraVerde = ( 2 ^ onebitcount  ) - 1    <== usa onebitcount del verde

y en la funcion:
rojo = ( color / DDRGBRedShiftLeft ) AND mascaraRojo
verde = ( color / DDRGBGreenShiftLeft ) AND mascaraVerde
azul = ( color / DDRGBBlueShiftLeft ) AND mascaraAzul


Nota: Aqui AND es la operacion binaria AND, si Visual Basic no la tiene (lo dudo) cambiala  por:   Mod (mascaraRojo+1)
ejemplo:
rojo = ( color / DDRGBRedShiftLeft ) Mod (mascaraRojo+1)

Zaelsius

 El AND de VB funciona también como operador "bitwise", segun la doc de la MSDN es recomendable ponerlo entre paréntesis porque tiene la menor precedencia.

http://msdn.microsoft.com/library/default....ml/vaoprand.asp

Edit: ahora que me fijo, lo mío deberia ser con divisiones :P


rojo = ( PixelFormat.lRBitMask AND Color ) / DDRGBRedShiftRight
verde = ( PixelFormat.lGBitMask AND Color ) / DDRGBGreenShiftRight
azul = ( PixelFormat.lBBitMask AND Color ) / DDRGBBlueShiftRight


samsaga2

 En el caso del VB7 (VB.NET):

AND: puerta logica (como el & del C)
OR: puerta logica (como el | del C)
AndAlso: and exclusivo (como el && del C)
OrElse: or exclusivo (como el || del C)
Shl: shift left (como el << del C)
Shr: shift right (como el >> del C)

Una muestra muy clara de que el VB6 es bastante cutre es que no dispone de operandos tipo AndAlso y OrElse.

tewe76

 Bueno, al final lo he conseguido solucionar de forma más sencilla, sin cálculos binarios ni nada. No está optimizado, ni mucho menos :D, pero funcionar funciona:
'cómo extraer R, G y B de un valor DDRGB (16 bits)
Dim ColorDDRGB As Long
Dim Rojo As Long
Dim Verde As Long
Dim Azul As Long
ColorDDRGB = DDRGB(225, 124, 15)'por ejemplo

'calculo los bits que usa para cada componente
Dim BitsR As Long '5, 6, 5, de normal
Dim BitsG As Long
Dim BitsB As Long

'log(x)=logaritmo neperiano de x
'log(x)/log(y)=logaritmo en base y de x
BitsR = 8 - (Log(DDRGBRedShiftRight) / Log(2))
BitsG = 8 - (Log(DDRGBGreenShiftRight) / Log(2))
BitsB = 8 - (Log(DDRGBBlueShiftRight) / Log(2))

'calculo el valor (0-255) de cada componente
Rojo = ColorDDRGB \ (2 ^ (BitsB + BitsG))
Verde = (ColorDDRGB - Rojo * (2 ^ (BitsB + BitsG))) \ (2 ^ BitsB)
Azul = (ColorDDRGB - Rojo * (2 ^ (BitsB + BitsG)) - Verde * (2 ^ BitsB)) \ (2 ^ 0)
Rojo = Rojo * (2 ^ (8 - BitsR))
Verde = Verde * (2 ^ (8 - BitsG))
Azul = Azul * (2 ^ (8 - BitsB))

'NOTA:la conversión no será exacta porque DDRGB pasa 24bits de info a 16bits,
'por lo que es preciso que se pierda información. Así, de DDRGB(255,7,7) nos
'dirá que R=248, G=4 y B=0 (la precisión de cada componente depende de cuantos
'bits le dedique.
'Ej: R y B:5 bits-> precisión=2^(8-5)=8. G:6 bits-> precisión=2^(8-6)=4)



CitarUna muestra muy clara de que el VB6 es bastante cutre es que no dispone de operandos tipo AndAlso y OrElse
VB6 SÍ tiene XOR, imagino que es el equivalente a OrElse. Respecto al AndAlso, ya no estoy tan seguro.
VB6 no es tan malo... ;)
Tewe
www.TAPAZAPA.com : Funny and easy to play games for all ages! - Fairy Match - Brain Crash
www.LaRebelionDelBiberon.com : Experiencias de unos padres primerizos






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.