Plasma effect

From Rosetta Code
Revision as of 18:01, 4 October 2017 by Aamrun (talk | contribs) (Added ASCII and Graphics implementations in C.)
Task
Plasma effect
You are encouraged to solve this task according to the task description, using any language you may know.

The plasma effect is a visual effect created by applying various functions, notably sine and cosine, to the color values of screen pixels. When animated (not a task requirement) the effect may give the impression of a colorful flowing liquid.


Task

Create a plasma effect.

See also



C

ASCII version for Windows

If you don't want to bother with Graphics libraries, try out this nifty implementation on Windows : <lang C> /*Abhishek Ghosh, 4th October 2017*/

  1. include<windows.h>
  2. include<stdlib.h>
  3. include<stdio.h>
  4. include<time.h>
  5. include<math.h>
  1. define pi M_PI

int main() { CONSOLE_SCREEN_BUFFER_INFO info;

   int cols, rows;

time_t t; int i,j;

   GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
   cols = info.srWindow.Right - info.srWindow.Left + 1;
   rows = info.srWindow.Bottom - info.srWindow.Top + 1;

HANDLE console;

console = GetStdHandle(STD_OUTPUT_HANDLE);

system("@clear||cls");

srand((unsigned)time(&t));

for(i=0;i<rows;i++) for(j=0;j<cols;j++){ SetConsoleTextAttribute(console,fabs(sin(pi*(rand()%254 + 1)/255.0))*254); printf("%c",219); }

getchar();

return 0; } </lang>

Graphics version

And here's the Graphics version, requires the WinBGIm library. Prints out usage on incorrect invocation. <lang C> /*Abhishek Ghosh, 4th October 2017*/

  1. include<graphics.h>
  2. include<stdlib.h>
  3. include<math.h>
  4. include<time.h>
  1. define pi M_PI

void plasmaScreen(int width,int height){

int x,y,sec; double dx,dy,dv; time_t t;

initwindow(width,height,"WinBGIm Plasma");

while(1){ time(&t); sec = (localtime(&t))->tm_sec;

for(x=0;x<width;x++) for(y=0;y<height;y++){ dx = x + .5 * sin(sec/5.0); dy = y + .5 * cos(sec/3.0);

dv = sin(x*10 + sec) + sin(10*(x*sin(sec/2.0) + y*cos(sec/3.0)) + sec) + sin(sqrt(100*(dx*dx + dy*dy)+1) + sec);

setcolor(COLOR(255*fabs(sin(dv*pi)),255*fabs(sin(dv*pi + 2*pi/3)),255*fabs(sin(dv*pi + 4*pi/3))));

putpixel(x,y,getcolor()); } delay(1000); } }

int main(int argC,char* argV[]) { if(argC != 3) printf("Usage : %s <Two positive integers separated by a space specifying screen size>",argV[0]); else{ plasmaScreen(atoi(argV[1]),atoi(argV[2])); } return 0; } </lang>

C++

Windows version. <lang cpp>

  1. include <windows.h>
  2. include <math.h>
  3. include <string>

const int BMP_SIZE = 240, MY_TIMER = 987654;

class myBitmap { public:

