Plasma effect: Difference between revisions

From Rosetta Code
Content added Content deleted
(Scala contribution added.)
Line 1,245: Line 1,245:
https://www.dropbox.com/s/gdioouv328m2d60/PlasmaEffect.jpg?dl=0
https://www.dropbox.com/s/gdioouv328m2d60/PlasmaEffect.jpg?dl=0


=={{header|Scala}}==
===Java Swing Interoperability===
<lang Scala>import java.awt._
import java.awt.event.ActionEvent
import java.awt.image.BufferedImage

import javax.swing._

import scala.math.{sin, sqrt}

object PlasmaEffect extends App {

SwingUtilities.invokeLater(() =>
new JFrame("Plasma Effect") {

class PlasmaEffect extends JPanel {
private val (w, h) = (640, 640)
private var hueShift = 0.0f

override def paintComponent(gg: Graphics): Unit = {
val g = gg.asInstanceOf[Graphics2D]

def drawPlasma(g: Graphics2D) = {
val img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB)

for (y <- 0 until h;
x <- 0 until w) {

def design =
(sin(x / 16f) + sin(y / 8f) + sin((x + y) / 16f) + sin(sqrt(x * x + y * y) / 8f) + 4).toFloat / 8

img.setRGB(x, y, Color.HSBtoRGB(hueShift + design % 1, 1, 1))
}
g.drawImage(img, 0, 0, null)
}

super.paintComponent(gg)
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
drawPlasma(g)
}

// animate about 24 fps and shift hue value with every frame
new Timer(42, (_: ActionEvent) => {
hueShift = (hueShift + 0.02f) % 1
repaint()
}).start()

setBackground(Color.white)
setPreferredSize(new Dimension(h, w))
}

add(new PlasmaEffect, BorderLayout.CENTER)
pack()
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
setLocationRelativeTo(null)
setResizable(false)
setVisible(true)
})

}</lang>
=={{header|Sidef}}==
=={{header|Sidef}}==
{{trans|Perl 6}}
{{trans|Perl 6}}

Revision as of 11:30, 28 June 2018

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
Translation of: Java

<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: navy;
       }
   </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 time = new Date().getTime();
           var delay = 42;
           if (lastFrameTime + delay < time) {
               hueShift = (hueShift + 0.02) % 1;
               drawPlasma(canvas.width, canvas.height);
               drawBorder();
               lastFrameTime = time;
           }
           
           requestAnimationFrame(function () {
               animate(lastFrameTime);
           });
       }
       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>

Phix

Translation of: JavaScript

<lang Phix>-- -- demo\rosetta\plasma.exw -- include pGUI.e

Ihandle dlg, canvas cdCanvas cddbuffer, cdcanvas

sequence plasma integer pw = 0, ph = 0

procedure createPlasma(integer w, h)

   plasma = repeat(repeat(0,w),h)
   for y=1 to h do
       for x=1 to w do
           atom v = sin(x/16)
           v += sin(y/8)
           v += sin((x+y)/16)
           v += sin(sqrt(x*x + y*y)/8)
           v += 4 -- shift range from -4 .. 4 to 0 .. 8
           v /= 8 -- bring range down to 0 .. 1
           plasma[y][x] = v
       end for
   end for
   pw = w
   ph = h

end procedure

atom hueShift = 0

procedure drawPlasma(integer w, h)

   hueShift = remainder(hueShift + 0.02,1)
   sequence rgb3 = repeat(repeat(0,w*h),3)
   integer cx = 1
   for y=1 to h do
       for x=1 to w do
           atom hue = hueShift + remainder(plasma[y][x],1)
           integer i = floor(hue * 6)
           atom t = 255,
                f = (hue * 6 - i)*t,
                q = t - f, 
                r, g, b
           switch mod(i,6) do
               case 0: r = t; g = f; b = 0
               case 1: r = q; g = t; b = 0
               case 2: r = 0; g = t; b = f
               case 3: r = 0; g = q; b = t
               case 4: r = f; g = 0; b = t
               case 5: r = t; g = 0; b = q
           end switch
           rgb3[1][cx] = r
           rgb3[2][cx] = g
           rgb3[3][cx] = b
           cx += 1
       end for
   end for
   cdCanvasPutImageRectRGB(cddbuffer, w, h, rgb3, 0, 0, 0, 0, 0, 0, 0, 0) 

end procedure

function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)

   atom {w,h} = IupGetIntInt(canvas, "DRAWSIZE")
   if pw!=w or ph!=h then
       createPlasma(w,h)
   end if
   cdCanvasActivate(cddbuffer)
   drawPlasma(w,h)
   cdCanvasFlush(cddbuffer)
   return IUP_DEFAULT

end function

