Peripheral drift illusion

From Rosetta Code
Revision as of 17:55, 30 August 2021 by Wherrera (talk | contribs) (typo)
Peripheral drift illusion is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Generate and display a Peripheral Drift Illusion

The image appears to be moving even though it is perfectly static.

References


Julia

Line color tables taken from the Wren example. <lang julia>using Gtk, Colors, Cairo

function CodepenApp()

   # left-top, top-right, right-bottom, bottom-left
   LT, TR, RB, BL = 1, 2, 3, 4
   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]]
   W, B = colorant"white", colorant"darkgray"
   colors = [
       [W, B, B, W],
       [W, W, B, B],
       [B, W, W, B],
       [B, B, W, W]]
   win = GtkWindow("Peripheral drift illusion", 230, 230) |> (can = GtkCanvas())
   @guarded draw(can) do widget
       ctx = Gtk.getgc(can)
       function line(x1, y1, x2, y2, colr)
           set_source(ctx, colr)
           move_to(ctx, x1, y1)
           line_to(ctx, x2, y2)
           stroke(ctx)
       end
       set_source(ctx, colorant"yellow")
       rectangle(ctx, 0, 0, 250, 250)
       fill(ctx)
       set_line_width(ctx, 2)
       for x in 1:12
           px = 18 + x * 14
           for y in 1:12
               py = 18 + y * 14
               set_source(ctx, colorant"skyblue")
               rectangle(ctx, px, py, 10, 10)
               fill(ctx)
               carray = colors[edges[y][x]]
               line(px, py, px + 9, py, carray[1])
               line(px + 9, py, px + 9, py + 9, carray[2])
               line(px + 9, py + 9, px, py + 9, carray[3])
               line(px, py + 9, px, py, carray[4])
           end
       end
   end
   showall(win)
   draw(can)
   condition = Condition()
   endit(w) = notify(condition)
   signal_connect(endit, win, :destroy)
   showall(win)
   wait(condition)

end

CodepenApp() </lang>

Phix

Library: Phix/online

You can run this online here.

--
-- demo\rosetta\Peripheral_Drift_Illusion.exw
-- ==========================================
--
-- converted from https://codepen.io/josetxu/pen/rNmXjrq
--
with javascript_semantics
include pGUI.e
Ihandle dlg, canvas
cdCanvas cdcanvas

constant title = "Peripheral Drift Illusion",
         CD_LIGHT_OLIVE = #d3d004,
         CD_PALE_BLUE = #3250ff,
         dxy = {{45,45},{0,45},{0,0},{45,0},{45,45},{0,45}}

function redraw_cb(Ihandle /*ih*/, integer /*posx*/, /*posy*/)
    integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE")
    cdCanvasActivate(cdcanvas)
    cdCanvasSetBackground(cdcanvas, CD_LIGHT_OLIVE)
    cdCanvasClear(cdcanvas)
    integer c = 0,
            cy = floor(height/2)*2-81
    while cy>100 do
        integer d = c,
                cx = 81
        while cx<width-100 do
            cdCanvasSetForeground(cdcanvas, CD_WHITE)
            cdCanvasBox(cdcanvas, cx, cx+45, cy, cy-45)
            cdCanvasSetForeground(cdcanvas, CD_BLACK)
            cdCanvasBegin(cdcanvas, CD_FILL)
            for i=4 to 6 do
                integer {dy,dx} = dxy[i-d]
                cdCanvasVertex(cdcanvas, cx+dx, cy-dy)
            end for
            cdCanvasEnd(cdcanvas)
            cdCanvasSetForeground(cdcanvas, CD_PALE_BLUE)
            cdCanvasBox(cdcanvas, cx+4, cx+41, cy-4, cy-41)
            d = remainder(d+(odd(cx)==odd(cy)),4)
            cx += 63
        end while
        c = remainder(c+4-even(cy),4)
        cy -= 63
    end while
    cdCanvasFlush(cdcanvas)
    return IUP_DEFAULT
end function

function map_cb(Ihandle ih)
    atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
    IupGLMakeCurrent(canvas)
    if platform()=JS then
        cdcanvas = cdCreateCanvas(CD_IUP, canvas)
    else
        cdcanvas = cdCreateCanvas(CD_GL, "10x10 %g", {res})
    end if
    cdCanvasSetBackground(cdcanvas, CD_PARCHMENT)
    return IUP_DEFAULT
end function

function canvas_resize_cb(Ihandle /*canvas*/)
    integer {cw, ch} = IupGetIntInt(canvas, "DRAWSIZE")
    atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
    cdCanvasSetAttribute(cdcanvas, "SIZE", "%dx%d %g", {cw, ch, res})
    return IUP_DEFAULT
end function

procedure main()
    IupOpen()
    canvas = IupGLCanvas("RASTERSIZE=780x600") -- (sensible restore size)
    sequence cb = {"MAP_CB", Icallback("map_cb"),
                   "ACTION", Icallback("redraw_cb"),
                   "RESIZE_CB", Icallback("canvas_resize_cb")}
    IupSetCallbacks(canvas, cb)
    dlg = IupDialog(canvas,`TITLE="%s",PLACEMENT=MAXIMIZED`,{title})
    IupShow(dlg)
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure
main()

Wren

Library: DOME

This reproduces the codepen image and does indeed appear to move although it's static. <lang ecmascript>import "dome" for Window import "graphics" for Canvas, Color

// signifies the white edges on the blue squares var LT = 0 var TR = 1 var RB = 2 var BL = 3

var 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]

]

var Light_olive = Color.hex("#d3d004") var Pale_blue = Color.hex("#3250ff")

var W = Color.white var B = Color.black

var Colors = [

   [W, B, B, W],
   [W, W, B, B],
   [B, W, W, B],
   [B, B, W, W]

]

class PeripheralDrift {

   construct new() {
       Window.resize(1000, 1000)
       Canvas.resize(1000, 1000)
       Window.title = "Peripheral drift illusion"
   }
   init() {
       Canvas.cls(Light_olive)
       for (x in 0..11) {
           var px = 90 + x * 70
           for (y in 0..11) {
               var py = 90 + y * 70
               Canvas.rectfill(px, py, 50, 50, Pale_blue)
               drawEdge(px, py, Edges[y][x])
           }
       }
   }
   drawEdge(px, py, edge) {
       var c = Colors[edge]
       Canvas.line(px, py, px + 46, py, c[0], 4)
       Canvas.line(px + 46, py, px + 46, py + 46, c[1], 4)
       Canvas.line(px, py + 46, px + 46, py + 46, c[2], 4)
       Canvas.line(px, py + 46, px, py, c[3], 4)
   }
   update() {}
   draw(alpha) {}

}

var Game = PeripheralDrift.new()</lang>