   myBitmap() : pen( NULL ), brush( NULL ), clr( 0 ), wid( 1 ) {}
   ~myBitmap() {
       DeleteObject( pen ); DeleteObject( brush );
       DeleteDC( hdc ); DeleteObject( bmp );
   }
   bool create( int w, int h ) {
       BITMAPINFO bi;
       ZeroMemory( &bi, sizeof( bi ) );
       bi.bmiHeader.biSize        = sizeof( bi.bmiHeader );
       bi.bmiHeader.biBitCount    = sizeof( DWORD ) * 8;
       bi.bmiHeader.biCompression = BI_RGB;
       bi.bmiHeader.biPlanes      = 1;
       bi.bmiHeader.biWidth       =  w;
       bi.bmiHeader.biHeight      = -h;
       HDC dc = GetDC( GetConsoleWindow() );
       bmp = CreateDIBSection( dc, &bi, DIB_RGB_COLORS, &pBits, NULL, 0 );
       if( !bmp ) return false;
       hdc = CreateCompatibleDC( dc );
       SelectObject( hdc, bmp );
       ReleaseDC( GetConsoleWindow(), dc );
       width = w; height = h;
       return true;
   }
   void clear( BYTE clr = 0 ) {
       memset( pBits, clr, width * height * sizeof( DWORD ) );
   }
   void setBrushColor( DWORD bClr ) {
       if( brush ) DeleteObject( brush );
       brush = CreateSolidBrush( bClr );
       SelectObject( hdc, brush );
   }
   void setPenColor( DWORD c ) {
       clr = c; createPen();
   }
   void setPenWidth( int w ) {
       wid = w; createPen();
   }
   void saveBitmap( std::string path ) {
       BITMAPFILEHEADER fileheader;
       BITMAPINFO       infoheader;
       BITMAP           bitmap;
       DWORD            wb;
       GetObject( bmp, sizeof( bitmap ), &bitmap );
       DWORD* dwpBits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];
       ZeroMemory( dwpBits, bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ) );
       ZeroMemory( &infoheader, sizeof( BITMAPINFO ) );
       ZeroMemory( &fileheader, sizeof( BITMAPFILEHEADER ) );
       infoheader.bmiHeader.biBitCount = sizeof( DWORD ) * 8;
       infoheader.bmiHeader.biCompression = BI_RGB;
       infoheader.bmiHeader.biPlanes = 1;
       infoheader.bmiHeader.biSize = sizeof( infoheader.bmiHeader );
       infoheader.bmiHeader.biHeight = bitmap.bmHeight;
       infoheader.bmiHeader.biWidth = bitmap.bmWidth;
       infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD );
       fileheader.bfType    = 0x4D42;
       fileheader.bfOffBits = sizeof( infoheader.bmiHeader ) + sizeof( BITMAPFILEHEADER );
       fileheader.bfSize    = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;
       GetDIBits( hdc, bmp, 0, height, ( LPVOID )dwpBits, &infoheader, DIB_RGB_COLORS );
       HANDLE file = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
       WriteFile( file, &fileheader, sizeof( BITMAPFILEHEADER ), &wb, NULL );
       WriteFile( file, &infoheader.bmiHeader, sizeof( infoheader.bmiHeader ), &wb, NULL );
       WriteFile( file, dwpBits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, NULL );
       CloseHandle( file );
       delete [] dwpBits;
   }
   HDC getDC() const     { return hdc; }
   DWORD* bits()          { return ( DWORD* )pBits; }

