Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2652 from mdcutone/pie-stim
NF: `Pie` shape class for pac-man shapes.
- Loading branch information
Showing
4 changed files
with
225 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
|
||
:class:`Pie` | ||
------------------------------------ | ||
.. autoclass:: psychopy.visual.Pie | ||
:members: | ||
:undoc-members: | ||
:inherited-members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
"""Demo for the class psychopy.visual.Pie(). | ||
Use the `Pie` class to create a Kanizsa figure which produces illusory | ||
contours. | ||
""" | ||
from psychopy import core | ||
import psychopy.visual as visual | ||
from psychopy.visual import Pie | ||
from psychopy import event | ||
|
||
# open a window to render the shape | ||
win = visual.Window((600, 600), allowGUI=False, monitor='testMonitor') | ||
|
||
# create the stimulus object | ||
pieStim = Pie( | ||
win, radius=50, start=0., end=270., fillColor=(-1., -1., -1.), units='pix') | ||
|
||
message = visual.TextStim( | ||
win, text='Any key to quit', pos=(0, -0.8), units='norm') | ||
|
||
# positions of the corners of the shapes | ||
pos = [(-100, 100), (100, 100), (-100, -100), (100, -100)] | ||
|
||
# orientations of the shapes | ||
ori = [180., 270., 90., 0.] | ||
|
||
while not event.getKeys(): | ||
|
||
for i in range(4): | ||
pieStim.pos = pos[i] | ||
pieStim.ori = ori[i] | ||
pieStim.draw() | ||
|
||
message.draw() | ||
win.flip() | ||
|
||
win.close() | ||
core.quit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
|
||
"""Create a pie shape.""" | ||
|
||
# Part of the PsychoPy library | ||
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019 Open Science Tools Ltd. | ||
# Distributed under the terms of the GNU General Public License (GPL). | ||
|
||
from __future__ import absolute_import, print_function | ||
from psychopy.visual.shape import BaseShapeStim | ||
from psychopy.tools.attributetools import attributeSetter, setAttribute | ||
import numpy as np | ||
|
||
|
||
class Pie(BaseShapeStim): | ||
"""Creates a pie shape which is a circle with a wedge cut-out. | ||
This shape is sometimes referred to as a Pac-Man shape which is often | ||
used for creating Kanizsa figures. However, the shape can be adapted for | ||
other uses. | ||
Attributes | ||
---------- | ||
start, end : float or int | ||
Start and end angles of the filled region of the shape in | ||
degrees. Shapes are filled counter clockwise between the specified | ||
angles. | ||
radius : float or int | ||
Radius of the shape. Avoid using `size` for adjusting figure dimensions | ||
if radius != 0.5 which will result in undefined behavior. | ||
""" | ||
def __init__(self, | ||
win, | ||
radius=.5, | ||
start=0.0, | ||
end=90.0, | ||
edges=32, | ||
units='', | ||
lineWidth=1.5, | ||
lineColor=None, | ||
lineColorSpace='rgb', | ||
fillColor=None, | ||
fillColorSpace='rgb', | ||
pos=(0, 0), | ||
size=1, | ||
ori=0.0, | ||
opacity=1.0, | ||
contrast=1.0, | ||
depth=0, | ||
interpolate=True, | ||
lineRGB=None, | ||
fillRGB=None, | ||
name=None, | ||
autoLog=None, | ||
autoDraw=False, | ||
color=None, | ||
colorSpace=None): | ||
|
||
""" | ||
Parameters | ||
---------- | ||
win : `~psychopy.visual.Window` | ||
Window this shape is associated with. | ||
radius : float or int | ||
Radius of the shape. Avoid using `size` for adjusting figure | ||
dimensions if radius != 0.5 which will result in undefined behavior. | ||
start, end : float or int | ||
Start and end angles of the filled region of the shape in | ||
degrees. Shapes are filled counter clockwise between the specified | ||
angles. | ||
edges : int | ||
Number of edges to use when drawing the figure. A greater number of | ||
edges will result in smoother curves, but will require more time | ||
to compute. | ||
""" | ||
self.__dict__['radius'] = radius | ||
self.__dict__['edges'] = edges | ||
self.__dict__['start'] = start | ||
self.__dict__['end'] = end | ||
|
||
self.vertices = self._calcVertices() | ||
|
||
super(Pie, self).__init__( | ||
win, | ||
units=units, | ||
lineWidth=lineWidth, | ||
lineColor=lineColor, | ||
lineColorSpace=lineColorSpace, | ||
fillColor=fillColor, | ||
fillColorSpace=fillColorSpace, | ||
vertices=self.vertices, | ||
closeShape=True, | ||
pos=pos, | ||
size=size, | ||
ori=ori, | ||
opacity=opacity, | ||
contrast=contrast, | ||
depth=depth, | ||
interpolate=interpolate, | ||
lineRGB=lineRGB, | ||
fillRGB=fillRGB, | ||
name=name, | ||
autoLog=autoLog, | ||
autoDraw=autoDraw, | ||
color=color, | ||
colorSpace=colorSpace) | ||
|
||
def _calcVertices(self): | ||
"""Calculate the required vertices for the figure. | ||
""" | ||
startRadians = np.radians(self.start) | ||
endRadians = np.radians(self.end) | ||
|
||
# get number of steps for vertices | ||
edges = self.__dict__['edges'] | ||
steps = np.linspace(startRadians, endRadians, num=edges) | ||
|
||
# offset by 1 since the first vertex needs to be at centre | ||
verts = np.zeros((edges + 2, 2), float) | ||
verts[1:-1, 0] = np.sin(steps) | ||
verts[1:-1, 1] = np.cos(steps) | ||
|
||
verts *= self.radius | ||
|
||
return verts | ||
|
||
@attributeSetter | ||
def start(self, value): | ||
"""Start angle of the slice/wedge in degrees (`float` or `int`). | ||
:ref:`Operations <attrib-operations>` supported. | ||
""" | ||
self.__dict__['start'] = value | ||
self.vertices = self._calcVertices() | ||
self.setVertices(self.vertices, log=False) | ||
|
||
def setStart(self, start, operation='', log=None): | ||
"""Usually you can use 'stim.attribute = value' syntax instead, | ||
but use this method if you need to suppress the log message | ||
""" | ||
setAttribute(self, 'start', start, log, operation) | ||
|
||
@attributeSetter | ||
def end(self, value): | ||
"""End angle of the slice/wedge in degrees (`float` or `int`). | ||
:ref:`Operations <attrib-operations>` supported. | ||
""" | ||
self.__dict__['end'] = value | ||
self.vertices = self._calcVertices() | ||
self.setVertices(self.vertices, log=False) | ||
|
||
def setEnd(self, end, operation='', log=None): | ||
"""Usually you can use 'stim.attribute = value' syntax instead, | ||
but use this method if you need to suppress the log message | ||
""" | ||
setAttribute(self, 'end', end, log, operation) | ||
|
||
@attributeSetter | ||
def radius(self, value): | ||
"""Radius of the shape in `units` (`float` or `int`). | ||
:ref:`Operations <attrib-operations>` supported. | ||
""" | ||
self.__dict__['radius'] = value | ||
self.vertices = self._calcVertices() | ||
self.setVertices(self.vertices, log=False) | ||
|
||
def setRadius(self, end, operation='', log=None): | ||
"""Usually you can use 'stim.attribute = value' syntax instead, | ||
but use this method if you need to suppress the log message | ||
""" | ||
setAttribute(self, 'radius', end, log, operation) |