Peripheral drift illusion: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (Ada: Comment)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(13 intermediate revisions by 6 users not shown)
Line 12:
 
=={{header|Action!}}==
<langsyntaxhighlight Actionlang="action!">PROC DrawTile(INT x BYTE y,flip,c1,c2)
BYTE i
 
Line 78:
DO UNTIL CH#$FF OD
CH=$FF
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Peripheral_drift_illusion.png Screenshot from Atari 8-bit computer]
Line 85:
{{trans|Wren}}
{{libheader|APDF}}
<langsyntaxhighlight Adalang="ada">with PDF_Out; use PDF_Out;
 
procedure Drift is
Line 184:
Draw_Squares;
PDF.Close;
end Drift;</langsyntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{trans|Wren,XPL0}}
{{libheader|SysUtils,StdCtrls}}
 
[[File:DelphiPerirpheralDrift.png|frame|none]]
<syntaxhighlight lang="Delphi">
 
 
{The illusion works by drawing light/dark edges around
{the squares in an inconsistent pattern that confuses}
{the eye about whethe squares are raise or lowered}
 
{Specifies corner on which the white lines are drawn}
 
type TCorners = (crTopLeft = 0,crTopRght = 1,crBtmLeft = 3,crBtmRght = 2);
 
{Array of edge patterns}
 
const Edges: array [0..12-1] of array [0..12-1] of TCorners =(
(crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght),
(crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft),
(crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft),
(crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft),
(crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft),
(crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght),
(crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght),
(crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght),
(crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght),
(crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft),
(crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft),
(crTopRght, crTopRght, crTopLeft, crTopLeft, crBtmLeft, crBtmLeft, crBtmRght, crBtmRght, crTopRght, crTopRght, crTopLeft, crTopLeft));
 
{Base colors}
 
const LightOlive: TColor = $04D0D3;
const PaleBlue: TColor = $FF523E;
 
{Patterns of edge colors}
 
type TColorArray = array [0..4-1] of array [0..4-1] of TColor;
 
const Colors: TColorArray = (
(clWhite, clBlack, clBlack, clWhite),
(clWhite, clWhite, clBlack, clBlack),
(clBlack, clWhite, clWhite, clBlack),
(clBlack, clBlack, clWhite, clWhite));
 
 
 
procedure DrawEdge(Canvas: TCanvas; PX, PY, Size: integer; Colors: TColorArray; Edge: TCorners);
{Draw edges around square}
begin
Canvas.MoveTo(PX, PY);
Canvas.Pen.Color:=Colors[Integer(Edge),0];
Canvas.LineTo(PX+Size, PY);
Canvas.Pen.Color:=Colors[Integer(Edge),1];
Canvas.LineTo(PX+Size, PY+Size);
Canvas.Pen.Color:=Colors[Integer(Edge),2];
Canvas.LineTo(PX, PY+Size);
Canvas.Pen.Color:=Colors[Integer(Edge),3];
Canvas.LineTo(PX, PY);
end;
 
 
procedure DrawPeripheralDrift(Image: TImage);
{Draw Peripheral Drift illusion}
var WWidth,WHeight: integer;
var X,Y,PX,PY: integer;
var SqrSize,Border,Spacing,InSquare,CellSize: integer;
begin
{Calculate base size from window size}
WWidth:=Min(Image.Width,Image.Height);
WHeight:=WWidth;
{Calculate border, square and spacing from base size}
InSquare:=MulDiv(WWidth,780,1000);
Border:=(WWidth-InSquare) div 2;
CellSize:=InSquare div 12;
 
SqrSize:=MulDiv(CellSize,75,100);
Spacing:=MulDiv(CellSize,25,100);
 
{Draw background rectangel}
Image.Canvas.Brush.Color:=LightOlive;
Image.Canvas.Rectangle(0,0,WWidth,WHeight);
 
{Draw 12x12 grid of squares}
for X:= 0 to 12-1 do
begin
PX:= Border + X*CellSize;
for Y:= 0 to 12-1 do
begin
PY:= Border + Y*CellSize;
{Draw square}
Image.Canvas.Brush.Color:=PaleBlue;
Image.Canvas.Pen.Color:=PaleBlue;
Image.Canvas.Rectangle(PX, PY, PX+SqrSize, PY+SqrSize);
{Draw edges, which causes the illusion}
DrawEdge(Image.Canvas, PX, PY, SqrSize, Colors, Edges[Y,X]);
end;
end;
Image.Invalidate;
end;
 
procedure ShowPeripheralDrift(Image: TImage);
begin
DrawPeripheralDrift(Image);
end;
 
 
 
</syntaxhighlight>
{{out}}
<pre>
Elapsed Time: 6.274 ms.
 
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Peripheral_drift_illusion}}
 