private:

   void createPen() {
       if( pen ) DeleteObject( pen );
       pen = CreatePen( PS_SOLID, wid, clr );
       SelectObject( hdc, pen );
   }
   HBITMAP bmp; HDC    hdc;
   HPEN    pen; HBRUSH brush;
   void    *pBits; int width, height, wid;
   DWORD    clr;

}; class plasma { public:

   plasma() {
       currentTime = 0; _WD = BMP_SIZE >> 1; _WV = BMP_SIZE << 1;
       _bmp.create( BMP_SIZE, BMP_SIZE ); _bmp.clear();
       plasma1 = new BYTE[BMP_SIZE * BMP_SIZE * 4];
       plasma2 = new BYTE[BMP_SIZE * BMP_SIZE * 4];
       int i, j, dst = 0;
       double temp;
       for( j = 0; j < BMP_SIZE * 2; j++ ) {
           for( i = 0; i < BMP_SIZE * 2; i++ ) {
               plasma1[dst] = ( BYTE )( 128.0 + 127.0 * ( cos( ( double )hypot( BMP_SIZE - j, BMP_SIZE - i ) / 64.0 ) ) );
               plasma2[dst] = ( BYTE )( ( sin( ( sqrt( 128.0 + ( BMP_SIZE - i ) * ( BMP_SIZE - i ) + 
                              ( BMP_SIZE - j ) * ( BMP_SIZE - j ) ) - 4.0 ) / 32.0 ) + 1 ) * 90.0 );
               dst++;
           }
       }
   }
   void update() {
       DWORD dst;
       BYTE a, c1,c2, c3;
       currentTime += ( double )( rand() % 2 + 1 );
       int x1 = _WD + ( int )( ( _WD - 1 ) * sin( currentTime  / 137 ) ),
           x2 = _WD + ( int )( ( _WD - 1 ) * sin( -currentTime /  75 ) ),
           x3 = _WD + ( int )( ( _WD - 1 ) * sin( -currentTime / 125 ) ),
           y1 = _WD + ( int )( ( _WD - 1 ) * cos( currentTime  / 123 ) ),
           y2 = _WD + ( int )( ( _WD - 1 ) * cos( -currentTime /  85 ) ),
           y3 = _WD + ( int )( ( _WD - 1 ) * cos( -currentTime / 108 ) );
       int src1 = y1 * _WV + x1, src2 = y2 * _WV + x2, src3 = y3 * _WV + x3;
       
       DWORD* bits = _bmp.bits();
       for( int j = 0; j < BMP_SIZE; j++ ) {
           dst = j * BMP_SIZE;
           for( int i= 0; i < BMP_SIZE; i++ ) {
               a = plasma2[src1] + plasma1[src2] + plasma2[src3];
               c1 = a << 1; c2 = a << 2; c3 = a << 3;
               bits[dst + i] = RGB( c1, c2, c3 );
               src1++; src2++; src3++;
           }
           src1 += BMP_SIZE; src2 += BMP_SIZE; src3 += BMP_SIZE;
       }
       draw();
   }
   void setHWND( HWND hwnd ) { _hwnd = hwnd; }

private:

   void draw() {
       HDC dc = _bmp.getDC(), wdc = GetDC( _hwnd );
       BitBlt( wdc, 0, 0, BMP_SIZE, BMP_SIZE, dc, 0, 0, SRCCOPY );
       ReleaseDC( _hwnd, wdc );
   }
   myBitmap _bmp; HWND _hwnd; float _ang;
   BYTE *plasma1, *plasma2;
   double currentTime; int _WD, _WV;

}; class wnd { public:

   wnd() { _inst = this; }
   int wnd::Run( HINSTANCE hInst ) {
       _hInst = hInst; _hwnd = InitAll();
       SetTimer( _hwnd, MY_TIMER, 15, NULL );
       _plasma.setHWND( _hwnd );
       ShowWindow( _hwnd, SW_SHOW );
       UpdateWindow( _hwnd );
       MSG msg;
       ZeroMemory( &msg, sizeof( msg ) );
       while( msg.message != WM_QUIT ) {
           if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) != 0 ) {
               TranslateMessage( &msg );
               DispatchMessage( &msg );
           }
       }
       return UnregisterClass( "_MY_PLASMA_", _hInst );
   }

private:

   void wnd::doPaint( HDC dc ) { _plasma.update(); }
   void wnd::doTimer()         { _plasma.update(); }
   static int WINAPI wnd::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
       switch( msg ) {
           case WM_PAINT: {
                   PAINTSTRUCT ps;
                   _inst->doPaint( BeginPaint( hWnd, &ps ) );
                   EndPaint( hWnd, &ps );
                   return 0;
               }
           case WM_DESTROY: PostQuitMessage( 0 ); break;
           case WM_TIMER: _inst->doTimer(); break;
           default: return DefWindowProc( hWnd, msg, wParam, lParam );
       }
       return 0;
   }
   HWND InitAll() {
       WNDCLASSEX wcex;
       ZeroMemory( &wcex, sizeof( wcex ) );
       wcex.cbSize        = sizeof( WNDCLASSEX );
       wcex.style         = CS_HREDRAW | CS_VREDRAW;
       wcex.lpfnWndProc   = ( WNDPROC )WndProc;
       wcex.hInstance     = _hInst;
       wcex.hCursor       = LoadCursor( NULL, IDC_ARROW );
       wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
       wcex.lpszClassName = "_MY_PLASMA_";
       RegisterClassEx( &wcex );
       RECT rc = { 0, 0, BMP_SIZE, BMP_SIZE };
       AdjustWindowRect( &rc, WS_SYSMENU | WS_CAPTION, FALSE );
       int w = rc.right - rc.left, h = rc.bottom - rc.top;
       return CreateWindow( "_MY_PLASMA_", ".: Plasma -- PJorente :.", WS_SYSMENU, CW_USEDEFAULT, 0, w, h, NULL, NULL, _hInst, NULL );
   }
   static wnd* _inst; HINSTANCE _hInst; HWND _hwnd; plasma _plasma;

}; wnd* wnd::_inst = 0; int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) {

   wnd myWnd;
   return myWnd.Run( hInstance );

} </lang>

