예제 #1
0
 def shortestDistanceFromWall(self, point):
     '''returns the shortest distance of the point to
         a maze wall in degrees'''
     from psychopy.event import xydist
     point-=self.pos
     X=Maze.I; Y = Maze.J
     (gx,gy)=self.dispSize/2.0
     arena=(((-gx,-gy),(gx,-gy)), ((gx,-gy),(gx,gy)),
         ((-gx,gy),(gx,gy)),((-gx,gy),(-gx,-gy)))
     # check outside walls
     dists=(abs(point[Y]+gy), abs(-point[X]+gx),
         abs(-point[Y]+gy),abs(point[X]+gx))
     shd = min(dists)
     edge=arena[dists.index(shd)]
     # check the lines
     for line in self.lineXY:
         dim=int(line[1][X]==line[0][X])
         # 1 is vertical
         mx=int(line[0][dim]<line[1][dim])
         mn=1-mx
         if point[dim]>line[mx][dim]:
             d=xydist(point,line[mx])
             ol=line[mx]
         elif point[dim]<line[mn][dim]:
             d=xydist(point,line[mn])
             ol=line[mn]
         else:
             d=abs(point[1-dim]-line[0][1-dim])
             ol=line
         if d<shd:
             shd=d; edge=ol
     #print shd,point, edge
     return shd-self.lw/2.0, edge
예제 #2
0
def circleLine(p0,lin1,lin2,r):
    """ compute circle line intersetion
        p0 - circle center
        lin1, lin2 - line edges
        r - circle radius
    """
    # translate first
    p2=lin2-p0; p1=lin1-p0
    dpos=p2-p1
    dr=dpos[X]**2+dpos[Y]**2
    det=p1[X]*p2[Y]-p1[Y]*p2[X]
    discriminant= dr*r**2-det**2
    if discriminant<0:
        raise NameError('No intersection')
    temp1=(2*bool(dpos[Y]>=0)-1)*dpos[X]*discriminant**0.5
    temp2=abs(dpos[Y])*discriminant**0.5
    inter=(((det*dpos[Y]+temp1)/dr,
        (-det*dpos[X]+temp2)/dr),
        ((det*dpos[Y]-temp1)/dr,
        (-det*dpos[X]-temp2)/dr))
    # output point which is nearer to p1
    i= (xydist(p1,inter[0])+xydist(p2,inter[0]) >
        xydist(p1,inter[1])+xydist(p2,inter[1]))
    # check whether inter lies between line edges
    cw=xydist(p1,p2)
    if xydist(p1,inter[i])>=cw or xydist(p2,inter[i])>=cw:
        raise NameError('Intersection out of bounds')
    return np.array(inter[i])+p0
 def getJudgment(self,giveFeedback=False):
     '''asks subject to select chaser chasee'''
     position=np.transpose(self.pos)
     cond=position.shape[1]
     self.mouse.clickReset();self.mouse.setVisible(1)
     elem=self.elem
     t0=core.getTime();selected=[]
     mkey=self.mouse.getPressed()
     lastPress=t0
     while sum(mkey)>0:
         elem.draw()
         self.wind.flip()
         mkey=self.mouse.getPressed()
     released=True
     clrs=np.ones((cond,1))*Q.agentCLR
     while len(selected) <2:
         elem.draw()
         self.wind.flip()
         mpos=self.mouse.getPos()
         mkey=self.mouse.getPressed()
         mtime=core.getTime()
         for a in range(cond):
             if (event.xydist(mpos,np.squeeze(position[:,a]))
                 < Q.agentRadius*self.scale):
                 if 0<sum(mkey) and released: # button pressed
                     if selected.count(a)==0: # avoid selecting twice
                         clrs[a]=Q.selectedCLR
                         elem.setColors(clrs,'rgb')
                         selected.append(a)
                         self.output.write('\t%d\t%2.4f' % (a,mtime-t0))
                     released=False
                 elif a in selected: # no button pressed but selected already
                     clrs[a]=Q.selectedCLR
                     elem.setColors(clrs,'rgb')
                 else: # no button pressed but mouse cursor over agent
                     clrs[a]=Q.mouseoverCLR
                     elem.setColors(clrs,'rgb')
             elif a in selected: # no button pressed, no cursor over agent, but already selected
                 clrs[a]=Q.selectedCLR
                 elem.setColors(clrs,'rgb')
             else: # no button press, no cursor over agent, not selected
                 clrs[a]=Q.agentCLR
                 elem.setColors(clrs,'rgb')
         if 0==sum(mkey) and not released:
             released=True       
     t0=core.getTime()
     while core.getTime()-t0<1:
         elem.draw()
         self.wind.flip()
     self.mouse.setVisible(0)
     if (selected[0]==0 and selected[1]==1
         or selected[0]==1 and selected[1]==0):
         return 1
     else: return 0
 def draw(self, debug_mode=False): 
     mouse_x, mouse_y = self.mouse.getPos()
     for text_stim in self.contrib_choices:
         if xydist((mouse_x, mouse_y), text_stim.pos) < self.mouseover_threshold:
             text_stim.color = 'darkorange'
             if self.mouse.getPressed()[0]:
                 self.contrib_choice = text_stim.text
                 self.contrib_instructions.setText(self.instr_text_preformat.format(self.contrib_choice))
                 self.continue_button.clickable = True
         else:
             text_stim.color = 'white'
         text_stim.draw()
     self.continue_button.draw()
     self.contrib_instructions.draw()
     if self.gaze_pos_getter is not None:
         self.gaze.pos = self.coords(self.gaze_pos_getter())
         self.gaze.draw()
