Plasma effect: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Perl 6}}: eliminate some intermediate variables)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(36 intermediate revisions by 18 users not shown)
Line 12:
* [http://www.bidouille.org/prog/plasma Plasma (bidouille.org)]
<br><br>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
#!/usr/bin/awk -f
 
function clamp(val, a, b) { return (val<a) ? a : (val>b) ? b : val }
 
## return a timestamp with centisecond precision
function timex() {
getline < "/proc/uptime"
close("/proc/uptime")
return $1
}
 
## draw image to terminal
function draw(src, xpos, ypos, w,h, x,y, up,dn, line,screen) {
w = src["width"]
h = src["height"]
 
for (y=0; y<h; y+=2) {
line = sprintf("\033[%0d;%0dH", y/2+ypos+1, xpos+1)
for (x=0; x<w; x++) {
up = src[x,y+0]
dn = src[x,y+1]
line = line "\033[38;2;" palette[up] ";48;2;" palette[dn] "m▀"
}
screen = screen line "\033[0m"
}
printf("%s", screen)
}
 
## generate a palette
function paletteGen( i, r,g,b) {
# generate palette
for (i=0; i<256; i++) {
r = 128 + 128 * sin(3.14159265 * i / 32.0)
g = 128 + 128 * sin(3.14159265 * i / 64.0)
b = 128 + 128 * sin(3.14159265 * i / 128.0)
palette[i] = sprintf("%d;%d;%d", clamp(r,0,255), clamp(g,0,255), clamp(b,0,255))
}
}
 
## generate a plasma
function plasmaGen(plasma, w, h, x,y, color) {
for (y=0; y<h; y++) {
for (x=0; x<w; x++) {
color = ( \
128.0 + (128.0 * sin((x / 8.0) - cos(now/2) )) \
+ 128.0 + (128.0 * sin((y / 16.0) - sin(now)*2 )) \
+ 128.0 + (128.0 * sin(sqrt((x - w / 2.0) * (x - w / 2.0) + (y - h / 2.0) * (y - h / 2.0)) / 4.0)) \
+ 128.0 + (128.0 * sin((sqrt(x * x + y * y) / 4.0) - sin(now/4) )) \
) / 4;
 
plasma[x,y] = int(color)
}
}
}
 
BEGIN {
"stty size" | getline
buffer["height"] = h = ($1 ? $1 : 24) * 2
buffer["width"] = w = ($2 ? $2 : 80)
 
paletteGen()
start = timex()
 
while (elapsed < 30) {
elapsed = (now = timex()) - start
 
plasmaGen(plasma, w, h)
 
# copy plasma to buffer
for (y=0; y<h; y++)
for (x=0; x<w; x++)
buffer[x,y] = int(plasma[x,y] + now * 100) % 256
 
# draw buffer to terminal
draw(buffer)
}
 
printf("\n")
}
</syntaxhighlight>
 
=={{header|C}}==
===ASCII version for Windows===
If you don't want to bother with Graphics libraries, try out this nifty implementation on Windows :
<syntaxhighlight lang="c">
<lang C>
#include<windows.h>
#include<stdlib.h>
Line 53 ⟶ 137:
return 0;
}
</syntaxhighlight>
</lang>
 
===Graphics version===
And here's the Graphics version, requires the [http://www.cs.colorado.edu/~main/bgi/cs1300/ WinBGIm] library. Prints out usage on incorrect invocation.
<syntaxhighlight lang="c">
<lang C>
#include<graphics.h>
#include<stdlib.h>
Line 101 ⟶ 185:
return 0;
}
</syntaxhighlight>
</lang>
 
=={{header|C++}}==
===Version 1 (windows.h)===
[[File:plasma.png]]
 
Windows version.
<langsyntaxhighlight lang="cpp">
#include <windows.h>
#include <math.h>
Line 323 ⟶ 408:
return myWnd.Run( hInstance );
}
</syntaxhighlight>
</lang>
 
===Version 2 (SDL2)===
{{libheader|SDL2}}
<center>Take that, Paulo Jorente!</center>
 
====Version 2.1====
<syntaxhighlight lang="cpp" line>
// Standard C++ stuff
#include <iostream>
#include <array>
#include <cmath>
#include <numbers>
 
// SDL2 stuff
#include "SDL2/SDL.h"
 
// Compile: g++ -std=c++20 -Wall -Wextra -pedantic -Ofast SDL2Plasma.cpp -o SDL2Plasma -lSDL2 -fopenmp
 
struct RGB {
int Red, Green, Blue;
};
 
RGB HSBToRGB(const double hue, const double saturation, const double brightness) {
double Red = 0,
Green = 0,
Blue = 0;
if (hue == 1) {
Red = brightness;
} else {
double Sector = hue * 360,
Cosine = std::cos(Sector*std::numbers::pi/180),
Sine = std::sin(Sector*std::numbers::pi/180);
Red = brightness * Cosine + saturation * Sine;
Green = brightness * Cosine - saturation * Sine;
Blue = brightness - saturation * Cosine;
}
RGB Result;
Result.Red = (int)(Red * 255);
Result.Green = (int)(Green * 255);
Result.Blue = (int)(Blue * 255);
return Result;
}
 