Ceylon

Be sure to import javafx.base, javafx.graphics and ceylon.numeric in your module file.

Translation of: Java

<lang ceylon> import javafx.application {

   Application

} import javafx.stage {

   Stage

} import javafx.scene {

   Scene

} import javafx.scene.layout {

   BorderPane

} import javafx.scene.image {

   WritableImage,
   ImageView

} import ceylon.numeric.float {

   sin,
   sqrt,
   remainder

} import javafx.scene.paint {

   Color

} import javafx.animation {

   AnimationTimer

}

shared void run() {

   Application.launch(`Plasma`);

}

shared class Plasma() extends Application() {

   function createPlasma(Integer width, Integer height) => [
       for (j in 0:height) [
           for (i in 0:width)
           let (x = i.float, y = j.float)
           ( sin(x / 16.0)
           + sin(y / 8.0)
           + sin((x + y) / 16.0)
           + sin(sqrt(x ^ 2.0 + y ^ 2.0) / 8.0)
           + 4.0 )
           / 8.0
       ]
   ];
   void writeImage(Float[][] plasma, WritableImage img, Float hueShift = 0.0) {
       value writer = img.pixelWriter;
       for(j->row in plasma.indexed) {
           for(i->percent in row.indexed) {
               value hue = remainder(hueShift + percent, 1.0)  * 360.0;
               writer.setColor(i, j, Color.hsb(hue, 1.0, 1.0));
           }
       }
   }
   shared actual void start(Stage primaryStage) {
       value w = 500;
       value h = 500;
       value plasma = createPlasma(w, h);
       value img = WritableImage(w, h);
       writeImage(plasma, img);
       value root = BorderPane();
       root.center = ImageView(img);
       variable value hueShift = 0.0;
       value timer = object extends AnimationTimer() {
           shared actual void handle(Integer now) {
               hueShift = remainder(hueShift + 0.02, 1.0);
               writeImage(plasma, img, hueShift);
           }
       };
       timer.start();
       value scene = Scene(root);
       primaryStage.title = "Plasma";
       primaryStage.setScene(scene);
       primaryStage.sizeToScene();
       primaryStage.show();
   }

}</lang>

Common Lisp

Library: simple-rgb

plasma_demo.lisp: <lang lisp>(require :lispbuilder-sdl) (require :simple-rgb)