function timer_cb(Ihandle /*ih*/)

   IupUpdate(canvas)
   return IUP_IGNORE

end function

function map_cb(Ihandle ih)

   cdcanvas = cdCreateCanvas(CD_IUP, ih)
   cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
   cdCanvasSetBackground(cddbuffer, CD_WHITE)
   cdCanvasSetForeground(cddbuffer, CD_GRAY)
   return IUP_DEFAULT

end function

procedure main()

   IupOpen()
   canvas = IupCanvas(NULL)
   IupSetAttribute(canvas, "RASTERSIZE", "450x300")
   IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
   IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
   dlg = IupDialog(canvas)
   IupSetAttribute(dlg, "TITLE", "Plasma")
   IupCloseOnEscape(dlg)
   IupShow(dlg)
   IupSetAttribute(canvas, "RASTERSIZE", NULL)
   Ihandle timer = IupTimer(Icallback("timer_cb"), 50)
   IupMainLoop()
   IupClose()

end procedure

main()</lang> And here's a simple console ditty, similar I think to C's ASCII version for Windows, though this also works on Linux: <lang Phix>sequence s = video_config() for i=1 to s[VC_SCRNLINES]*s[VC_SCRNCOLS]-1 do

   bk_color(rand(16)-1)
   text_color(rand(16)-1)
   puts(1,"\xDF")

end for {} = wait_key()</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>

Ring

<lang ring>

  1. Project : Plasma effect
  2. Date  : 2018/01/10
  3. Author : Gal Zsolt (~ CalmoSoft ~), Bert Mariani
  4. Email  : <calmosoft@gmail.com>

load "guilib.ring"

paint = null

new qapp

      {
       win1 = new qwidget()
      {
                  setwindowtitle("Plasma effect")
                  setgeometry(100,100,500,600)
                  label1 = new qlabel(win1)
                  {
                  setgeometry(10,10,400,400)
                  settext("")
                   }
                  new qpushbutton(win1)
                  {
                  setgeometry(150,500,100,30)
                  settext("Draw")
                  setclickevent("Draw()")
                 }
                 show()
      }
      exec()
      }

func draw

       p1    = new qpicture()
       color = new qcolor() { setrgb(0,0,255,255) }   ### <<< BLUE
       pen   = new qpen() { setcolor(color) setwidth(1) }
       paint = new qpainter()
       {
                  begin(p1)
                  setpen(pen)
                  w = 256 
                  h = 256
                  time = 0
                  for x = 0 to w -1
                        for y = 0 to h -1
                              time = time + 0.99 
                              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 = floor(value * 32)
                              r = c
                              g = (c*2)%255
                              b = 255-c
                              color2 = new qcolor()
                              color2.setrgb(r,g,b,255)
                              pen.setcolor(color2) 
                              setpen(pen)     
                              drawpoint(x,y)
                       next
                  next
       endpaint()
       }
       label1 { setpicture(p1) show() }
       return

func dist(a, b, c, d)

       d = sqrt(((a - c) * (a - c) + (b - d) * (b - d)))
       return d

</lang> Output:

https://www.dropbox.com/s/gdioouv328m2d60/PlasmaEffect.jpg?dl=0

Scala

Java Swing Interoperability

<lang Scala>import java.awt._ import java.awt.event.ActionEvent import java.awt.image.BufferedImage

import javax.swing._

import scala.math.{sin, sqrt}

object PlasmaEffect extends App {

 SwingUtilities.invokeLater(() =>
   new JFrame("Plasma Effect") {
     class PlasmaEffect extends JPanel {
       private val (w, h) = (640, 640)
       private var hueShift = 0.0f
       override def paintComponent(gg: Graphics): Unit = {
         val g = gg.asInstanceOf[Graphics2D]
         def drawPlasma(g: Graphics2D) = {
           val img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB)
           for (y <- 0 until h;
                x <- 0 until w) {
             def design =
               (sin(x / 16f) + sin(y / 8f) + sin((x + y) / 16f) + sin(sqrt(x * x + y * y) / 8f) + 4).toFloat / 8
             img.setRGB(x, y, Color.HSBtoRGB(hueShift + design % 1, 1, 1))
           }
           g.drawImage(img, 0, 0, null)
         }
         super.paintComponent(gg)
         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
         drawPlasma(g)
       }
       // animate about 24 fps and shift hue value with every frame
       new Timer(42, (_: ActionEvent) => {
         hueShift = (hueShift + 0.02f) % 1
         repaint()
       }).start()
       setBackground(Color.white)
       setPreferredSize(new Dimension(h, w))
     }
     add(new PlasmaEffect, BorderLayout.CENTER)
     pack()
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
     setLocationRelativeTo(null)
     setResizable(false)
     setVisible(true)
   })

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