template <int width_array_length, int height_array_length>
void CalculatePlasma(std::array<std::array<double, width_array_length>, height_array_length> &array) {
#pragma omp parallel for
for (unsigned long y = 0; y < array.size(); y++)
#pragma omp simd
for (unsigned long x = 0; x < array.at(0).size(); x++) {
// Calculate the hue
double Hue = std::sin(x/16.0);
Hue += std::sin(y/8.0);
Hue += std::sin((x+y)/16.0);
Hue += std::sin(std::sqrt(x*x+y*y)/8.0);
Hue += 4;
// Clamp the hue to the range of [0, 1]
Hue /= 8;
array[y][x] = Hue;
}
}
 
template <int width_array_length, int height_array_length>
void DrawPlasma(SDL_Renderer *r, const std::array<std::array<double, width_array_length>, height_array_length> &array, const double &hue_shift) {
for (unsigned long y = 0; y < array.size(); y++)
for (unsigned long x = 0; x < array.at(0).size(); x++) {
// Convert the HSB value to RGB value
double Hue = hue_shift + std::fmod(array[y][x], 1);
RGB CurrentColour = HSBToRGB(Hue, 1, 1);
// Draw the actual plasma
SDL_SetRenderDrawColor(r, CurrentColour.Red, CurrentColour.Green, CurrentColour.Blue, 0xff);
SDL_RenderDrawPoint(r, x, y);
}
}
 
int main() {
const unsigned DefaultWidth = 640,
DefaultHeight = 640;
std::array<std::array<double, DefaultWidth>, DefaultHeight> ScreenArray;
SDL_Window *Window = NULL; // Define window
SDL_Renderer *Renderer = NULL; // Define renderer
// Init everything just for sure
SDL_Init(SDL_INIT_EVERYTHING);
// Set window size to 640x640, always shown
Window = SDL_CreateWindow("Plasma effect", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DefaultWidth, DefaultHeight, SDL_WINDOW_SHOWN);
Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED);
// Set background colour to white
SDL_SetRenderDrawColor(Renderer, 0xff, 0xff, 0xff, 0xff);
SDL_RenderClear(Renderer);
// Create an event handler and a "quit" flag
SDL_Event e;
bool KillWindow = false;
CalculatePlasma<DefaultWidth, DefaultHeight>(ScreenArray);
double HueShift = 0.0;
// The window runs until the "quit" flag is set to true
while (!KillWindow) {
while (SDL_PollEvent(&e) != 0) {
// Go through the events in the queue
switch (e.type) {
// Event: user hits a key
case SDL_QUIT: case SDL_KEYDOWN:
// Destroy window
KillWindow = true;
break;
}
}
// Render the plasma
DrawPlasma<DefaultWidth, DefaultHeight>(Renderer, ScreenArray, HueShift);
SDL_RenderPresent(Renderer);
if (HueShift < 1) {
HueShift = std::fmod(HueShift + 0.0025, 3);
} else {
CalculatePlasma<DefaultWidth, DefaultHeight>(ScreenArray);
HueShift = 0.0;
}
}
// Destroy renderer and window
SDL_DestroyRenderer(Renderer);
SDL_DestroyWindow(Window);
SDL_Quit();
return 0;
}
</syntaxhighlight>
 
{{Output}}
<center>[[File:C++ plasma effect SDL2.gif]]</center>
 
====Version 2.2====
<syntaxhighlight lang="cpp" line>
// Standard C++ stuff
#include <iostream>
#include <array>
#include <cmath>
#include <numbers>
 
// SDL2 stuff
#include "SDL2/SDL.h"
 
// Compile: g++ -std=c++20 -Wall -Wextra -pedantic -Ofast SDL2Plasma.cpp -o SDL2Plasma -lSDL2 -fopenmp
 
struct RGB {
int Red, Green, Blue;
};
 
RGB HSBToRGB(const float hue, const float saturation, const float brightness) {
float Red = 0,
Green = 0,
Blue = 0;
if (hue == 1) {
Red = brightness;
} else {
float Sector = hue * 360,
Cosine = std::cos(Sector*std::numbers::pi/180),
Sine = std::sin(Sector*std::numbers::pi/180);
Red = brightness * Cosine + saturation * Sine;
Green = brightness * Cosine - saturation * Sine;
Blue = brightness - saturation * Cosine;
}
RGB Result;
Result.Red = (int)(Red * 255);
Result.Green = (int)(Green * 255);
Result.Blue = (int)(Blue * 255);
return Result;
}
 
template <int width_array_length, int height_array_length>
void CalculatePlasma(std::array<std::array<float, width_array_length>, height_array_length> &array) {
#pragma omp parallel for
for (unsigned long y = 0; y < array.size(); y++)
#pragma omp simd
for (unsigned long x = 0; x < array.at(0).size(); x++) {
// Calculate the hue
float Hue = std::sin(x/16.0);
Hue += std::sin(y/8.0);
Hue += std::sin((x+y)/16.0);
Hue += std::sin(std::sqrt(x*x+y*y)/8.0);
Hue += 4;
// Clamp the hue to the range of [0, 1]
Hue /= 8;
array[y][x] = Hue;
}
}
 
