[visionegg] Re: anti-aliasing of FilledCircle
- From: Andrew Straw <astraw@xxxxxxxxxxx>
- To: visionegg@xxxxxxxxxxxxx
- Date: Tue, 21 Feb 2006 23:31:28 -0800
Thanks Gijs and Peter, I've put your changes into the code repository.
Cheers!
Andrew
Gijs Plomp wrote:
> I was lucky and had some help already. We changed the FilledCircle
> code in MoreStimuli.py so that it now does anti-aliasing, just like
> Target2D. Maybe this could be incorporated a future versions?
>
> New code below, thanks entirely to Peter Jurica:
>
> class FilledCircle(VisionEgg.Core.Stimulus):
> """A circular stimulus, typically used as a fixation point.
>
> (Note, this implementation almost certainly could be made faster
> using display lists.)
>
> Parameters
> ==========
> anchor -- how position parameter is used (String)
> Default: center
> color -- color (AnyOf(Sequence3 of Real or Sequence4 of Real))
> Default: (1.0, 1.0, 1.0)
> num_triangles -- number of triangles used to draw circle (Integer)
> Default: 51
> on -- draw? (Boolean)
> Default: True
> position -- position in eye coordinates (AnyOf(Sequence2 of
> Real or Sequence3 of Real or Sequence4 of Real))
> Default: (320.0, 240.0)
> radius -- radius in eye coordinates (Real)
> Default: 2.0
> """
>
> parameters_and_defaults = VisionEgg.ParameterDefinition({
> 'on':(True,
> ve_types.Boolean,
> 'draw?'),
> 'color':((1.0,1.0,1.0),
> ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
> ve_types.Sequence4(ve_types.Real)),
> 'color'),
> 'anti_aliasing':(True,
> ve_types.Boolean),
> 'position' : ( ( 320.0, 240.0 ), # in eye coordinates
> ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
> ve_types.Sequence3(ve_types.Real),
> ve_types.Sequence4(ve_types.Real)),
> 'position in eye coordinates'),
> 'anchor' : ('center',
> ve_types.String,
> 'how position parameter is used'),
> 'radius':(2.0,
> ve_types.Real,
> 'radius in eye coordinates'),
> 'num_triangles':(51,
> ve_types.Integer,
> 'number of triangles used to draw circle'),
> })
> __slots__ = VisionEgg.Core.Stimulus.__slots__ + (
> '_gave_alpha_warning',
> )
>
> def __init__(self,**kw):
> VisionEgg.Core.Stimulus.__init__(self,**kw)
> self._gave_alpha_warning = 0
>
> def draw(self):
> p = self.parameters # shorthand
> if p.on:
> # calculate center
> center =
> VisionEgg._get_center(p.position,p.anchor,(p.radius, p.radius))
> gl.glDisable(gl.GL_DEPTH_TEST)
> gl.glDisable(gl.GL_TEXTURE_2D)
> gl.glDisable(gl.GL_BLEND)
>
> gl.glColorf(*p.color)
>
> # Build filled circle from points
> # gl.glBegin(gl.GL_POINTS)
> # radius = int(math.ceil(p.radius))
> # for i in range(-radius, radius):
> # for j in range(-radius, radius):
> # if(i * i + j * j < radius * radius):
> # gl.glVertex3f(p.position[0] + i, p.position[1]
> + j, 0.0)
> # gl.glEnd() # GL_POINTS
>
> # Build filled circle from triangles (this is typically faster
> # then the commented code above with the points)
> gl.glBegin(gl.GL_TRIANGLE_FAN)
> gl.glVertex3f(p.position[0], p.position[1], 0.0)
> angles =
> Numeric.arange(p.num_triangles)/float(p.num_triangles)*2.0*math.pi
> verts = Numeric.zeros( (p.num_triangles,2), Numeric.Float )
> verts[:,0] = p.position[0] + p.radius * Numeric.cos(angles)
> verts[:,1] = p.position[1] + p.radius * Numeric.sin(angles)
> for i in range(verts.shape[0]):
> gl.glVertex2fv(verts[i])
> gl.glVertex2fv(verts[0])
>
> gl.glEnd() # GL_TRIANGLE_FAN
> if p.anti_aliasing:
> if not self._gave_alpha_warning:
> if len(p.color) > 3 and p.color[3] != 1.0:
> logger = logging.getLogger('VisionEgg.Arrow')
> logger.warning("The parameter anti_aliasing is "
> "set to true in the Arrow "
> "stimulus class, but the color "
> "parameter specifies an alpha "
> "value other than 1.0. To "
> "acheive anti-aliasing, ensure "
> "that the alpha value for the "
> "color parameter is 1.0.")
> self._gave_alpha_warning = 1
>
> # We've already drawn a filled polygon (aliased), now
> redraw
> # the outline of the polygon (with anti-aliasing). (Using
> # GL_POLYGON_SMOOTH results in artifactual lines where
> # triangles were joined to create quad, at least on some
> OpenGL
> # implementations.)
>
> # Calculate coverage value for each pixel of outline
> # and store as alpha
> gl.glEnable(gl.GL_LINE_SMOOTH)
> # Now specify how to use the alpha value
> gl.glBlendFunc(gl.GL_SRC_ALPHA,gl.GL_ONE_MINUS_SRC_ALPHA)
> gl.glEnable(gl.GL_BLEND)
>
> # Draw a second polygon in line mode, so the edges are
> anti-aliased
> gl.glPolygonMode(gl.GL_FRONT_AND_BACK,gl.GL_LINE)
> gl.glBegin(gl.GL_TRIANGLE_FAN)
> gl.glVertex3f(p.position[0], p.position[1], 0.0)
> angles =
> Numeric.arange(p.num_triangles)/float(p.num_triangles)*2.0*math.pi
> verts = Numeric.zeros( (p.num_triangles,2), Numeric.Float )
> verts[:,0] = p.position[0] + p.radius * Numeric.cos(angles)
> verts[:,1] = p.position[1] + p.radius * Numeric.sin(angles)
> for i in range(verts.shape[0]):
> gl.glVertex2fv(verts[i])
> gl.glVertex2fv(verts[0])
> gl.glEnd() # GL_TRIANGLE_FAN
>
> # Set the polygon mode back to fill mode
> gl.glPolygonMode(gl.GL_FRONT_AND_BACK,gl.GL_FILL)
> gl.glDisable(gl.GL_LINE_SMOOTH)
>
> ======================================
> The Vision Egg mailing list
> Archives: http://www.freelists.org/archives/visionegg
> Website: http://www.visionegg.org/mailinglist.html
======================================
The Vision Egg mailing list
Archives: http://www.freelists.org/archives/visionegg
Website: http://www.visionegg.org/mailinglist.html
- References:
- [visionegg] anti-aliasing of FilledCircle
- From: Gijs Plomp
- [visionegg] Re: anti-aliasing of FilledCircle
- From: Gijs Plomp
Other related posts:
- » [visionegg] anti-aliasing of FilledCircle
- » [visionegg] Re: anti-aliasing of FilledCircle
- » [visionegg] Re: anti-aliasing of FilledCircle
- [visionegg] anti-aliasing of FilledCircle
- From: Gijs Plomp
- [visionegg] Re: anti-aliasing of FilledCircle
- From: Gijs Plomp