Skip to content

Commit

Permalink
moved fast star codepath to fast_star, star works as originally designed
Browse files Browse the repository at this point in the history
  • Loading branch information
jsundram committed May 6, 2013
1 parent de142da commit 87e66f5
Showing 1 changed file with 51 additions and 47 deletions.
98 changes: 51 additions & 47 deletions nodebox/graphics/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ def rect(x, y, width, height, **kwargs):
glVertex2f(x+width, y+height)
glVertex2f(x, y+height)
glEnd()

def triangle(x1, y1, x2, y2, x3, y3, **kwargs):
""" Draws the triangle created by connecting the three given points.
The current stroke, strokewidth and fill color are applied.
Expand Down Expand Up @@ -685,57 +685,61 @@ def gcd(a, b):
return gcd(b, a % b) if b else a

_stars = {} #TODO: LRU?
def fast_star(x, y, points=20, outer=100, inner=50, **kwargs):
""" Draws a star with the given points, outer radius and inner radius.
The current stroke, strokewidth and fill color are applied.
"""
scale = gcd(inner, outer)
iscale = inner / scale
oscale = outer / scale
cached = _stars.get((points, iscale, oscale), [])
if not cached:
radii = [oscale, iscale] * int(points+1); radii.pop() # which radius?
f = pi / points
v = [(r*sin(i*f), r*cos(i*f)) for i, r in enumerate(radii)]
cached.append(precompile(lambda:(
glBegin(GL_TRIANGLE_FAN),
glVertex2f(0, 0),
[glVertex2f(vx, vy) for (vx, vy) in v],
glEnd()
)))
cached.append(precompile(lambda:(
glBegin(GL_LINE_LOOP),
[glVertex2f(vx, vy) for (vx, vy) in v],
glEnd()
)))
_stars[(points, iscale, oscale)] = cached

fill, stroke, strokewidth, strokestyle = color_mixin(**kwargs)
for i, clr in enumerate((fill, stroke)):
if clr is not None and (i == 0 or strokewidth > 0):
if i == 1:
glLineWidth(strokewidth)
if strokestyle != _strokestyle:
glLineDash(strokestyle)
glColor4f(clr[0], clr[1], clr[2], clr[3] * _alpha)
glPushMatrix()
glTranslatef(x, y, 0)
glScalef(scale, scale, 1)
glCallList(cached[i])
glPopMatrix()

def star(x, y, points=20, outer=100, inner=50, **kwargs):
""" Draws a star with the given points, outer radius and inner radius.
The current stroke, strokewidth and fill color are applied.
This is about 20x slower than fast_star; use it only if you need the path returned.
"""
if kwargs.get("draw", True):
scale = gcd(inner, outer)
iscale = inner / scale
oscale = outer / scale
cached = _stars.get((points, iscale, oscale), [])
if not cached:
radii = [oscale, iscale] * int(points+1); radii.pop() # which radius?
f = pi / points
v = [(r*sin(i*f), r*cos(i*f)) for i, r in enumerate(radii)]
cached.append(precompile(lambda:(
glBegin(GL_TRIANGLE_FAN),
glVertex2f(0, 0),
[glVertex2f(vx, vy) for (vx, vy) in v],
glEnd()
)))
cached.append(precompile(lambda:(
glBegin(GL_LINE_LOOP),
[glVertex2f(vx, vy) for (vx, vy) in v],
glEnd()
)))
_stars[(points, iscale, oscale)] = cached
p = BezierPath(**kwargs)
p.moveto(x, y+outer)
for i in range(0, int(2*points)+1):
r = (outer, inner)[i%2]
a = pi*i/points
p.lineto(x+r*sin(a), y+r*cos(a))
p.closepath()

fill, stroke, strokewidth, strokestyle = color_mixin(**kwargs)
for i, clr in enumerate((fill, stroke)):
if clr is not None and (i == 0 or strokewidth > 0):
if i == 1:
glLineWidth(strokewidth)
if strokestyle != _strokestyle:
glLineDash(strokestyle)
glColor4f(clr[0], clr[1], clr[2], clr[3] * _alpha)
glPushMatrix()
glTranslatef(x, y, 0)
glScalef(scale, scale, 1)
glCallList(cached[i])
glPopMatrix()
else:
# For whatever reason, the original api specified that you
# can get the path to the star. This is about 30x slower,
# but I'm keeping it here for backwards compatibility.
p = BezierPath(**kwargs)
p.moveto(x, y+outer)
for i in range(0, int(2*points)+1):
r = (outer, inner)[i%2]
a = pi*i/points
p.lineto(x+r*sin(a), y+r*cos(a))
p.closepath()
return p
if kwargs.get("draw", True):
p.draw(**kwargs)
return p

#=====================================================================================================

Expand Down

0 comments on commit 87e66f5

Please sign in to comment.