template <int width_array_length, int height_array_length>
void DrawPlasma(SDL_Renderer *r, SDL_Texture *t, const std::array<std::array<float, width_array_length>, height_array_length> &array, const float &hue_shift) {
unsigned char *Bytes = NULL;
int Pitch = 0;
float Hue;
// Lock the texture
SDL_LockTexture(t, NULL, (void**)&Bytes, &Pitch);
for (unsigned long y = 0; y < array.size(); y++)
for (unsigned long x = 0; x < array.at(0).size(); x++) {
// Convert the HSB value to RGB value
Hue = hue_shift + std::fmod(array[y][x], 1);
RGB CurrentColour = HSBToRGB(Hue, 1, 1);
// Write colour data directly to texture
Bytes[y*Pitch+x*4] = CurrentColour.Red; // Red
Bytes[y*Pitch+x*4+1] = CurrentColour.Green; // Green
Bytes[y*Pitch+x*4+2] = CurrentColour.Blue; // Blue
Bytes[y*Pitch+x*4+3] = 0xff; // Alpha
}
// Unlock the texture
SDL_UnlockTexture(t);
// Feed the finished texture to the renderer
SDL_RenderCopy(r, t, NULL, NULL);
}
 
int main() {
const unsigned DefaultWidth = 640,
DefaultHeight = 640;
std::array<std::array<float, DefaultWidth>, DefaultHeight> ScreenArray;
SDL_Window *Window = NULL; // Define window
SDL_Renderer *Renderer = NULL; // Define renderer
// Init everything just for sure
SDL_Init(SDL_INIT_EVERYTHING);
// Set window size to 640x640, always shown
Window = SDL_CreateWindow("Plasma effect", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DefaultWidth, DefaultHeight, SDL_WINDOW_SHOWN);
Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED);
SDL_Texture *PlasmaTexture = SDL_CreateTexture(Renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, DefaultWidth, DefaultHeight);
// Set background colour to white
SDL_SetRenderDrawColor(Renderer, 0xff, 0xff, 0xff, 0xff);
SDL_RenderClear(Renderer);
// Create an event handler and a "quit" flag
SDL_Event e;
bool KillWindow = false;
CalculatePlasma<DefaultWidth, DefaultHeight>(ScreenArray);
float HueShift = 0.0;
// The window runs until the "quit" flag is set to true
while (!KillWindow) {
while (SDL_PollEvent(&e) != 0) {
// Go through the events in the queue
switch (e.type) {
// Event: user hits a key
case SDL_QUIT: case SDL_KEYDOWN:
// Destroy window
KillWindow = true;
break;
}
}
// Render the plasma
DrawPlasma<DefaultWidth, DefaultHeight>(Renderer, PlasmaTexture, ScreenArray, HueShift);
SDL_RenderPresent(Renderer);
if (HueShift < 1) {
HueShift = std::fmod(HueShift + 0.0025, 3);
} else {
CalculatePlasma<DefaultWidth, DefaultHeight>(ScreenArray);
HueShift = 0.0;
}
}
// Destroy renderer and window
SDL_DestroyRenderer(Renderer);
SDL_DestroyWindow(Window);
SDL_Quit();
return 0;
}
</syntaxhighlight>
 
{{Output}}
<center>[[File:C++ plasma effect SDL2 version 2.2.png|480px]]</center>
 
=={{header|Ceylon}}==
Be sure to import javafx.base, javafx.graphics and ceylon.numeric in your module file.
{{trans|Java}}
<langsyntaxhighlight lang="ceylon">
import javafx.application {
Application
Line 413 ⟶ 789:
}
 
}</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
Line 419 ⟶ 795:
{{libheader|simple-rgb}}
plasma_demo.lisp:
<langsyntaxhighlight lang="lisp">(require :lispbuilder-sdl)
(require :simple-rgb)
 
Line 486 ⟶ 862:
(:quit-event () t))))))
 
(demo/plasma)</langsyntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
[[File:DelphiPlasma.png|frame|none]]
{{libheader|SysUtils,StdCtrls}}
This code animates the plasma, which looks very nice. However, there are too many colors to render it properly with an animated GIF. As a result, I've only posted a static image of the plasma.
 
 
<syntaxhighlight lang="Delphi">
 
