- for x in range(int(cmax)):
- vectors = [linedist(a,b,c,d,x,y) for ((a,b),(c,d)) in segments]
- dists = [memoisedsqrt(vx*vx+vy*vy) for (vx,vy) in vectors]
-
- # If the distance to the hole line is less than
- # holeradius, we're not part of the spanner.
- if dists[0] < holeradius:
- continue
- # If the distance to the head `line' is less than
- # headradius, we are part of the spanner; likewise if
- # the distance to the shaft line is less than
- # shaftwidth _and_ the resulting shaft point isn't
- # beyond the shaft end.
- if dists[1] > headradius and \
- (dists[2] > shaftwidth or x+vectors[2][0] >= shaftend):
- continue
-
- # We're part of the spanner. Now compute the highlight
- # on this pixel. We do this by computing a `slope
- # vector', which points from this pixel in the
- # direction of its nearest edge. We store an array of
- # slope vectors, in polar coordinates.
- angles = [math.atan2(vy,vx) for (vx,vy) in vectors]
- slopes = []
- if dists[0] < holeradius + holehighlight:
- slopes.append(((dists[0]-holeradius)/holehighlight,angles[0]))
- if dists[1]/headradius < dists[2]/shaftwidth:
- if dists[1] > headradius - headhighlight and dists[1] < headradius:
- slopes.append(((headradius-dists[1])/headhighlight,math.pi+angles[1]))
- else:
- if dists[2] > shaftwidth - shafthighlight and dists[2] < shaftwidth:
- slopes.append(((shaftwidth-dists[2])/shafthighlight,math.pi+angles[2]))
- # Now we find the smallest distance in that array, if
- # any, and that gives us a notional position on a
- # sphere which we can use to compute the final
- # highlight level.
- bestdist = None
- bestangle = 0
- for dist, angle in slopes:
- if bestdist == None or bestdist > dist:
- bestdist = dist
- bestangle = angle
- if bestdist == None:
- bestdist = 1.0
- sx = (1.0-bestdist) * math.cos(bestangle)
- sy = (1.0-bestdist) * math.sin(bestangle)
- sz = math.sqrt(1.0 - sx*sx - sy*sy)
- shade = sx-sy+sz / math.sqrt(3) # can range from -1 to +1
- shade = 1.0 - (1-shade)/3
-
- pixel(x, y, yellowpix(shade), canvas)
+ for x in range(int(cmax)):
+ vectors = [linedist(a,b,c,d,x,y) for ((a,b),(c,d)) in segments]
+ dists = [memoisedsqrt(vx*vx+vy*vy) for (vx,vy) in vectors]
+
+ # If the distance to the hole line is less than
+ # holeradius, we're not part of the spanner.
+ if dists[0] < holeradius:
+ continue
+ # If the distance to the head `line' is less than
+ # headradius, we are part of the spanner; likewise if
+ # the distance to the shaft line is less than
+ # shaftwidth _and_ the resulting shaft point isn't
+ # beyond the shaft end.
+ if dists[1] > headradius and \
+ (dists[2] > shaftwidth or x+vectors[2][0] >= shaftend):
+ continue
+
+ # We're part of the spanner. Now compute the highlight
+ # on this pixel. We do this by computing a `slope
+ # vector', which points from this pixel in the
+ # direction of its nearest edge. We store an array of
+ # slope vectors, in polar coordinates.
+ angles = [math.atan2(vy,vx) for (vx,vy) in vectors]
+ slopes = []
+ if dists[0] < holeradius + holehighlight:
+ slopes.append(((dists[0]-holeradius)/holehighlight,angles[0]))
+ if dists[1]/headradius < dists[2]/shaftwidth:
+ if dists[1] > headradius - headhighlight and dists[1] < headradius:
+ slopes.append(((headradius-dists[1])/headhighlight,math.pi+angles[1]))
+ else:
+ if dists[2] > shaftwidth - shafthighlight and dists[2] < shaftwidth:
+ slopes.append(((shaftwidth-dists[2])/shafthighlight,math.pi+angles[2]))
+ # Now we find the smallest distance in that array, if
+ # any, and that gives us a notional position on a
+ # sphere which we can use to compute the final
+ # highlight level.
+ bestdist = None
+ bestangle = 0
+ for dist, angle in slopes:
+ if bestdist == None or bestdist > dist:
+ bestdist = dist
+ bestangle = angle
+ if bestdist == None:
+ bestdist = 1.0
+ sx = (1.0-bestdist) * math.cos(bestangle)
+ sy = (1.0-bestdist) * math.sin(bestangle)
+ sz = math.sqrt(1.0 - sx*sx - sy*sy)
+ shade = sx-sy+sz / math.sqrt(3) # can range from -1 to +1
+ shade = 1.0 - (1-shade)/3
+
+ pixel(x, y, yellowpix(shade), canvas)