Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

Drawing script

PadPad
edited April 2016 in OpenSesame

Hi,
I designed an experiment where at some point, the subject must draw something. I tried to do this with opensesame using python inline code but i'm experiencing fluidity troubles.
Here is what my code looks like :

from openexp.canvas import canvas
from openexp.mouse import mouse

my_mouse = mouse(exp, buttonlist = ([1]), visible = True)
my_canvas = canvas(exp)

my_canvas.show()
start = clock.time()

my_mouse.set_pos(pos=(0, 0))
while clock.time() - start <= 10000: 
    button, position, timestamp = my_mouse.get_click(timeout=10)
    x,y = position if button is not None else (None,None)

    if button is not None:
        while my_mouse.get_pressed()==(1,0,0):
            (x, y), timestamp = my_mouse.get_pos()
            #my_canvas.image(dot, x=x, y=y)
            my_canvas.circle(x, y, 4, fill=True, color='black')
            my_canvas.show()

Here is what it looks like :

I noticed that legacy backend was a bit better that xpyriment (because the circle display is faster) but it still lacks fluidity.
Any idea how i could do this ?

Comments

  • PadPad
    edited April 2016

    New code. I save coordinates (x,y) and draw lines. Looks a bit better but not perfect.

    from openexp.canvas import canvas
    from openexp.mouse import mouse
    
    my_mouse = mouse(exp, buttonlist = ([1]), visible = True)
    my_canvas = canvas(exp)
    
    dot = exp.pool[u'dot.png']
    my_canvas.show()
    start = clock.time()
    
    my_mouse.set_pos(pos=(0, 0))
    while clock.time() - start <= 30000: 
        button, position, timestamp = my_mouse.get_click(timeout=10)
        x,y = position if button is not None else (None,None)
    
        if button is not None:
            (x0, y0) = (None,None)
            while my_mouse.get_pressed()==(1,0,0):
                (x, y), timestamp = my_mouse.get_pos()
                if (x0,y0) != (None, None):
                    #my_canvas.circle(x0, y0, 4, fill=True, color='black')
                    my_canvas.line(x0,y0,x,y, penwidth=8)
                    #my_canvas.circle(x, y, 4, fill=True, color='black')
                else:
                    my_canvas.circle(x, y, 4, fill=True, color='black')
                (x0,y0) = (x,y)
                my_canvas.show()
    

    Besides, if i uncomment the two circles around the line, it looks better but it's very laggy.

    NB : this test was with xpyriment. With legacy it's less laggy, but still odd

  • edited April 2016

    Looks pretty good Pad, maybe combine the two? So a line between two sets of coordinates, but also a dot at each of those coordinates..

    [EDIT: only now do I see you already tried this, but it makes the program laggy.. you could maybe place only the dots at first, and only add all the lines at once once the mouse button is released.]

    Cheers,

    Josh

  • PadPad
    edited April 2016

    Would visually look weird if the subject presses the button more than 1sec.
    It's very laggy with xpyriment but actually with legacy it's pretty fluid.

    Here is the code that gave me the best result so far (with legacy backend)


    from openexp.canvas import canvas from openexp.mouse import mouse my_mouse = mouse(exp, buttonlist = ([1]), visible = True) my_canvas = canvas(exp) dot = exp.pool[u'dot3.png'] my_canvas.show() start = clock.time() my_mouse.set_pos(pos=(0, 0)) while clock.time() - start <= 30000: button, position, timestamp = my_mouse.get_click(timeout=10) x,y = position if button is not None else (None,None) if button is not None: (x0, y0) = (None,None) while my_mouse.get_pressed()==(1,0,0): (x, y), timestamp = my_mouse.get_pos() if (x0,y0) != (None, None): my_canvas.image(dot, x=x0, y=y0) my_canvas.line(x0,y0,x,y, penwidth=8) my_canvas.image(dot, x=x, y=y) else: my_canvas.image(dot, x=x, y=y) (x0,y0) = (x,y) my_canvas.show()

    Here is what it looks like if i draw "test" :

    dot3.png is a dot that i made with gimp with some transparency (looks better than opensesame circle and it's fast to display) :
    http://www.filedropper.com/dot3

    Looks OK, but if anyone manages to have a nicer result i would be interested.

  • PadPad
    edited 6:21PM

    Up,

    New feature i'd want to add : being able to "replay" the drawing, exactly like if the screen had been recorded.

    I have a few ideas of how i could implement this :
    1) working with canvas

    • save somewhere every canvas before a canvas.show() and re-load them when we want to replay. In this solution, the timing won't be accurate.
    • save the canvas every X ms and re-load them later

    2) working with images

    • save screenshots of the canvas. This solution will probably be too slow.

    3) working with coordinates

    • save coordinates of each dot and each line that has been drawn (every X ms) and redraw everything for the replay

    Does anyone have advices ? I initially tried to implement the first solution, but i encounter an unknown problem (opensesame crashes) when i try to save canvas objects in a list. I'm not really used to python neither to object programming so maybe i'm making mistakes when trying to save the objects in another variable... Here is what my code looks like :

    all_canvas=[] # list where i want to store every canvas
    
    # ...
    # code here
    # ...
    
    c = canvas(exp)
    c.copy(my_canvas) #my_canvas is the current canvas i want to save
    all_canvas.append(c)
    
    my_canvas.show()
    
  • edited 6:21PM

    Hello, sorry for asking but I wanted to do the same thing. Indeed I want people to read a text and draw a cross on certain letters. So I want to show a text pictures and allow people to draw on it and save the new one..
    Were you able to do what you want ?

    Thanks

  • PadPad
    edited 6:21PM

    Hello Amandine,

    Is it very important that they draw the cross ? Can't they just click on the letter ? If a click is ok, you can simply design a cross on Paint (in png format for transparency) and simply display this cross (using canvas.image() function) when the users clicks on the screen.

  • edited 6:21PM

    Hello,
    No it's not important that they draw the cross. So thank's for the answer it works very well :)

Sign In or Register to comment.