function PasmaPixel(X,Y,W,H: integer; Offset: double): TColor;
{Return pixel based on X,Y position and the size of the image}
{Offset controls the progression through the plasma for animation}
var A, B, C, Red, Green, Blue: double;
begin
A:=X + Y + Cos(Sin(Offset) * 2) * 100 + Sin(x / 100) * 1000;
B:=Y / H / 0.2 + Offset;
C:=X / W / 0.2;
Red:=abs(Sin(B + Offset) / 2 + C / 2 - B - C + Offset);
Green:=abs(Sin(Red + Sin(A / 1000 + Offset) + Sin(Y / 40 + Offset) + Sin((X + Y) / 100) * 3));
Blue:=abs(sin(Green + Cos(B + C + Green) + Cos(C) + Sin(X / 1000)));
Result := RGB(Round(255*Red), Round(255*Green), Round(255*Blue));
end;
 
 
procedure DisplayPlasma(Bmp: TBitmap; Width,Height: integer; Offset: double);
{Draw the plasma pattern on the bitmap progressed according to "Offset"}
var X,Y: integer;
var Scan: pRGBTripleArray;
begin
Bmp.PixelFormat:=pf24Bit;
for Y:=0 to Height-1 do
begin
Scan:=Bmp.ScanLine[Y];
for X:=0 to Width-1 do
begin
Scan[X]:=ColorToTriple(PasmaPixel(X,Y,Width,Height,Offset));
end;
end;
end;
var Offset: double;
 
 
procedure ShowPlasma(Image: TImage);
{Animate 10 seconds of plasma display}
var X,Y: integer;
var I,StartTime,CurTime,StopTime: integer;
const TimeLimit = 10;
begin
{setup stop time based on real-time clock}
StartTime:=GetTickCount;
StopTime:=StartTime + (TimeLimit * 1000);
{Keep display frame until stop time is reached}
for I:=0 to high(integer) do
begin
{Display one frame}
DisplayPlasma(Image.Picture.Bitmap,Image.Width,Image.Height,Offset);
{Display count-down time}
CurTime:=GetTickCount;
Image.Canvas.Brush.Style:=bsClear;
Image.Canvas.TextOut(5,5,IntToStr((CurTime-StartTime) div 1000)+' '+IntToStr(I));
Image.Repaint;
Application.ProcessMessages;
if Application.Terminated then exit;
{Exit if timed out}
if CurTime>StopTime then break;
Sleep(50);
{progress animation one step}
Offset:=Offset+0.1;
end;
end;
 
</syntaxhighlight>
{{out}}
<pre>
Elapsed Time: 10.127 Sec.
 
</pre>
 
=={{header|Forth}}==
 
{{works with|gforth|0.7.3}}
Ouputs a PPM file.
<syntaxhighlight lang="forth">: sqrt ( u -- sqrt ) ( Babylonian method )
dup 2/ ( first square root guess is half )
dup 0= if drop exit then ( sqrt[0]=0, sqrt[1]=1 )
begin dup >r 2dup / r> + 2/ ( stack: square old-guess new-guess )
2dup > while ( as long as guess is decreasing )
nip repeat ( forget old-guess and repeat )
drop nip ;
 
: sgn 0< if -1 else 1 then ;
: isin
256 mod 128 - \ full circle is 255 "degrees"
dup dup sgn * 128 swap - * \ second order approximation
negate 32 / ; \ amplitude is +/-128
 
: color-shape 256 mod 6 * 765 - abs 256 - 0 max 255 min ; \ trapezes
: hue
dup color-shape . \ red
dup 170 + color-shape . \ green
85 + color-shape . ; \ blue
 
: plasma
outfile-id >r
s" plasma.ppm" w/o create-file throw to outfile-id
s\" P3\n500 500\n255\n" type
500 0 do
500 0 do
i 2 * isin 128 +
j 4 * isin 128 + +
i j + isin 2 * 128 + +
i i * j j * + sqrt 4 * isin 128 + +
4 /
hue
s\" \n" type
loop
s\" \n" type
loop
 
outfile-id close-file throw
r> to outfile-id ;
 
plasma</syntaxhighlight>
 
 
 
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 12-04-2017
' compile with: fbc -s gui
' Computer Graphics Tutorial (lodev.org), last example
Line 524 ⟶ 1,028:
End If
 
Loop</langsyntaxhighlight>
 
=={{header|Go}}==
Line 536 ⟶ 1,040:
$ eog plasma2.gif
</pre>
<langsyntaxhighlight lang="go">package main
 
import (
Line 624 ⟶ 1,128:
log.Fatal(err2)
}
}</langsyntaxhighlight>
 
=={{header|Gosu}}==
[[File:Gosu_plasma.png|200px|thumb|right]]
{{trans|Java}}
<langsyntaxhighlight lang="gosu">
uses javax.swing.*
uses java.awt.*
Line 675 ⟶ 1,179:
}
}
</syntaxhighlight>
</lang>
 
=={{header|J}}==
[[File:J-viewmat-plasma.png|200px|thumb|right]]
<langsyntaxhighlight lang="j">require 'trig viewmat'
plasma=: 3 :0
'w h'=. y
Line 689 ⟶ 1,193:
xy2=. sin (Y +&.*:/ X)*32
xy1+xy2+y1+/x1
)</langsyntaxhighlight>
 
<syntaxhighlight lang ="j"> viewmat plasma 256 256</langsyntaxhighlight>
 
