I want an efficient algorithm to fill polygon with an Image, I want to fill an Image into Trapezoid. currently I am doing it in two steps
1) First Perform StretchBlt on Image,
2) Perform Column by Column vertical StretchBlt,
Is there any better method to implement this? Is there any Generic and Fast algorithm which can fill any polygon?
Thanks,
Sunny
I can’t help you with the distortion part, but filling polygons is pretty simple, especially if they are convex.
For each Y scan line have a table indexed by Y, containing a minX and maxX.
For each edge, run a DDA line-drawing algorithm, and use it to fill in the table entries.
For each Y line, now you have a minX and maxX, so you can just fill that segment of the scan line.
The hard part is a mental trick – do not think of coordinates as specifying pixels. Think of coordinates as lying between the pixels. In other words, if you have a rectangle going from point 0,0 to point 2,2, it should light up 4 pixels, not 9. Most problems with polygon-filling revolve around this issue.
ADDED: OK, it sounds like what you’re really asking is how to stretch the image to a non-rectangular shape (but trapezoidal). I would do it in terms of parameters
sandt, going from0to1. In other words, a location in the original rectangle is(x + w0*s, y + h0*t). Then define a function such thatsandtalso map to positions in the trapezoid, such as((x+t*a) + w0*s*(t-1) + w1*s*t, y + h1*t). This defines a coordinate mapping between the two shapes. Then just scanxandy, converting tosandt, and mapping points from one to the other. You probably want to have a little smoothing filter rather than a direct copy.ADDED to try to give a better explanation:
I’m supposing both your rectangle and trapezoid have top and bottom edges parallel with the X axis. The lower-left corner of the rectangle is
<x0,y0>, and the lower-left corner of the trapezoid is<x1,y1>. I assume the rectangle’s width and height are<w,h>.For the trapezoid, I assume it has height
h1, and that it’s lower width isw0, while it’s upper width isw1. I assume it’s left edge “slants” by a distancea, so that the position of its upper-left corner is<x1+a, y1+h1>. Now suppose you iterate<x,y>over the rectangle. At each point, computes = (x-x0)/w, andt = (y-y0)/h, which are both in the range0to1. (I’ll let you figure out how to do that without using floating point.) Then convert that to a coordinate in the trapezoid, asxt = ((x1 + t*a) + s*(w0*(1-t) + w1*t)), andyt = y1 + h1*t. Then<xt,yt>is the point in the trapezoid corresponding to<x,y>in the rectangle. Now I’ll let you figure out how to do the copying 🙂 Good luck.P.S. And please don’t forget – coordinates fall between pixels, not on them.