Re: I don't expect solution... but,
- Posted by Pete Eberlein <xseal at HARBORSIDE.COM> Jun 30, 1997
- 816 views
Here's a polygon procedure I've been working with recently. It draws only four sided polygons though. It works with a single color or a tiled bitmap like my fill procedure. It breaks the polygon down into horizontal strips and scans the endpoints downward along the edges. The vertices are in a fixed-point format, so multiply pixel values by 65536. The upper and right side of the polygon is clipped so that two polygons, sharing two vertices, will not overlap when drawn. Pretty weird, huh? ---- here's the code ---- function get_slope(sequence p1, sequence p2) integer denom, dx denom = floor(((p1[2] > p2[2]) * 2 - 1) * (p1[2] - p2[2]) / 65536) + 1 dx = floor((p2[1] - p1[1]) / denom) return {p1[1] + floor(dx * and_bits(-p1[2], 65535) / 65536), dx} end function procedure poly(object tile, sequence vertices) -- draws a filled four-sided polygon -- tile may be an atom for a solid color -- or a 2-d sequence of pixels to be tiled -- vertices is a length-4 sequence of length-2 sequences -- of fixed point coordinates -- floor(vertice / 65536) is the pixel position -- remainder(vertice, 65536) is the fractional pixel value integer boty, y2, y3, y4, x1, x2, temp sequence line1, line2 -- rotate vertices, so first position is highest on screen while (vertices[1][2] > vertices[4][2]) or (vertices[1][2] > vertices[3][2]) or (vertices[1][2] > vertices[2][2]) do vertices = append(vertices[2..4], vertices[1]) end while -- find the bottommost vertice boty = floor(vertices[2][2] / 65536) if floor(vertices[3][2] / 65536) > boty then boty = floor(vertices[3][2] / 65536) end if if floor(vertices[4][2] / 65536) > boty then boty = floor(vertices[4][2] / 65536) end if -- calculate starting x-positions and rates of change line1 = get_slope(vertices[1], vertices[2]) line2 = get_slope(vertices[1], vertices[4]) -- precompute critical y-values y2 = floor((vertices[2][2] + 65535) / 65536) y3 = floor((vertices[3][2] + 65535) / 65536) y4 = floor((vertices[4][2] + 65535) / 65536) for y = floor((vertices[1][2] + 65535) / 65536) to boty do -- test for a vertice if y = y2 then line1 = get_slope(vertices[2], vertices[3]) end if if y = y4 then line2 = get_slope(vertices[4], vertices[3]) end if if y = y3 then if boty = floor(vertices[2][2] / 65536) then line2 = get_slope(vertices[3], vertices[2]) else line1 = get_slope(vertices[3], vertices[4]) end if end if x1 = floor(line1[1] / 65536) x2 = floor(line2[1] / 65536) if atom(tile) then -- solid color if x1 < x2 then pixel(repeat(tile, x2-x1), {x1,y}) else pixel(repeat(tile, x1-x2), {x2,y}) end if else -- tiled bitmap if x1 > x2 then temp = x1 x1 = x2 x2 = temp end if if x1 < 0 then x1 = 0 end if for x = x1 to x2 do pixel(tile[1+remainder(y, length(tile))] [1+remainder(x, length(tile[1]))], {x,y}) end for end if line1[1] = line1[1] + line1[2] line2[1] = line2[1] + line2[2] end for end procedure function rotate(sequence s, atom a) atom sine, cosine sine = sin(a) cosine = cos(a) for i = 1 to length(s) do s[i] = s[i] * cosine + {s[i][2],-s[i][1]} * sine end for return s end function include graphics.e for a = graphics_mode(19) to 255 do poly(a, floor(65536*(repeat({a+50,100},4)+ rotate({{-50,-50},{50,-50},{50,50},{-50,50}}, a*3.14159/128)))) end for ---- code ends ---- This doesn't do the virtual paging or the number of vertices originally requested by Lee woo seob, but hopefully someone can use this to come up with a solution. Pete Eberlein <xseal at harborside.com>