예제 #5
0
 def test_xydist(self):
     assert event.xydist([0,0], [1,1]) == np.sqrt(2)
예제 #6
0
 def test_misc(self):
     assert event.xydist([0, 0], [1, 1]) == sqrt(2)
예제 #7
0
 def test_misc(self):
     assert event.xydist([0,0], [1,1]) == sqrt(2)
예제 #8
0
def generateTrial(nragents,maze,rejectionDistance=0.0,STATISTICS=False):
    ''' generates the agent trajectories for a single trial
        the generation may take considerably longer when rejectionDistance>0
        nragents - number of agents to generate
        maze - Maze class instance (see Maze.py)
        rejectionDistance - chaser-chasee minimum distance in degrees
        STATISTICS - if True will log stats for the Diagnosis class
        
        returns ndarray of size (nrframes x nragents x 3)
            first dim - number of frames is derived based on trial duration
                and frame rate (both in Settings.py)
            second dim - the first agents is chasee,
                         the second agents is chaser,
                         the rest are distractors
            third dim - X position in degrees, Y position in degrees,
                direction in radians  
        if STATISTICS is True returns statistics
        
    '''
    if STATISTICS: nrbacktracks=0
    # init chaser chasee
    chasee=RandomAgent(Q.nrframes,maze.dispSize,maze.pos,
            Q.pDirChange[CHASEE],Q.aSpeed,Q.phiRange[0])
    chaser=HeatSeekingChaser(Q.nrframes,maze.dispSize,maze.pos,
            Q.pDirChange[CHASER],Q.aSpeed,Q.phiRange[CHASER],True)
    while (xydist(chaser.getPosition(),chasee.getPosition())<Q.initDistCC[MIN]
        and xydist(chaser.getPosition(),chasee.getPosition())>Q.initDistCC[MAX]):
        # resample until valid distance between chaser and chasee is obtained
        chasee.reset(); chaser.reset()
    agents=[chasee,chaser]
    # init distractors
    for d in range(nragents-2):
        distractor=RandomAgent(Q.nrframes,maze.dispSize,maze.pos,
            Q.pDirChange[DISTRACTOR],Q.aSpeed,Q.phiRange[CHASEE])
        agents.append(distractor)
    # check for wall collisions
    for a in range(nragents):
        d,edge=maze.shortestDistanceFromWall(agents[a].getPosition())
        while d<=Q.agentRadius:
            agents[a].reset()
            d,edge=maze.shortestDistanceFromWall(agents[a].getPosition())
    # generate the movement of chasee and chaser
    finished=False
    while not finished:
        # check the distance
        (dx,dy)=chasee.getPosition() - chaser.getPosition()
        if np.sqrt(dx**2+dy**2)<rejectionDistance:
            if STATISTICS: nrbacktracks+=1
            deadend=chaser.backtrack()
            chasee.backtrack()
            if deadend: # reset the algorithm 
                print 'dead end', chasee.f
                if STATISTICS: return None, None, None, None,None
                else: return None
            (dx,dy)=chasee.getPosition() - chaser.getPosition()
        # move chaser and avoid walls
        chaser.move((dx,dy))
        d,edge=maze.shortestDistanceFromWall(chaser.getPosition())
        if d<=Q.agentRadius:
            newD=maze.bounceOff(chaser.getPosition(),
                chaser.getPosition(-1),edge,Q.agentRadius)
            chaser.crashed(newD=newD,targetPos=(dx,dy))
        # move chasee and avoid walls
        finished=chasee.move()
        d,edge=maze.shortestDistanceFromWall(chasee.getPosition())
        if d<=Q.agentRadius:
            newD=maze.bounceOff(chasee.getPosition(),
                chasee.getPosition(-1),edge,Q.agentRadius)
            chasee.crashed(newD)
        #if chaser.f>401:
        #    raise NameError('stop')
    # generate distractor movement
    finished=False
    while not finished and nragents>2:
        for a in range(2,nragents):
            finished=agents[a].move()
            d,edge=maze.shortestDistanceFromWall(agents[a].getPosition())
            if d<=Q.agentRadius:
                newD=maze.bounceOff(agents[a].getPosition(),
                    agents[a].getPosition(-1),edge,Q.agentRadius)
                agents[a].crashed(newD)
    trajectories=np.zeros((Q.nrframes,nragents,3))
    for a in range(nragents):
        tt=agents[a].getTrajectory()
        trajectories[:,a,X]=tt[:,X]
        trajectories[:,a,Y]=tt[:,Y]
        trajectories[:,a,PHI]=tt[:,PHI]
    if STATISTICS:
        #statistics=np.zeros((nrframes,nragents,3))
        statistics=[trajectories,np.zeros((Q.nrframes,3)),
                    np.zeros((3)),nrbacktracks,[chasee.ndc.sum(),chaser.ndc.sum(),agents[2].ndc.sum()]]
        for a in range(3):
            statistics[1][:,a]=agents[a].getTrajectory()[:,PHI]
            statistics[2][a]=agents[a].nrcrashes.sum()
        return statistics
    else: return trajectories
예제 #9
0
def inStim(pointer, target):
    pos1 = pointer.getPos()
    pos2 = target.pos
    return (event.xydist(pos1, pos2) < 0.05)