Вот код Python, основанный на ответе MizardX , который делает именно то, что я хотел:
#!/usr/bin/python
import math
def minY(x0, y0, x1, y1, x):
if x0 == x1:
# vertical line, y0 is lowest
return int(math.floor(y0))
m = (y1 - y0)/(x1 - x0)
if m >= 0.0:
# lowest point is at left edge of pixel column
return int(math.floor(y0 + m*(x - x0)))
else:
# lowest point is at right edge of pixel column
return int(math.floor(y0 + m*((x + 1.0) - x0)))
def maxY(x0, y0, x1, y1, x):
if x0 == x1:
# vertical line, y1 is highest
return int(math.ceil(y1))
m = (y1 - y0)/(x1 - x0)
if m >= 0.0:
# highest point is at right edge of pixel column
return int(math.ceil(y0 + m*((x + 1.0) - x0)))
else:
# highest point is at left edge of pixel column
return int(math.ceil(y0 + m*(x - x0)))
# view_bl, view_tl, view_tr, view_br are the corners of the rectangle
view_bl = (0.16511327500123524, 1.2460844930844697)
view_tl = (1.6091354363329917, 0.6492542948962687)
view_tr = (1.1615128085358943, -0.4337622756706583)
view_br = (-0.2825093527958621, 0.16306792251754265)
pixels = []
# find l,r,t,b,m1,m2
view = [ view_bl, view_tl, view_tr, view_br ]
l, m1, m2, r = sorted(view, key=lambda p: (p[0],p[1]))
b, t = sorted([m1, m2], key=lambda p: (p[1],p[0]))
lx, ly = l
rx, ry = r
bx, by = b
tx, ty = t
m1x, m1y = m1
m2x, m2y = m2
xmin = 0
ymin = 0
xmax = 10
ymax = 10
# outward-rounded integer bounds
# note that we're clamping the area of interest to (xmin,ymin)-(xmax,ymax)
lxi = max(int(math.floor(lx)), xmin)
rxi = min(int(math.ceil(rx)), xmax)
byi = max(int(math.floor(by)), ymin)
tyi = min(int(math.ceil(ty)), ymax)
x1 = lxi
x2 = rxi
for x in range(x1, x2):
xf = float(x)
if xf < m1x:
# Phase I: left to top and bottom
y1 = minY(lx, ly, bx, by, xf)
y2 = maxY(lx, ly, tx, ty, xf)
elif xf < m2x:
if m1y < m2y:
# Phase IIa: left/bottom --> top/right
y1 = minY(bx, by, rx, ry, xf)
y2 = maxY(lx, ly, tx, ty, xf)
else:
# Phase IIb: left/top --> bottom/right
y1 = minY(lx, ly, bx, by, xf)
y2 = maxY(tx, ty, rx, ry, xf)
else:
# Phase III: bottom/top --> right
y1 = minY(bx, by, rx, ry, xf)
y2 = maxY(tx, ty, rx, ry, xf)
y1 = max(y1, byi)
y2 = min(y2, tyi)
for y in range(y1, y2):
pixels.append((x,y))
print pixels
Выход:
[(0, 0), (0, 1), (1, 0)]