=={{header|Java}}==
[[File:plasma_effect_java.png|200px|thumb|right]]
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
Line 777 ⟶ 1,281:
});
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
{{trans|Java}}
<langsyntaxhighlight lang="javascript"><!DOCTYPE html>
<html lang='en'>
<head>
Line 902 ⟶ 1,406:
 
</body>
</html></langsyntaxhighlight>
 
=={{header|Julia}}==
{{trans|Perl}}
<syntaxhighlight lang="julia">using Luxor, Colors
 
Drawing(800, 800)
 
function plasma(wid, hei)
for x in -wid:wid, y in -hei:hei
sethue(parse(Colorant, HSV(180 + 45sin(x/19) + 45sin(y/9) +
45sin((x+y)/25) + 45sin(sqrt(x^2 + y^2)/8), 1, 1)))
circle(Point(x, y), 1, :fill)
end
end
 
@png plasma(800, 800)
</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.1.2
 
import java.awt.*
Line 976 ⟶ 1,497:
f.isVisible = true
}
}</langsyntaxhighlight>
 
=={{header|Lua}}==
Needs L&Ouml;VE 2D Engine
{{trans|C++}}
<langsyntaxhighlight lang="lua">
_ = love.graphics
p1, p2, points = {}, {}, {}
Line 1,022 ⟶ 1,543:
_.points( points )
end
</syntaxhighlight>
</lang>
 
