Не понимаю уравнение эффекта плазмы Грех на 2d массив для матрицы светодиодных лент в Python - PullRequest
0 голосов
/ 22 марта 2019

Я успешно получил приведенный ниже код от Github , работающего над Raspberry Pi и светодиодной матрицей 8 x 16 с использованием ШИМ на выводе 18. Поскольку для создания графики используются функции sin и cos, я хотел попробовать сделать свои собственные эффекты. Я позаимствовал эффект из этой страницы, но когда я включил его в функцию, у меня только красные светодиоды.

Пример кода плазмы

import time
import math
import colorsys
from neopixel import *

# LED strip configuration:
LED_COUNT = 128      # Number of LED pixels.
LED_PIN = 18      # GPIO pin connected to the pixels (must support PWM!).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10       # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 128  # Set to 0 for darkest and 255 for brightest
# True to invert the signal (when using NPN transistor level shift)
LED_INVERT = False

# Draws an animated horizontal bar test pattern for alignment
def bar(w,h,t):
    out = [ Color( 0, 0, 0 ) for x in range( w * h ) ]
    y = int(t * 4) % h
    for x in range(0, w):
        out[ x + y * w ] = Color( 10, 10, 10 )
    return out

# Draws an animated colorful plasma effect
def plasma (w, h, t):
    out = [ Color( 0, 0, 0 ) for x in range( w * h ) ]
    for x in range( w ):
        for y in range( h ):
            hue = 4.0 + math.sin( t + x ) + math.sin( t + y / 4.5 ) \
                + math.sin( x + y + t ) + math.sin( math.sqrt( ( x + t ) ** 2.0 + ( y + 1.5 * t ) ** 2.0 ) / 4.0 )
            hsv = colorsys.hsv_to_rgb( hue / 8.0, 1, 1 )
            out[ x + y * w ] = Color( *[ int( round( c * 10.0 ) ) for c in hsv ] )
    return out

# Main program logic follows:
if __name__ == '__main__':
    # Create NeoPixel object with appropriate configuration.
    strip = Adafruit_NeoPixel(
        LED_COUNT,
        LED_PIN,
        LED_FREQ_HZ,
        LED_DMA,
        LED_INVERT,
        LED_BRIGHTNESS
    )
    # Intialize the library (must be called once before other functions).
    strip.begin()

    t = 0.0                                                                       # time
    dt = 0.1                                                                      # speed of time

    for i in range( 0, strip.numPixels(), 1):                                     # iterate over all LEDs
        strip.setPixelColor( i, Color( 0, 0, 0 ) )                                # set LED to black (off)

    while True:
        t = t + dt                                                                # increment time
        pic = plasma( 8, 16, t )                                                  # render plasma of size 8x8 at time t
        #pic = bar( 8, 16, t )                                                    # remove comment for bar test pattern
        for i in range( 0, strip.numPixels(), 1 ):                                # iterate over all LEDs
            strip.setPixelColor(                                                  # set pixel to color in picture
                i,
                pic[ i ]
            )
        strip.show()                                                              # update LEDs
        time.sleep(0.01) 

Функция плазмы

def plasma (w, h, t):
    out = [ Color( 0, 0, 0 ) for x in range( w * h ) ]
    for x in range( w ):
        for y in range( h ):
            hue = 4.0 + math.sin( t + x ) + math.sin( t + y / 4.5 ) \
                + math.sin( x + y + t ) + math.sin( math.sqrt( ( x + t ) ** 2.0 + ( y + 1.5 * t ) ** 2.0 ) / 4.0 )
            hsv = colorsys.hsv_to_rgb( hue / 8.0, 1, 1 )
            out[ x + y * w ] = Color( *[ int( round( c * 10.0 ) ) for c in hsv ] )
    return out

Модифицированная функция, которая показывает только красный

Уравнение оттенка изменено. Формула с этого сайта о плазменной графике.

def plasma (w, h, t):
    out = [ Color( 0, 0, 0 ) for x in range( w * h ) ]
    for x in range( w ):
        for y in range( h ):
            hue = int(math.sin((x+y)/4.0)) # Throws error without int
            hsv = colorsys.hsv_to_rgb( hue / 8.0, 1, 1 )
            out[ x + y * h ] = Color( *[ int( round( c * 10.0 ) ) for c in hsv ] )
    return out

Я также не понимаю, как работает эта запись массива.

out[ x + y * h ] = Color( *[ int( round( c * 10.0 ) ) for c in hsv ] )

Я понимаю, что это выравнивает массив, но не знаю как.

Пожалуйста, сообщите. Спасибо.

1 Ответ

0 голосов
/ 25 марта 2019

С помощью друга я разобрался с этой функцией и теперь могу создавать свои собственные шаблоны.

Я набрал во втором примере с сайта https://lodev.org/cgtutor/plasma.html неправильно.

Я также понял, что все значения в цветовом пространстве HSV находятся между 0 и 1, поэтому мне пришлось разделить на 256, чтобы получить значимые значения.

hue = ((128 +(128*math.sin( y )/8.0)))))256

В примере функции строка hsv = colorsys.hsv_to_rgb( hue / 8.0, 1, 1 ) переменная оттенка влияет только на 1-ю часть триплета. Ценности, которые я передавал, делали оттенок красным. Чтобы сделать шаблоны греха, как в примере, значение оттенка или пикселя должно быть передано третьей части hsv как часть значения.

hsv = colorsys.hsv_to_rgb( 1, 1, hue ) Это по-прежнему делает красный, потому что первое значение равно 1. Если вы измените первое значение, то вы получите другие цвета. Например .5 дает синий цвет.

Ключ должен поместить сгенерированные значения sin в слот hsv "value" для генерации градиентов.

out[ x + y * h ] = Color( *[ int( round( c * 10.0 ) ) for c in hsv ] )

Я тоже понимаю эту часть кода. Запутывающей частью была out[ x + y * h] часть. Теперь я понимаю, что это назначает положение значений пикселей в массиве, которые должны быть переданы в цепочку светодиодов.

Я должен был изменить этот код, потому что мои жилы светодиодов соединены так, что сигнал чередуется в матрице.

if y % 2 == 0: # if column even
    out[ x + (h * y)] = color ( *[int( round( c * plasmaBright ) ) for c in hsv ] )
else: # if column odd
    out[ (y * h) + (h -1 -x) ] = color ( *[int( round( c * plasmaBright ) ) for c in hsv ] )

Этот код проверяет, является ли столбец четным, и переворачивает все остальные.

...