Plasma effect: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added ASCII and Graphics implementations in C.)
(→‎{{header|JavaScript}}: added javascript)
Line 679: Line 679:
}
}
}</lang>
}</lang>

=={{header|JavaScript}}==
{{trans|Java}}
<lang javascript><!DOCTYPE html>
<html lang='en'>

<head>
<meta charset='UTF-8'>
<style>
canvas {
position: absolute;
top: 50%;
left: 50%;
width: 700px;
height: 500px;
margin: -250px 0 0 -350px;
}

body {
background-color: black;
}
</style>
</head>

<body>
<canvas></canvas>
<script>
'use strict';
var canvas = document.querySelector('canvas');
canvas.width = 700;
canvas.height = 500;

var g = canvas.getContext('2d');

var plasma = createPlasma(canvas.width, canvas.height);
var hueShift = 0;

function createPlasma(w, h) {
var buffer = new Array(h);

for (var y = 0; y < h; y++) {
buffer[y] = new Array(w);

for (var x = 0; x < w; x++) {

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) / 8.0);
value += 4; // shift range from -4 .. 4 to 0 .. 8
value /= 8; // bring range down to 0 .. 1

buffer[y][x] = value;
}
}
return buffer;
}

function drawPlasma(w, h) {
var img = g.getImageData(0, 0, w, h);

for (var y = 0; y < h; y++) {

for (var x = 0; x < w; x++) {

var hue = hueShift + plasma[y][x] % 1;
var rgb = HSVtoRGB(hue, 1, 1);
var pos = (y * w + x) * 4;
img.data[pos] = rgb.r;
img.data[pos + 1] = rgb.g;
img.data[pos + 2] = rgb.b;
}
}
g.putImageData(img, 0, 0);
}

// copied from stackoverflow
function HSVtoRGB(h, s, v) {
var r, g, b, i, f, p, q, t;

i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
}

function drawBorder() {
g.strokeStyle = "white";
g.lineWidth = 10;
g.strokeRect(0, 0, canvas.width, canvas.height);
}

function animate(lastFrameTime) {
var requestID = requestAnimationFrame(function () {
animate(lastFrameTime);
});

var time = new Date().getTime();
var delay = 42; // about 24 fps

if (lastFrameTime + delay < time) {
hueShift = (hueShift + 0.02) % 1;
drawPlasma(canvas.width, canvas.height);
drawBorder();
lastFrameTime = time;
}
}

g.fillRect(0, 0, canvas.width, canvas.height);
animate(0);
</script>

</body>

</html></lang>


=={{header|Kotlin}}==
=={{header|Kotlin}}==

Revision as of 12:08, 8 October 2017

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>

JavaScript

Translation of: Java

<lang javascript><!DOCTYPE html> <html lang='en'>

<head>

   <meta charset='UTF-8'>
   <style>
       canvas {
           position: absolute;
           top: 50%;
           left: 50%;
           width: 700px;
           height: 500px;
           margin: -250px 0 0 -350px;
       }
       body {
           background-color: black;
       }
   </style>

</head>

<body>

   <canvas></canvas>
   <script>
       'use strict';
       var canvas = document.querySelector('canvas');
       canvas.width = 700;
       canvas.height = 500;
       var g = canvas.getContext('2d');
       var plasma = createPlasma(canvas.width, canvas.height);
       var hueShift = 0;
       function createPlasma(w, h) {
           var buffer = new Array(h);
           for (var y = 0; y < h; y++) {
               buffer[y] = new Array(w);
               for (var x = 0; x < w; x++) {
                   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) / 8.0);
                   value += 4; // shift range from -4 .. 4 to 0 .. 8
                   value /= 8; // bring range down to 0 .. 1
                   buffer[y][x] = value;
               }
           }
           return buffer;
       }
       function drawPlasma(w, h) {
           var img = g.getImageData(0, 0, w, h);
           for (var y = 0; y < h; y++) {
               for (var x = 0; x < w; x++) {
                   var hue = hueShift + plasma[y][x] % 1;
                   var rgb = HSVtoRGB(hue, 1, 1);
                   var pos = (y * w + x) * 4;
                   img.data[pos] = rgb.r;
                   img.data[pos + 1] = rgb.g;
                   img.data[pos + 2] = rgb.b;
               }
           }
           g.putImageData(img, 0, 0);
       }
       // copied from stackoverflow
       function HSVtoRGB(h, s, v) {
           var r, g, b, i, f, p, q, t;
           i = Math.floor(h * 6);
           f = h * 6 - i;
           p = v * (1 - s);
           q = v * (1 - f * s);
           t = v * (1 - (1 - f) * s);
           switch (i % 6) {
               case 0: r = v, g = t, b = p; break;
               case 1: r = q, g = v, b = p; break;
               case 2: r = p, g = v, b = t; break;
               case 3: r = p, g = q, b = v; break;
               case 4: r = t, g = p, b = v; break;
               case 5: r = v, g = p, b = q; break;
           }
           return {
               r: Math.round(r * 255),
               g: Math.round(g * 255),
               b: Math.round(b * 255)
           };
       }
       function drawBorder() {
           g.strokeStyle = "white";
           g.lineWidth = 10;
           g.strokeRect(0, 0, canvas.width, canvas.height);
       }
       function animate(lastFrameTime) {
           var requestID = requestAnimationFrame(function () {
               animate(lastFrameTime);
           });
           var time = new Date().getTime();
           var delay = 42; // about 24 fps
           if (lastFrameTime + delay < time) {
               hueShift = (hueShift + 0.02) % 1;
               drawPlasma(canvas.width, canvas.height);
               drawBorder();
               lastFrameTime = time;
           }
       }
       g.fillRect(0, 0, canvas.width, canvas.height);
       animate(0);
   </script>

</body>

</html></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>