=={{header|RacketMathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">s = 400;
Image@Table[
hue = Sin[i/16] + Sin[j/8] + Sin[(i + j)/16] + Sin[Sqrt[i^2 + j^2]/8];
hue = (hue + 4)/8;
Hue[hue, 1, 0.75]
,
{i, 1.0, s},
{j, 1.0, s}
]</syntaxhighlight>
{{out}}
Outputs an image.
 
=={{header|Nim}}==
Uses `return-color-by-pos` from [[#Lisp]], because it was almost lift and shift
{{libheader|imageman}}
<syntaxhighlight lang="nim">import math
import imageman
 
const
<lang racket>#lang racket
Width = 400
;; from lisp (cos I could just lift the code)
Height = 400
(require images/flomap
2htdp/universe
racket/flonum)
 
var img = initImage[ColorRGBF](Width, Height)
;; copied from pythagoras-triangle#racket
for x in 0..<Width:
(define (real-remainder x q) (- x (* (floor (/ x q)) q)))
for y in 0..<Height:
let fx = float32(x)
let fy = float32(y)
var hue = sin(fx / 16) + sin(fy / 8) + sin((fx + fy) / 16) + sin(sqrt((fx^2 + fy^2)) / 8)
hue = (hue + 4) / 8 # Between 0 and 1.
let rgb = to(ColorHSL([hue * 360, 1, 0.5]), ColorRGBF)
img[x, y] = rgb
img.savePNG("plasma.png")</syntaxhighlight>
 
=={{header|Ol}}==
(define (HSV->RGB H S V)
<syntaxhighlight lang="scheme">
(define C (* V S)) ; chroma
; creating the "plasma" image buffer
(define H′ (/ H 60))
(import (scheme inexact))
(define X (* C (- 1 (abs (- (real-remainder H′ 2) 1)))))
(define-values (R1 G1 B1)plasma
(fold append #null
(cond
[(<map H′ 1)(lambda (values C X 0.y)]
[(< H′ 2) (values X C 0.(map (lambda (x)]
[(< H′ 3) (values 0. C X)] (let ((value (/
[(< H′ 4) (values+ 0.(sin X(/ Cy 4))]
[(< H′ 5) (valuessin X(/ 0.(+ Cx y) 8))]
[ (<sin H′(/ 6(sqrt (+ (* x x) (values* Cy 0.y))) X8))]
[else (values 0. 0. 0. 4) 8)]))
(define m (- V C value))
(values (+ R1 m) (+ G1 m) (+ B1 m (iota 256)))
(iota 256))))
</syntaxhighlight>
<syntaxhighlight lang="scheme">
; rendering the prepared buffer (using OpenGL)
(import (lib gl1))
(gl:set-window-size 256 256)
 
(glBindTexture GL_TEXTURE_2D 0)
(glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_LINEAR)
(glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_LINEAR)
(glTexImage2D GL_TEXTURE_2D 0 GL_LUMINANCE
256 256
0 GL_LUMINANCE GL_FLOAT (cons (fft* fft-float) plasma))
 
(glEnable GL_TEXTURE_2D)
(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))
 
(gl:set-renderer (lambda (_)
(define ((plasma-flomap (ϕ 0)) w h)
(glClear GL_COLOR_BUFFER_BIT)
(build-flomap 1 w h (colour-component-by-pos ϕ)))
(glBegin GL_QUADS)
(glTexCoord2f 0 0)
(glVertex2f -1 -1)
(glTexCoord2f 0 1)
(glVertex2f -1 1)
(glTexCoord2f 1 1)
(glVertex2f 1 1)
(glTexCoord2f 1 0)
(glVertex2f 1 -1)
(glEnd)))
</syntaxhighlight>
 
=={{header|Perl}}==
(define ((plasma-image (ϕ 0)) w h)
{{trans|Raku}}
(flomap->bitmap ((plasma-flomap ϕ) w h)))
<syntaxhighlight lang="perl">use Imager;
 
(definesub ((colour-plasma plsm) t){
(let my (($w, (flomap-width$h) 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))))))
 
my $img = Imager->new(xsize => $w, ysize => $h);
;((plasma-image) 200 200)
 
for my $x (0 .. $w-1) {
;((plasma-image (/ pi 32)) 200 200)
for my $y (0 .. $h-1) {
 
my $hue = 4 + sin($x/19) + sin($y/9) + sin(($x+$y)/25) + sin(sqrt($x**2 + $y**2)/8);
(define plsm ((plasma-flomap) 300 300))
$img->setpixel(x => $x, y => $y, color => {hsv => [360 * $hue / 8, 1, 1]});
(animate (λ (t)
((colour-plasma plsm) t)))</lang>
 
=={{header|Perl 6}}==
[[File:Plasma-perl6.png|200px|thumb|right]]
{{works with|Rakudo|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) {
(^$w).race.map: -> $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);
}
}
 
return $img;
}
 
my $img = plasma(400, 400);
sub hsv2rgb ( $h, $s, $v ){
$img->write(file => 'plasma-perl.png');</syntaxhighlight>
my $c = $v * $s;
Off-site image: [https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/plasma.png Plasma effect]
my $x = $c * (1 - abs( (($h*6) % 2) - 1 ) );
my $m = $v - $c;
(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 }
} ).map: ((*+$m) * 255).Int
}</lang>
 
=={{header|Phix}}==
{{libheader|Phix/pGUI}}
{{trans|JavaScript}}
<syntaxhighlight lang="phix">-- demo\rosetta\plasma.exw
<lang Phix>--
-- demo\rosetta\plasma.exw
--
include pGUI.e
 
Line 1,220 ⟶ 1,740:
dlg = IupDialog(canvas)
IupSetAttribute(dlg, "TITLE", "Plasma")
IupCloseOnEscape(dlg)
 
IupShow(dlg)
Line 1,229 ⟶ 1,748:
end procedure
 
main()</langsyntaxhighlight>
And here's a simple console ditty, similar I think to C's ASCII version for Windows, though this also works on Linux:
<langsyntaxhighlight Phixlang="phix">sequence s = video_config()
for i=1 to s[VC_SCRNLINES]*s[VC_SCRNCOLS]-1 do
bk_color(rand(16)-1)
Line 1,237 ⟶ 1,756:
puts(1,"\xDF")
end for
{} = wait_key()</langsyntaxhighlight>
 
=={{header|Processing}}==
<syntaxhighlight lang="java">/**
Plasmas with Palette Looping
https://lodev.org/cgtutor/plasma.html#Plasmas_with_Palette_Looping_
*/
 
int pal[] = new int[128];
int[] buffer;
float r = 42, g = 84, b = 126;
boolean rd, gd, bd;
 
void setup() {
size(600, 600);
frameRate(25);
buffer = new int[width*height];
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
buffer[x+y*width] = int(((128+(128*sin(x/32.0)))
+(128+(128*cos(y/32.0)))
+(128+(128*sin(sqrt((x*x+y*y))/32.0))))/4);
}
}
}
 
void draw() {
if (r > 128) rd = true;
if (!rd) r++;
else r--;
if (r < 0) rd = false;
if (g > 128) gd = true;
if (!gd) g++;
else g--;
if (r < 0) gd = false;
if (b > 128) bd = true;
if (!bd) b++;
else b--;
if (b < 0){ bd = false;}
float s_1, s_2;
for (int i = 0; i < 128; i++) {
s_1 = sin(i*PI/25);
s_2 = sin(i*PI/50+PI/4);
pal[i] = color(r+s_1*128, g+s_2*128, b+s_1*128);
}
loadPixels();
for (int i = 0; i < buffer.length; i++) {
pixels[i] = pal[(buffer[i]+frameCount)&127];
}
updatePixels();
}</syntaxhighlight>
 
'''It can be played on line''' :<BR> [https://www.openprocessing.org/sketch/873932/ here.]
 
==={{header|Processing Python mode}}===
 
<syntaxhighlight lang="python">"""
Plasmas with Palette Looping
https://lodev.org/cgtutor/plasma.html#Plasmas_with_Palette_Looping_
"""
 
pal = [0] * 128
r = 42
g = 84
b = 126
rd = gd = bd = False
 
def setup():
global buffer
size(600, 600)
frameRate(25)
buffer = [None] * width * height
for x in range(width):
for y in range(width):
value = int(((128 + (128 * sin(x / 32.0)))
+ (128 + (128 * cos(y / 32.0)))
+ (128 + (128 * sin(sqrt((x * x + y * y)) / 32.0)))) / 4)
buffer[x + y * width] = value
 
def draw():
global r, g, b, rd, gd, bd
if r > 128: rd = True
if not rd: r += 1
else: r-=1
if r < 0: rd = False
if g > 128: gd = True
if not gd: g += 1
else: g- = 1
if r < 0: gd = False
if b > 128: bd = True
if not bd: b += 1
else: b- = 1
if b < 0: bd = False
for i in range(128):
s_1 = sin(i * PI / 25)
s_2 = sin(i * PI / 50 + PI / 4)
pal[i] = color(r + s_1 * 128, g + s_2 * 128, b + s_1 * 128)
 
loadPixels()
for i, b in enumerate(buffer):
pixels[i] = pal[(b + frameCount) % 127]
updatePixels()
</syntaxhighlight>
 
=={{header|Python}}==
{{trans|Perl 6Raku}}
 
<langsyntaxhighlight lang="python">import math
import colorsys
from PIL import Image
Line 1,259 ⟶ 1,881:
if __name__=="__main__":
im = plasma(400, 400)
im.show()</langsyntaxhighlight>
 
=={{header|Racket}}==
 
Uses `return-color-by-pos` from [[#Lisp]], because it was almost lift and shift
 
<syntaxhighlight 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)))</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
[[File:Plasma-perl6.png|200px|thumb|right]]
{{works with|Rakudo|2018.09}}
<syntaxhighlight lang="raku" line>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) {
(^$w).race.map: -> $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;
(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 }
} ).map: ((*+$m) * 255).Int
}</syntaxhighlight>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Plasma effect
 
Line 1,334 ⟶ 2,058:
d = sqrt(((a - c) * (a - c) + (b - d) * (b - d)))
return d
</syntaxhighlight>
</lang>
Output:
 
[http://www.dropbox.com/s/gdioouv328m2d60/PlasmaEffect.jpg?dl=0 Plasma effect]
 
 
=={{header|Ruby}}==
{{libheader|RubyGems}}
{{libheader|JRubyArt}}
JRubyArt is a port of Processing to the ruby language
<syntaxhighlight lang="ruby">
attr_reader :buffer, :palette, :r, :g, :b, :rd, :gd, :bd, :dim
 
def settings
size(600, 600)
end
 
def setup
sketch_title 'Plasma Effect'
frame_rate 25
@r = 42
@g = 84
@b = 126
@rd = true
@gd = true
@bd = true
@dim = width * height
@buffer = Array.new(dim)
grid(width, height) do |x, y|
buffer[x + y * width] = (
(
(128 + (128 * sin(x / 32.0))) +
(128 + (128 * cos(y / 32.0))) +
(128 + (128 * sin(Math.hypot(x, y) / 32.0)))
) / 4
).to_i
end
load_pixels
end
 
def draw
if rd
@r -= 1
@rd = false if r.negative?
else
@r += 1
@rd = true if r > 128
end
if gd
@g -= 1
@gd = false if g.negative?
else
@g += 1
@gd = true if g > 128
end
if bd
@b -= 1
@bd = false if b.negative?
else
@b += 1
@bd = true if b > 128
end
@palette = (0..127).map do |col|
s1 = sin(col * Math::PI / 25)
s2 = sin(col * Math::PI / 50 + Math::PI / 4)
color(r + s1 * 128, g + s2 * 128, b + s1 * 128)
end
dim.times do |idx|
pixels[idx] = palette[(buffer[idx] + frame_count) & 127]
end
update_pixels
end
</syntaxhighlight>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
extern crate image;
 
use image::ColorType;
use std::path::Path;
 
// Framebuffer dimensions
const WIDTH: usize = 640;
const HEIGHT: usize = 480;
 
/// Formula for plasma at any particular address
fn plasma_pixel(x: f64, y: f64) -> f64 {
((x / 16.0).sin()
+ (y / 8.0).sin()
+ ((x + y) / 16.0).sin()
+ ((x * x + y * y).sqrt() / 8.0).sin()
+ 4.0)
/ 8.0
}
 
/// Precalculate plasma field lookup-table for performance
fn create_plasma_lut() -> Vec<f64> {
let mut plasma: Vec<f64> = vec![0.0; WIDTH * HEIGHT];
for y in 0..HEIGHT {
for x in 0..WIDTH {
plasma[(y * WIDTH) + x] = plasma_pixel(x as f64, y as f64);
}
}
plasma
}
 
/// Convert from HSV float(1.0,1.0,1.0) to RGB u8 tuple (255,255,255).
/// From https://crates.io/crates/palette 0.5.0 rgb.rs, simplified for example
fn hsv_to_rgb(hue: f64, saturation: f64, value: f64) -> (u8, u8, u8) {
let c = value * saturation;
let h = hue * 6.0;
let x = c * (1.0 - (h % 2.0 - 1.0).abs());
let m = value - c;
let (red, green, blue) = match (h % 6.0).floor() as u32 {
0 => (c, x, 0.0),
1 => (x, c, 0.0),
2 => (0.0, c, x),
3 => (0.0, x, c),
4 => (x, 0.0, c),
_ => (c, 0.0, x),
};
// Convert back to RGB (where components are integers from 0 to 255)
(
((red + m) * 255.0).round() as u8,
((green + m) * 255.0).round() as u8,
((blue + m) * 255.0).round() as u8,
)
}
fn main() {
// The bitmap/framebuffer for our application. 3 u8 elements per output pixel
let mut framebuffer: Vec<u8> = vec![0; WIDTH * HEIGHT * 3];
// Generate a lookup table so we don't do too much math for every pixel.
// Do it in a function so that the local one can be immutable.
let plasma_lookup_table = create_plasma_lut();
// For each (r,g,b) pixel in our output buffer
for (index, rgb) in framebuffer.chunks_mut(3).enumerate() {
// Lookup the precalculated plasma value
let hue_lookup = plasma_lookup_table[index] % 1.0;
let (red, green, blue) = hsv_to_rgb(hue_lookup, 1.0, 1.0);
rgb[0] = red;
rgb[1] = green;
rgb[2] = blue;
}
// Save our plasma image to out.png
let output_path = Path::new("out.png");
match image::save_buffer(
output_path,
framebuffer.as_slice(),
WIDTH as u32,
HEIGHT as u32,
ColorType::RGB(8),
) {
Err(e) => println!("Error writing output image:\n{}", e),
Ok(_) => println!("Output written to:\n{}", output_path.to_str().unwrap()),
}
}
 
</syntaxhighlight>
 
=={{header|Scala}}==
===Java Swing Interoperability===
<langsyntaxhighlight Scalalang="scala">import java.awt._
import java.awt.event.ActionEvent
import java.awt.image.BufferedImage
Line 1,398 ⟶ 2,276:
})
 
}</langsyntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">require('Imager')
 
