-
Notifications
You must be signed in to change notification settings - Fork 891
/
pie.py
175 lines (150 loc) · 5.77 KB
/
pie.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
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)