'''Solution'''
 
The following function generates a Paul Nasca peripheral drift illusion:
 
[[File:Fōrmulæ - Peripheral drift illusion 01.png]]
 
'''Test case:'''
 
[[File:Fōrmulæ - Peripheral drift illusion 02.png]]
 
[[File:Fōrmulæ - Peripheral drift illusion 03.png]]
 
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
 
public final class PeripheralDriftIllusion {
 
public static void main(String[] aArgs) {
EventQueue.invokeLater( () -> {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Peripheral Drift Illusion");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new PeripheralDrift() );
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
} );
}
}
 
final class PeripheralDrift extends JPanel {
public PeripheralDrift() {
setPreferredSize( new Dimension(600, 600) );
setBackground(LIGHT_OLIVE);
}
@Override
public void paintComponent(Graphics aGraphics) {
super.paintComponent(aGraphics);
Graphics2D graphics2D = (Graphics2D) aGraphics;
graphics2D.setStroke( new BasicStroke(3.0F) );
drawPeripheralDrift(graphics2D);
}
private void drawPeripheralDrift(Graphics2D aGraphics2D) {
final int panelWidth = getWidth();
final int outerSquare = panelWidth * 80 / 100;
final int border = ( panelWidth - outerSquare ) / 2;
final int cellSize = outerSquare / 12;
final int boxSize = cellSize * 75 / 100;
final int margin = ( cellSize - boxSize ) / 2;
for ( int row = 0; row < 12; row++ ) {
int x = border + margin + row * cellSize;
for ( int col = 0; col < 12; col++ ) {
int y = border + margin + col * cellSize;
drawBox(x, y, boxSize, EDGES.get(col).get(row), aGraphics2D);
}
}
}
private void drawBox(int aX, int aY, int aSize, Edg aEdge, Graphics2D aGraphics2D) {
aGraphics2D.setColor(PALE_BLUE);
aGraphics2D.fillRect(aX, aY, aSize, aSize);
aGraphics2D.setColor(COLORS.get(aEdge.index).get(0));
aGraphics2D.drawLine(aX, aY, aX + aSize, aY);
aGraphics2D.setColor(COLORS.get(aEdge.index).get(1));
aGraphics2D.drawLine(aX + aSize, aY, aX + aSize, aY + aSize);
aGraphics2D.setColor(COLORS.get(aEdge.index).get(2));
aGraphics2D.drawLine(aX + aSize, aY + aSize, aX, aY + aSize);
aGraphics2D.setColor(COLORS.get(aEdge.index).get(3));
aGraphics2D.drawLine(aX, aY + aSize, aX, aY);
}
 
private enum Edg {
TL(0), TR(1), BR(2), BL(3);
private Edg(int aIndex) {
index = aIndex;
}
private final int index;
}
 
private static final List<List<Edg>> EDGES = List.of(
List.of( Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR ),
List.of( Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL ),
List.of( Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL ),
List.of( Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL ),
List.of( Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL ),
List.of( Edg.BR, Edg.BR, Edg.TR, Edg.BR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR ),
List.of( Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR ),
List.of( Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR ),
List.of( Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR ),
List.of( Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL ),
List.of( Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL ),
List.of( Edg.TR, Edg.TR, Edg.TL, Edg.TL, Edg.BL, Edg.BL, Edg.BR, Edg.BR, Edg.TR, Edg.TR, Edg.TL, Edg.TL ) );
private static final List<List<Color>> COLORS = List.of(
List.of( Color.WHITE, Color.BLACK, Color.BLACK, Color.WHITE ),
List.of( Color.WHITE, Color.WHITE, Color.BLACK, Color.BLACK ),
List.of( Color.BLACK, Color.WHITE, Color.WHITE, Color.BLACK ),
List.of( Color.BLACK, Color.BLACK, Color.WHITE, Color.WHITE ) );
private static final Color PALE_BLUE = new Color(51, 77, 255);
private static final Color LIGHT_OLIVE = new Color(204, 204, 0);
}
</syntaxhighlight>
{{ out }}
[[Media:PeripheralDriftJava.PNG]]
 