class Plasma(width=400, height=400) {
Line 1,425 ⟶ 2,304:
var plasma = Plasma(256, 256)
plasma.generate
plasma.save_as('plasma.png')</langsyntaxhighlight>
Output image: [https://github.com/trizen/rc/blob/master/img/plasma-effect-sidef.png Plasma effect]
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|DOME}}
<syntaxhighlight lang="wren">import "graphics" for Canvas, Color, ImageData
import "dome" for Window
import "math" for Math
 
class PlasmaEffect {
construct new(width, height) {
Window.title = "Plasma Effect"
Window.resize(width, height)
Canvas.resize(width, height)
_w = width
_h = height
_bmp = ImageData.create("plasma_effect", _w, _h)
_plasma = createPlasma() // stores the hues for the colors
}
 
init() {
_frame = 0
_hueShift = 0
Canvas.cls(Color.white)
}
 
createPlasma() {
var buffer = List.filled(_w, null)
for (x in 0..._w) {
buffer[x] = List.filled(_h, 0)
for (y in 0..._h) {
var value = Math.sin(x / 16)
value = value + Math.sin(y / 8)
value = value + Math.sin((x + y) / 16)
value = value + Math.sin((x * x + y * y).sqrt / 8)
value = value + 4 // shift range from -4 .. 4 to 0 .. 8
value = value / 8 // bring range down to 0 .. 1
if (value < 0 || value > 1) Fiber.abort("Hue value out of bounds")
buffer[x][y] = value
pset(x, y, Color.hsv(value * 360, 1, 1))
}
}
return buffer
}
 
pset(x, y, col) { _bmp.pset(x, y, col) }
 
pget(x, y) { _bmp.pget(x, y) }
 
update() {
_frame = _frame + 1
if (_frame % 3 == 0) { // update every 3 frames or 1/20th second
_hueShift = (_hueShift + 0.02) % 1
}
}
 
draw(alpha) {
for (x in 0..._w) {
for (y in 0..._h) {
var hue = (_hueShift + _plasma[x][y]) % 1
var col = Color.hsv(hue * 360, 1, 1)
pset(x, y, col)
}
}
_bmp.draw(0, 0)
}
}
 
var Game = PlasmaEffect.new(640, 640)</syntaxhighlight>
 
=={{header|XPL0}}==
Translation of Lode's RGB plasma, provided by link at the top of this page.
<syntaxhighlight lang="xpl0">func real Dist(X1, Y1, X2, Y2);
int X1, Y1, X2, Y2;
return sqrt( float((X1-X2)*(X1-X2) + (Y1-Y2)*(Y1-Y2)) );
 
int Time, X, Y, Color;
real Value;
[SetVid($112); \640x480x24
repeat Time:= GetTime/50_000;
for Y:= 0 to 256-1 do
for X:= 0 to 256-1 do
[Value:= Sin(Dist(X+Time, Y, 128, 128) / 8.0) +
Sin(Dist(X, Y, 64, 64) / 8.0) +
Sin(Dist(X, Y+Time/7, 192, 64) / 7.0) +
Sin(Dist(X, Y, 192, 100) / 8.0);
Color:= fix((4.0+Value) * 31.875); \[0..255]
Point(X, Y, Color<<16 + ((Color*2)&$FF)<<8 + (255-Color));
];
until KeyHit;
]</syntaxhighlight>
9,476

edits