File: _circle.py

package info (click to toggle)
python-expyriment 0.7.0%2Bgit34-g55a4e7e-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,504 kB
  • ctags: 2,094
  • sloc: python: 12,766; makefile: 150
file content (163 lines) | stat: -rw-r--r-- 4,393 bytes parent folder | download | duplicates (2)
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
#!/usr/bin/env python

"""
A circle stimulus.

This module contains a class implementing a circle stimulus.

"""

__author__ = 'Florian Krause <florian@expyriment.org>, \
Oliver Lindemann <oliver@expyriment.org>'
__version__ = '0.7.0'
__revision__ = '55a4e7e'
__date__ = 'Wed Mar 26 14:33:37 2014 +0100'


import math

import defaults
from _ellipse import Ellipse


class Circle(Ellipse):
    """A class implementing a basic 2D circle."""

    def __init__(self, diameter, colour=None, line_width=None, position=None):
        """Create a circle.

        Parameters
        ----------
        diameter : int
            diameter of the circle
        colour : (int,int,int), optional
            colour of the circle
        line_width : int, optional
            line width in pixels; 0 or a value larger the radius will result
            in a filled circle
        position : (int, int), optional
            position of the stimulus

        """

        self._diameter = diameter
        self._radius = diameter/2.0
        if position is None:
            position = defaults.circle_position
        if colour is None:
            colour = defaults.circle_colour
        if line_width is None:
            line_width = defaults.circle_line_width
        elif line_width < 0 or line_width >= self._diameter/2.0:
            raise AttributeError("line_width must be >= 0 and < diameter/2!")
        Ellipse.__init__(self, [diameter, diameter], colour, line_width,
                         position)

    _getter_exception_message = "Cannot set {0} if surface exists!"

    @property
    def diameter(self):
        """Getter for diameter."""
        return self._diameter

    @diameter.setter
    def diameter(self, value):
        """Setter for diameter."""

        if self.has_surface:
            raise AttributeError(Circle._getter_exception_message.format(
                "diameter"))
        else:
            self._diameter = value

    @property
    def radius(self):
        """Getter for radius."""
        return self._radius

    def get_polar_coordiantes(self):
        """Returns tuple with polar coordinates (radial, angle in degrees)."""
        angle = math.atan2(self._position[1], self._position[0])
        angle = angle / math.pi * 180
        radial = math.sqrt ((self._position[0] * self._position[0]) +
                            (self._position[1] * self._position[1]))
        return (radial, angle)

    def set_polar_coordinates(self, radial, angle_in_degrees):
        """Set polar coordinates.

        Parameters
        ----------
        radial : int
            radial to set
        angle_in_degrees : float
            angle of degrees to set

        """

        a = angle_in_degrees / 180.0 * math.pi
        self._position[0] = radial * math.cos(a)
        self._position[1] = radial * math.sin(a)

    def overlapping_with_circle(self, other, minimal_gap=0):
        """Return True if touching or overlapping with another circle.

        Parameters
        ----------
        other : expyriment.stimuli.Circle object
            other circle
        minimal_gap : int, optional
            minimum gap between two circle, small gaps will be treated as
            overlapping (default=0)

        Returns
        -------
        is_inside : bool

        """

        d = self.distance(other)
        return (d - minimal_gap <= other._radius + self._radius)

    def center_inside_circle(self, other):
        """Return True if the center is inside another circle.

        Parameters
        ----------
        other : expyriment.stimuli.Circle object
            other circle

        Returns
        -------
        is_inside : bool

        """

        d = self.distance(other)
        return (d <= other._radius)

    def inside_circle(self, other):
        """Return True if the whole circle is inside another circle.

        Parameters
        ----------
        other : expyriment.stimuli.Circle object
            other circle

        Returns
        -------
        is_inside : bool

        """

        d = self.distance(other)
        return (d <= other._radius - self._radius)

if __name__ == "__main__":
    from expyriment import control
    control.set_develop_mode(True)
    defaults.event_logging = 0
    exp = control.initialize()
    dot = Circle(diameter=100, line_width=3)
    dot.present()
    exp.clock.wait(1000)