Hi
This post will hopefully explain my subroutine in my previous post for those that are interested. If you're not interested or don't care then I suggest you stop reading now!
It's hard to explain my procedure without diagrams, etc, so I hope you can understand what I'm trying to explain.
I realised that it was not very hard to write a routine to draw a triangle that had a horizontal top or bottom. My subroutine _DrawHalfTriangle does this.
Take a triangle with coordinates (A,B), (C,D), and (E,D). Note that using 'D' twice is not a mistake - (C,D) and (E,D) form the horizontal side and their y-coordinate is therefore the same.
All you have to do is the following:
1. count the number of pixels from the horizontal side to the opposite corner (in other words, the height of the triangle in pixels). In my procedure this height is stored in 'Z'. Therefore:
Z = ABS(B-D)
2. work out the x-coordinate at each value of Z from each corner of the horizontal side to the opposite corner. We want to do a loop from 0 to Z and we want to draw a horizontal line at each step. We therefore need to calculate the coordinates of the horizontal line at each step. The y-coordinate is easy - it's the step value between 0 and Z. We need to calculate the x-coordinates of each end of the line. To do this we simply take the difference of the x-coordinates [(C-A) and (E-A)] and divide by Z. These values are stored in 'X' and 'Y' in my subroutine. We then multiply this value by the step value between 0 and Z and add it back to the starting coordinate (C or E).
3. draw a horizontal line at each value of Z using the calculated x-coordinates. In my procedure 'I' and 'J' are used to store the new value and the line is drawn.
And that's it.
Now, that's very good for a triangle with a horizontal side, but not all triangles have horizontal sides. However, having said that, all triangles can be divided into two triangles, each one having a horizontal side at which point they join together to form the complete triangle.
If you think about it, take any triangle (that doesn't have a horizontal side) and draw a horizontal line through the middle point (the corner that is neither the highest corner nor the lowest corner). This horizontal line you have drawn will have divided your triangle into two triangles, each with a horizontal top or bottom where they join each other.
So, all we have to do is calculate that horizontal line and then draw both triangles using the above procedure.
This is what my procedure _DrawFilledTriangle does before calling _DrawHalfTriangle twice.
The first thing the procedure does is sort the coordinates out so that (A,B) is the lowest corner, (C,D) is the middle corner, and (E,F) is the highest corner.
The dividing horizontal line therefore cuts through (C,D), and (C,D) would be one of the coordinates of the flat side. We have to calculate the coordinate where the horizontal line cuts through the opposite side of the triangle. In my procedure this is stored in variable 'G'.
We then have two triangles with coordinates as follows:
(A,B), (C,D), (G,D)
(E,F), (C,D), (G,D)
In my subroutine, variables I and J are used to store the opposite corner [(A,B) and then (E,F)] so that the same procedure can be used for both triangles.
Finally I draw the outline to finish it off. This is important as triangles with sharp, pointy corners will not be drawn correctly without drawing the outline.
Note that my _DrawHalfTriangle subroutine has protection so that if you actually want to draw a triangle with a horizontal side which therefore has no top (or bottom) triangle it will exit and do nothing when called.
I've noticed an issue with my procedure. If you draw the outline of the triangle in a different colour to the fill you may notice that my fill does not fit in exactly. There are some sides where the fill seems to stick out beyond the line slightly (by one pixel). This is due to the routine for drawing lines using a different algorithm to the one I have used and it would be difficult for me to get it exactly right, but it's currently fairly accurate.
And that's pretty much it. I hope it made sense.
If anyone wants to improve on it or convert it into an applet that can be called then please be my guest. As I said previously, drawing triangles is very important when dealing with graphics, so I would welcome this.