 We've already demonstrated how we can use nearest neighbor or bilinear filtering to resize an image, but what if we want to rotate an image? Well, say we render this image of the Mona Lisa scaled down by a factor of 0.7, rotated 135 degrees, and moved such that its bottom left corner is at coordinate 850. For this purpose, we'll assume a simple pixel grid in which our source image starts out with its bottom left corner at the origin, and in which each pixel is centered at half coordinates, e.g. this tan pixel here is centered at 12.57.5. The most obvious way to affect this transformation is to individually scale, rotate, and translate, in that order, each pixel of the source image. So say the source pixel centered at 78.5, 199.5. First it's x and y, both get multiplied by 0.7. Then using the rotation formula we derived in a previous video, we rotate the coordinate by 135 degrees, and lastly, whatever results from the rotation we add 800 to its x and 350 to its y to translate it. Do this for every pixel and we have our transformed image. Using this process, we should be able to render any image in any 2D orientation. A better approach, however, is to reverse the process. Instead of determining the corresponding location in the destination for each pixel center in the source, we should determine the corresponding location in the source for each pixel center in the destination. Here for example, we should find the corresponding location in the source for the pixel 683.5281.5 in the destination. Using this reverse process not only ensures that every destination pixel gets filled in, it allows us to use nearest neighbor or bilinear filtering, just like when we resized images. The first step is to find the bounds of our destination image by simply transforming the four corners of our source image. Then to find the pixels that lie inside the destination rectangle, the simplest solution is to split the rectangle into two triangles, and then scan the two triangles using the same method we saw in an earlier video. In scanning the triangles, we get the coordinates for each destination pixel, from each of which we can find the corresponding source pixel by reversing the transformation. First the reverse translation, then the reverse rotation, and lastly the reverse scaling. Once we have the source coordinate that corresponds to a pixel center in the destination, we can get the color value for that pixel using nearest neighbor or bilinear filtering. While we now have a workable solution that produces good quality results, the sticking point is that this process is rather slow because for each pixel, we're doing a translation, rotation, and scaling operation. To simplify the amount of work done per pixel and thus speed up the job, we can use interpolation. First, consider how interpolation works along a straight line. To compute the coordinate that lies 35% along the way from 0.1030 to 0.6050, we don't have to find the equation of the line. Instead, we can independently find 35% of the horizontal distance and 35% of the vertical distance. So if 10 is x1 and 60 is x2, we find x to the new chord by the formula x equals x2 minus x1 times alpha plus x1, where alpha is the interpolation factor 0.35, the percentage of the distance from x1 to x2. In other words, we find the distance between 10 and 60, find 35% of that distance, and add 10. To find the y value, the formula will be just the same, but with y's instead of x's. A problem with this formula though is that it only works when x2 is greater than x1 and when the interpolation is expressed as the percentage of distance from x1 to x2, not from x2 to x1. So when using this formula in code, we may have to first determine whichever points has the greater x value, and then we may have to flip the alpha value by subtracting it from 1, e.g. 0.2 would become 0.8. Generally, a better formula then is the one we used in a previous video when composing colors with alpha transparency values. The way to think of it in this approach is that we're averaging the two x values, but the contributions from both are not equal. Here, x1 contributes 65% to the final value, while x2 contributes 35%. Generalized, the formula is x equals x1 times 1 minus alpha plus x2 times alpha. Note though that when the interpolation value is instead expressed as the distance from x2 to x1, then the formula is x equals x1 times alpha plus x2 times 1 minus alpha. One use of interpolation is to find the other half of a coordinate along a line. Here we want to find the y value along this line that goes with the x value of 40. To do so, we simply need to determine the alpha value, the interpolation value of 40 along the x-axis, then use that alpha value to find y. To determine alpha, we simply find the ratio of the distance between x and x1 and the distance between x2 and x1. The distance is the absolute difference between two values, but because the signs of the two subtractions will always match, the division will cancel out the negative signs, so we can drop the absolute value operators. Also, while it doesn't matter in this formula which x value is greater, it does of course still matter which point we're interpolating from. To find the interpolation value that starts from x2, we would have to swap the formulas x2 and x1 values. Anyway, once we've found the alpha value, we can use it to find y. Another important use of interpolation is to find corresponding points on separate lines. Here, if we take it that the endpoint 2055 of the line on the left corresponds to the endpoint 5030 of the line on the right and the endpoint 4080 of the line on the left corresponds to the endpoint 115 of the line on the right, then the point which lies 75% of the way from 2055 along the line on the left corresponds to the point which lies 75% of the way from 5030 along the line on the right. In fact, any point which lies n% along one line should correspond to the point which lies n% along the other. Just be clear that it matters which endpoint corresponds to which endpoint. If here 2055 corresponds to 115 of the other line, then our interpolation values run in the other direction along that line. Once we can use interpolation to find corresponding points on lines, we can also find corresponding points along the edges of two triangles. Here the letters denote the corresponding vertices of the two triangles, and so for example the point which lies 50% of the way from A to B on the left triangle corresponds to the point which lies 50% of the way from A to B on the right triangle. The interesting question though is how we can use interpolation to find corresponding points inside two triangles. Given this point inside the right triangle, how can we find the corresponding point inside the left triangle? Well, let's first consider a special case, a triangle with an edge that runs horizontal. If we double the height of the triangle, what happens to points along the edges and points in the interior? Demonstrated visually, you can see that a line that runs horizontal through the middle of the triangle still runs through the middle after we stretch the triangle. In fact, the orange line retains the same width and so every point on the line retains the same x-coordinate. The point in the middle of the line, for example, remains the midpoint after the stretch. So by linear interpolation, these points in the two triangles correspond to one another. Similarly, if we take the same starting triangle but instead skew it by moving the top coordinate to the side, the orange line no longer maintains the same width, but its y-coordinate remains unchanged. Its endpoints still sit 50% along the side edges and its midpoint remains the midpoint. So again, by linear interpolation, these points in the two triangles correspond to one another. If you're not quite convinced, observe that in both triangles, these points are intersected by the line running from the top vertex to the midpoint of the bottom edge. Now, what if we draw the orange line to run between endpoints at 80% along AB and 30% along CA? Well, most of the same statements still apply, including the fact that the point interpolated 50% along this line corresponds to the point interpolated 50% along the corresponding line in the other triangle. And again, in both triangles, the line that runs from the top vertex to this point hits the bottom edge at the same interpolation point along the bottom edge. So we've informally demonstrated that these two interior points of the triangles correspond to one another. We can likewise observe the same thing when we skew the triangle, a point interpolated along a line running between points interpolated along the edges, that point corresponds to the point interpolated by the same value along a line running between points interpolated along the edges. So these two points correspond. Finally, what if we move the A vertex to both stretch and skew the triangle? Well, again, even without any formal proof, we can see that when the lines run between equivalent interpolation points along the triangle edges, then the equivalent interpolation points along the lines correspond. So returning to our general case of triangles of any orientations, we should realize that first, every edge of every triangle runs horizontal in the right frame of reference, and second, any triangle can be transformed into the shape of any other by moving around one of the points, which is just what we did when stretching and skewing. So the problem of finding corresponding points between any two triangles is really the same as finding corresponding points between two triangles with a common horizontal edge. Therefore, we can use the same interpolation technique. To find the point in the triangle on the left, which corresponds to this point in the triangle on the right, we first find a line, any line, that runs through the point and determine where it intersects two of the edges. With the interpolation values along those edges, we can find the corresponding line in the other triangle. So here, the line that runs between the point 25% along the edge from A to B, and the point 55% along the edge from C to B, we then determine where our interior point lies along our line, and use this to find the corresponding point in the other triangle. So here, the point lies 80% along the length of the orange line in the triangle on the right, so the corresponding point lies 80% along the length of the triangle on the left. And we have our answer. Here is the point in the triangle on the left, which corresponds with the point in the triangle on the right. Now that we can use interpolation to map any point inside a triangle to a corresponding point in any other triangle, we can proportionally draw any triangular section of an image in any other triangle. Here, for example, we could draw the source image bound by this triangle on the left to the corresponding triangle on the right. To do so, we simply map each pixel center in the destination to a coordinate within the source, and use nearest neighbor or bilinear filtering to get a color value. So for example, in the destination, the pixel with its center at 44.5, 120.5, maps to a corresponding point in the triangle bound section of the source image, and from that point, we derive a color value for that pixel. To do this for each pixel in the destination triangle easily and efficiently, it makes sense to use horizontal interpolation lines because they're easier to compute, and they can be reused for every pixel in the same row. We could just as well use vertical lines for the same advantages, but horizontal lines are the usual choice. Just be clear that the corresponding lines in the source likely don't run horizontal or vertical. Here, for example, this corresponding line runs at a slope. Finally, we can return to our original problem, rotating an image efficiently with interpolation. Now that we can render the pixels from one triangle into the bounds of any other, no matter its shape, size, or orientation, we can rotate a rectangular image by, first, splitting into two triangles and finding the triangle coordinates of both the source and destination triangles. Second, scanning the two destination triangles to find the horizontal lines of pixels. Third, for each of these lines, finding the corresponding line in the respective source triangle. Fourth, for each destination pixel, interpolate along the corresponding lines to find the corresponding coordinate in the source. And fifth, using this corresponding point to determine a color value for the pixel with nearest neighbor or bilinear filtering. Not only can we now rotate and smoosh the pixel contents of one triangle into any other, we'll later use this interpolation technique as the starting point for 3D texture mapping.