(defparameter *palette*

 (let ((palette-aux (make-array 256 :element-type 'fixnum)))
   (dotimes (i 256)
     (let ((color_i (simple-rgb:hsv->rgb (simple-rgb:hsv (/ i 255.0) 1.0 1.0))))
       (setf (aref palette-aux i) (loop :for component :across color_i
                                      :for i :from 0
                                      :sum (ash component (* 8 i))))))
   palette-aux)
 "palette")

(defun value->color (palette palette-shift index)

 (aref palette (mod (+ index palette-shift) (length palette))))

(defun return-color-by-pos (x y &optional w h)

 "returns a color index"
 (floor
  (/ (+ (+ 128.0 (* 128.0 (sin (/ x 16.0))))
        (+ 128.0 (* 128.0 (sin (/ y 8.0))))
        (+ 128.0 (* 128.0 (sin (/ (+ x y) 16.0))))
        (+ 128.0 (* 128.0 (sin (/ (sqrt (+ (* x x) (* y y))) 8.0)))))
     4.0)))

(defun return-color-by-pos-another (x y &optional w h)

 "a different function that returns a color index"
 (floor
  (/ (+ (+ 128.0 (* 128.0 (sin (/ x 16.0))))
        (+ 128.0 (* 128.0 (sin (/ y 32.0))))
        (+ 128.0 (* 128.0 (sin (/ (sqrt (+ (expt (/ (- x w) 2.0) 2) (expt (/ (- y h) 2.0) 2))) 8.0))))
        (+ 128.0 (* 128.0 (sin (/ (sqrt (+ (* x x) (* y y))) 8.0)))))
     4.0)))

(defun plasma-render (surface palette-shift)

 "render plasma"
 (let ((width (sdl:width surface))
       (height (sdl:height surface)))
   (sdl-base::with-pixel (s (sdl:fp surface))
     (dotimes (h height)
       (dotimes (w width)
         (sdl-base::write-pixel s w h (value->color *palette* palette-shift (funcall #'return-color-by-pos-another w h width height)))))))
 surface)

(defun demo/plasma ()

 "main function: shows a window rendering a plasma efect"
 (sdl:with-init ()
   (let ((win (sdl:window 320 240
                          :bpp 24
                          :resizable nil
                          :title-caption "demo/plasma"
                          :icon-caption "demo/plasma")))
     (let ((palette-shift 0))
     (sdl:update-display win)
     (sdl:with-events ()
       (:idle
        (plasma-render win palette-shift)
        (sdl:update-display win)
        (incf palette-shift))
       (:video-expose-event () (sdl:update-display win))
       (:key-down-event (:key key)
                        (when (or
                               (sdl:key= key :sdl-key-escape)
                               (sdl:key= key :sdl-key-q))
                          (sdl:push-quit-event)))
       (:quit-event () t))))))

(demo/plasma)</lang>

FreeBASIC

<lang freebasic>' version 12-04-2017 ' compile with: fbc -s gui ' Computer Graphics Tutorial (lodev.org), last example

  1. Define dist(a, b, c, d) Sqr(((a - c) * (a - c) + (b - d) * (b - d)))

Const As ULong w = 256 Const As ULong h = 256 ScreenRes w, h, 24 WindowTitle ("Plasma effect")

Dim As ULong x, y Dim As UByte c Dim As Double time_, value

Do

   time_ += .99
   ScreenLock
   For x = 0 To w -1
       For y = 0 To h -1
           value = Sin(dist(x + time_, y, 128, 128) / 8) _
           + Sin(dist(x, y, 64, 64) / 8) _
           + Sin(dist(x, y + time_ / 7, 192, 64) / 7) _
           + Sin(dist(x, y, 192, 100) / 8) + 4
           ' c = Int(value) * 32
           c = int(value * 32)
           PSet(x, y), RGB(c, c * 2, 255 - c)
       Next
   Next
   ScreenUnLock
   Sleep 1
   If Inkey <> "" Or Inkey = Chr(255) + "k" Then
       End
   End If

Loop</lang>

Gosu

File:Gosu plasma.png

<lang gosu> uses javax.swing.* uses java.awt.* uses java.awt.image.* uses java.awt.event.ActionEvent uses java.awt.image.BufferedImage#* uses java.lang.Math#*

var size = 400 EventQueue.invokeLater(\ -> showPlasma())

function showPlasma() {

 var frame = new JFrame("Plasma") {:Resizable = false, :DefaultCloseOperation = JFrame.EXIT_ON_CLOSE}
 frame.add(new Plasma(), BorderLayout.CENTER)
 frame.pack()
 frame.setLocationRelativeTo(null)
 frame.Visible = true 

}

class Plasma extends JPanel {

 var hueShift: float
 property get plasma: float[][] = createPlasma(size, size)
 property get img: BufferedImage = new BufferedImage(size, size, TYPE_INT_RGB)
 
 construct() {
   PreferredSize = new Dimension(size, size)
   new Timer(50, \ e -> {hueShift+=0.02 repaint()}).start()
 }
 
 private function createPlasma(w: int, h: int): float[][] {
   var buffer = new float[h][w]
   for(y in 0..|h)
     for(x in 0..|w) {
       var value = (sin(x / 16) + sin(y / 8) + sin((x + y) / 16) + sin(sqrt(x * x + y * y) / 8) + 4) / 8
       buffer[y][x] = value as float
     }
   return buffer
 }
 override function paintComponent(g: Graphics) {
   for(y in 0..|plasma.length)
     for(x in 0..|plasma[0].length)
       img.setRGB(x, y, Color.HSBtoRGB(hueShift + plasma[y][x], 1, 1))
   g.drawImage(img, 0, 0, null)
 }

} </lang>

J

<lang j>require 'trig viewmat' plasma=: 3 :0

 'w h'=. y
 X=. (i. % <:) w
 Y=. (i. % <:) h
 x1=. sin X*16
 y1=. sin Y*32
 xy1=. sin (Y+/X)*16
 xy2=. sin (Y +&.*:/ X)*32
 xy1+xy2+y1+/x1

)</lang>

<lang j> viewmat plasma 256 256</lang>

Java

Works with: Java version 8

<lang java>import java.awt.*; import java.awt.event.*; import java.awt.image.*; import static java.awt.image.BufferedImage.*; import static java.lang.Math.*; import javax.swing.*;

public class PlasmaEffect extends JPanel {

   float[][] plasma;
   float hueShift = 0;
   BufferedImage img;
   public PlasmaEffect() {
       Dimension dim = new Dimension(640, 640);
       setPreferredSize(dim);
       setBackground(Color.white);
       img = new BufferedImage(dim.width, dim.height, TYPE_INT_RGB);
       plasma = createPlasma(dim.height, dim.width);
       // animate about 24 fps and shift hue value with every frame
       new Timer(42, (ActionEvent e) -> {
           hueShift = (hueShift + 0.02f) % 1;
           repaint();
       }).start();
   }
   float[][] createPlasma(int w, int h) {
       float[][] buffer = new float[h][w];
       for (int y = 0; y < h; y++)
           for (int x = 0; x < w; x++) {
               double value = sin(x / 16.0);
               value += sin(y / 8.0);
               value += sin((x + y) / 16.0);
               value += sin(sqrt(x * x + y * y) / 8.0);
               value += 4; // shift range from -4 .. 4 to 0 .. 8
               value /= 8; // bring range down to 0 .. 1
               // requires VM option -ea
               assert (value >= 0.0 && value <= 1.0) : "Hue value out of bounds";
               buffer[y][x] = (float) value;
           }
       return buffer;
   }
   void drawPlasma(Graphics2D g) {
       int h = plasma.length;
       int w = plasma[0].length;
       for (int y = 0; y < h; y++)
           for (int x = 0; x < w; x++) {
               float hue = hueShift + plasma[y][x] % 1;
               img.setRGB(x, y, Color.HSBtoRGB(hue, 1, 1));
           }
       g.drawImage(img, 0, 0, null);
   }
   @Override
   public void paintComponent(Graphics gg) {
       super.paintComponent(gg);
       Graphics2D g = (Graphics2D) gg;
       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
       drawPlasma(g);
   }
   public static void main(String[] args) {
       SwingUtilities.invokeLater(() -> {
           JFrame f = new JFrame();
           f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           f.setTitle("Plasma Effect");
           f.setResizable(false);
           f.add(new PlasmaEffect(), BorderLayout.CENTER);
           f.pack();
           f.setLocationRelativeTo(null);
           f.setVisible(true);
       });
   }

}</lang>

Kotlin

Translation of: Java

<lang scala>// version 1.1.2

import java.awt.* import java.awt.image.BufferedImage import javax.swing.*

class PlasmaEffect : JPanel() {

   private val plasma: Array<FloatArray>
   private var hueShift = 0.0f
   private val img: BufferedImage
   init {
       val dim = Dimension(640, 640)
       preferredSize = dim
       background = Color.white
       img = BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_RGB)
       plasma = createPlasma(dim.height, dim.width)
       // animate about 24 fps and shift hue value with every frame
       Timer(42) {
           hueShift = (hueShift + 0.02f) % 1
           repaint()
       }.start()
   }
   private fun createPlasma(w: Int, h: Int): Array<FloatArray> {
       val buffer = Array(h) { FloatArray(w) }
       for (y in 0 until h)
           for (x in 0 until w) {
               var value = Math.sin(x / 16.0)
               value += Math.sin(y / 8.0)
               value += Math.sin((x + y) / 16.0)
               value += Math.sin(Math.sqrt((x * x + y * y).toDouble()) / 8.0)
               value += 4.0  // shift range from -4 .. 4 to 0 .. 8
               value /= 8.0  // bring range down to 0 .. 1
               if (value < 0.0 || value > 1.0) throw RuntimeException("Hue value out of bounds")
               buffer[y][x] = value.toFloat()
           }
       return buffer
   }
   private fun drawPlasma(g: Graphics2D) {
       val h = plasma.size
       val w = plasma[0].size
       for (y in 0 until h)
           for (x in 0 until w) {
               val hue = hueShift + plasma[y][x] % 1
               img.setRGB(x, y, Color.HSBtoRGB(hue, 1.0f, 1.0f))
           }
       g.drawImage(img, 0, 0, null)
   }
   override fun paintComponent(gg: Graphics) {
       super.paintComponent(gg)
       val g = gg as Graphics2D
       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
       drawPlasma(g);
   }

}

fun main(args: Array<String>) {

   SwingUtilities.invokeLater {
       val f = JFrame()
       f.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
       f.title = "Plasma Effect"
       f.isResizable = false
       f.add(PlasmaEffect(), BorderLayout.CENTER)
       f.pack()
       f.setLocationRelativeTo(null)
       f.isVisible = true
   }

}</lang>

Lua

Needs LÖVE 2D Engine

Translation of: C++

<lang lua> _ = love.graphics p1, p2, points = {}, {}, {}

function hypotenuse( a, b )

   return a * a + b * b

end function love.load()

   size = _.getWidth()
   currentTime, doub, half = 0, size * 2, size / 2
   local b1, b2
 
   for j = 0, size * 2 do
       for i = 0, size * 2 do
           b1 = math.floor( 128 + 127 * ( math.cos( math.sqrt( hypotenuse( size - j , size - i ) ) / 64 ) ) )
           b2 = math.floor( ( math.sin( ( math.sqrt( 128.0 + hypotenuse( size - i, size - j ) ) - 4.0 ) / 32.0 ) + 1 ) * 90 )
           table.insert( p1, b1 ); table.insert( p2, b2 )
       end
   end

end function love.draw()

   local a, c1, c2, c3, s1, s2, s3
   currentTime = currentTime + math.random( 2 ) * 3
   local x1 = math.floor( half + ( half -  2 ) * math.sin(  currentTime /  47 ) )
   local x2 = math.floor( half + ( half /  7 ) * math.sin( -currentTime / 149 ) )
   local x3 = math.floor( half + ( half -  3 ) * math.sin( -currentTime / 157 ) )
   local y1 = math.floor( half + ( half / 11 ) * math.cos(  currentTime /  71 ) )
   local y2 = math.floor( half + ( half -  5 ) * math.cos( -currentTime / 181 ) )
   local y3 = math.floor( half + ( half / 23 ) * math.cos( -currentTime / 137 ) )
   s1 = y1 * doub + x1; s2 = y2 * doub + x2; s3 = y3 * doub + x3
   for j = 0, size do
       for i = 0, size do
           a = p2[s1] + p1[s2] + p2[s3]
           c1 = a * 2; c2 = a * 4; c3 = a * 8
           table.insert( points, { i, j, c1, c2, c3, 255 } )
           s1 = s1 + 1; s2 = s2 + 1; s3 = s3 + 1;
       end
       s1 = s1 + size; s2 = s2 + size; s3 = s3 + size
   end
   _.points( points ) 

end </lang>

Racket

Uses `return-color-by-pos` from #Lisp, because it was almost lift and shift

<lang racket>#lang racket

from lisp (cos I could just lift the code)

(require images/flomap

        2htdp/universe
        racket/flonum)
copied from pythagoras-triangle#racket

(define (real-remainder x q) (- x (* (floor (/ x q)) q)))

(define (HSV->RGB H S V)

 (define C (* V S)) ; chroma
 (define H′ (/ H 60))
 (define X (* C (- 1 (abs (- (real-remainder H′ 2) 1)))))
 (define-values (R1 G1 B1)
   (cond
     [(< H′ 1) (values C X 0.)]
     [(< H′ 2) (values X C 0.)]
     [(< H′ 3) (values 0. C X)]
     [(< H′ 4) (values 0. X C)]
     [(< H′ 5) (values X 0. C)]
     [(< H′ 6) (values C 0. X)]
     [else (values 0. 0. 0.)]))
 (define m (- V C))
 (values (+ R1 m) (+ G1 m) (+ B1 m)))


(define ((colour-component-by-pos ϕ) k x y)

 (let ((rv
        (/ (+ (+ 1/2 (* 1/2 (sin (+ ϕ (/ x 16.0)))))
              (+ 1/2 (* 1/2 (sin (+ ϕ (/ y 8.0)))))
              (+ 1/2 (* 1/2 (sin (+ ϕ (/ (+ x y) 16.0)))))
              (+ 1/2 (* 1/2 (sin (+ ϕ (/ (sqrt (+ (sqr x) (sqr y))) 8.0))))))
           4.0)))
   rv))

(define ((plasma-flomap (ϕ 0)) w h)

 (build-flomap 1 w h (colour-component-by-pos ϕ)))

(define ((plasma-image (ϕ 0)) w h)

 (flomap->bitmap ((plasma-flomap ϕ) w h)))

(define ((colour-plasma plsm) t)

 (let ((w (flomap-width plsm))
       (h (flomap-height plsm)))
   (flomap->bitmap
    (build-flomap* 3 w h
                   (λ (x y)
                     (define-values (r g b)
                       (HSV->RGB (real-remainder
                                  (+ (* t 5.)
                                     (* 360 (flomap-ref plsm 0 x y)))
                                  360.) 1. 1.))
                     (flvector r g b))))))
((plasma-image) 200 200)
((plasma-image (/ pi 32)) 200 200)

(define plsm ((plasma-flomap) 300 300))

 (animate (λ (t)
            ((colour-plasma plsm) t)))</lang>

Perl 6

Works with: Rakudo version 2016.03

<lang perl6>use Image::PNG::Portable;

my ($w, $h) = 400, 400; my $out = Image::PNG::Portable.new: :width($w), :height($h);

plasma($out);

$out.write: 'Plasma-perl6.png';

sub plasma ($png) {

   for ^$w -> $x {
       for ^$h -> $y {
           my $hue = 4 + sin($x / 19) + sin($y / 9) + sin(($x + $y) / 25) + sin(sqrt($x² + $y²) / 8);
           $png.set: $x, $y, |hsv2rgb($hue/8, 1, 1);
       }
   }

}

sub hsv2rgb ( $h, $s, $v ){

   my $c = $v * $s;
   my $x = $c * (1 - abs( (($h*6) % 2) - 1 ) );
   my $m = $v - $c;
   my ($r, $g, $b) = do given $h {
       when   0..^1/6 { $c, $x, 0 }
       when 1/6..^1/3 { $x, $c, 0 }
       when 1/3..^1/2 { 0, $c, $x }
       when 1/2..^2/3 { 0, $x, $c }
       when 2/3..^5/6 { $x, 0, $c }
       when 5/6..1    { $c, 0, $x }
   }
   ( $r, $g, $b ) = map { (($_+$m) * 255).Int }, $r, $g, $b;

}</lang>

Python

Translation of: Perl 6

<lang python>import math import colorsys from PIL import Image

def plasma (w, h): out = Image.new("RGB", (w, h)) pix = out.load() for x in range (w): for y in range(h): hue = 4.0 + math.sin(x / 19.0) + math.sin(y / 9.0) \ + math.sin((x + y) / 25.0) + math.sin(math.sqrt(x**2.0 + y**2.0) / 8.0) hsv = colorsys.hsv_to_rgb(hue/8.0, 1, 1) pix[x, y] = tuple([int(round(c * 255.0)) for c in hsv]) return out

if __name__=="__main__": im = plasma(400, 400) im.show()</lang>

Sidef

Translation of: Perl 6

<lang ruby>require('Imager')

class Plasma(width=400, height=400) {

   has img = nil
   method init {
       img = %s|Imager|.new(xsize => width, ysize => height)
   }
   method generate {
       for y,x in (^height ~X ^width) {
           var hue = (4 + sin(x/19) + sin(y/9) + sin((x+y)/25) + sin(hypot(x, y)/8))
           img.setpixel(x => x, y => y, color => Hash(hsv => [360 * hue / 8, 1, 1]))
       }
   }
   method save_as(filename) {
       img.write(file => filename)
   }

}

var plasma = Plasma(256, 256) plasma.generate plasma.save_as('plasma.png')</lang>