=={{header|Julia}}==
Line color tables taken from the Wren example. See the output [https://imgur.com/jKqIgbe on imgur].
<langsyntaxhighlight lang="julia">using Gtk, Colors, Cairo
 
function CodepenApp()
Line 250 ⟶ 499:
 
CodepenApp()
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
Line 257 ⟶ 506:
A translation using Gtk via the <code>gintro</code> bindings for Nim, so the code is quite different. We chose also different sizes for the window and the grid, and colors closer to those of the codepen demo.
 
<syntaxhighlight lang="nim">import gintro/[glib, gobject, gtk, gio, cairo]
See window screenshot [https://github.com/lscrd/Rosetta/blob/main/Images/Peripheral_drift_illusion-Nim.png here.]
 
<lang Nim>import gintro/[glib, gobject, gtk, gio, cairo]
 
const
Line 353 ⟶ 600:
let app = newApplication(Application, "Rosetta.Illusion")
discard app.connect("activate", activate)
discard app.run()</langsyntaxhighlight>
 
{{out}}
Window screenshot:
[[File:Peripheral drift illusion (Nim).png|center|Peripheral drift illusion]]
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
 
Line 386 ⟶ 637:
open my $fh, '>', 'peripheral-drift.svg';
print $fh $svg;
close $fh;</langsyntaxhighlight>
See [https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/peripheral-drift.svg offsite SVG image]
 
Line 392 ⟶ 643:
{{libheader|Phix/online}}
You can run this online [http://phix.x10.mx/p2js/Peripheral_Drift_Illusion.htm here].
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Peripheral_Drift_Illusion.exw
Line 475 ⟶ 726:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
 
=={{header|Raku}}==
<syntaxhighlight lang="raku" perl6line>use SVG;
 
my @blocks = (1..15 X 1..10).map: -> ($X, $Y) {
Line 501 ⟶ 752:
|@blocks,
]
)</langsyntaxhighlight>
See [https://github.com/thundergnat/rc/blob/master/img/peripheral-drift-raku.svg offsite SVG image]
 
Line 508 ⟶ 759:
This reproduces the codepen image and does indeed appear to move although it's static.
See the output [https://imgur.com/xyVcnif on imgur]
<langsyntaxhighlight ecmascriptlang="wren">import "dome" for Window
import "graphics" for Canvas, Color
 
Line 577 ⟶ 828:
}
 
var Game = PeripheralDrift.new()</langsyntaxhighlight>
 
=={{header|XPL0}}==
The illusion is more effective when the image is displayed full-screen.
{{trans|Wren}}
<syntaxhighlight lang "XPL0">proc DrawRect(X0, Y0, W, H, Color);
int X0, Y0, W, H, Color, Y;
for Y:= Y0 to Y0+H-1 do
[Move(X0, Y); Line(X0+W-1, Y, Color)];
 
proc DrawEdge(PX, PY, Colors, Edge);
int PX, PY, Colors, Edge;
int C;
[C:= Colors(Edge);
Move(PX, PY);
Line(PX+11, PY, C(0));
Line(PX+11, PY+11, C(1));
Line(PX, PY+11, C(2));
Line(PX, PY, C(3));
];
 
def ScrW=256, ScrH=256;
def LT=0, TR=1, RB=2, BL=3; \left top, etc.
def White = $ffffff, Black = 0;
def LightOlive = $d3d004, PaleBlue = $3250ff;
int Edges, Colors, X, Y, PX, PY;
[SetFB(ScrW, ScrH, 24);
\Signifies white and black edges on the blue squares
Edges:= [
[LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL, RB],
[LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL],
[TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL],
[TR, TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT],
[RB, TR, TR, LT, LT, BL, BL, RB, RB, TR, TR, LT],
[RB, RB, TR, TR, LT, LT, BL, BL, RB, RB, TR, TR],
[BL, RB, RB, TR, TR, LT, LT, BL, BL, RB, RB, TR],
[BL, BL, RB, RB, TR, TR, LT, LT, BL, BL, RB, RB],
[LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL, RB],
[LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL],
[TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL],
[TR, TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT] ];
Colors:= [
[White, Black, Black, White],
[White, White, Black, Black],
[Black, White, White, Black],
[Black, Black, White, White] ];
DrawRect(0, 0, ScrW, ScrH, LightOlive);
for X:= 0 to 11 do
[PX:= 27 + X*17;
for Y:= 0 to 11 do
[PY:= 27 + Y*17;
DrawRect(PX, PY, 12, 12, PaleBlue);
DrawEdge(PX, PY, Colors, Edges(Y,X));
];
];
]</syntaxhighlight>
{{out}}
[[File:PdriftXPL0.png]]
9,476

edits