Computer Science Canada

help - fillTriangle

Author:  whoareyou [ Wed Apr 27, 2011 2:50 pm ]
Post subject:  help - fillTriangle

We are learning to create methods in java in computer science at the moment. One of the questions is to create a method that will draw a triangle and create another method that draws and fills a triangle. It's sort of like using the c.drawRect and c.fillRect (btw, I'm using the HSA console). What I have so far is a method that will take 3 coordinates and draw a triangle. I am completely stuck on how to draw the triangle and fill it.

I've searched google, but they talk about arrays and using a polygon method. However, we haven't learned those yet, so I guess those are out of bounds.

Java:

    public static void drawTriangle (int x1, int y1, int x2, int y2, int x3, int y3)
    {

        c.drawLine (x1, y1, x2, y2);
        c.drawLine (x2, y2, x3, y3);
        c.drawLine (x3, y3, x1, y1);

    }

Author:  apython1992 [ Wed Apr 27, 2011 3:42 pm ]
Post subject:  RE:help - fillTriangle

I don't know Java, but if there's nothing built-in that can tell you whether or not a pixel is inside something you drew (I would suspect that this is the case), then my first thought is to use a ray-casting algorithm. http://en.wikipedia.org/wiki/Point_in_polygon

Author:  Insectoid [ Wed Apr 27, 2011 4:09 pm ]
Post subject:  RE:help - fillTriangle

Assuming RTP has a whatdotcolor function (or access to the robot class) you can find the centre of the triangle (or any point inside it, really), draw that color, and then expand outwards, drawing the pixels around that first pixel, then around those. Just don't draw on top of or past pixels that are already the right color (as these would be the border of the triangle, or pixels you've already drawn on). This may be very slow though.

Alternatively, you can use one of the lines of the triangle as a guide; Move across each pixel of that line, calculate another line perpendicular to that line, and its point of intersection with either of the other two lines (it will only intersect with one other line, except at one point). Since you have two points, you can just draw a line between them inside the triangle.

Alternatively alternatively, you can do a combination of the two; move across each pixel in one of the lines, and draw pixels straight perpendicular to it (you'll have to make sure you're drawing into the triangle) until you hit the other side (by reaching a pixel of the target color). This may do some odd things in case there are already pixels of the target color inside the triangle.

Author:  chrisbrown [ Wed Apr 27, 2011 4:25 pm ]
Post subject:  Re: help - fillTriangle

whoareyou @ Wed Apr 27, 2011 2:50 pm wrote:
arrays and using a polygon method

I'd ask your teacher and probably look into these again. A arbitrary triangle drawing algorithm is (or should be) beyond the scope of an introductory Java course.

Author:  RandomLetters [ Wed Apr 27, 2011 9:30 pm ]
Post subject:  RE:help - fillTriangle

with the Graphics class in applets, you could use the fillPolygon() method:

http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Graphics.html#fillPolygon(int[], int[], int)

All it is is providing an array of coordinates, which should be part of the course. Since it's just one triangle, you don't even need to worry about the order of the coordinates.

Author:  whoareyou [ Thu Apr 28, 2011 2:14 pm ]
Post subject:  RE:help - fillTriangle

My teacher did it in class today, however, he didn't necessarily fill the ENTIRE triangle. He said that he calculated the slope of one side of the triangle, and then took on point and drew a line to each point on the side. :S

Author:  whoareyou [ Thu Apr 28, 2011 3:42 pm ]
Post subject:  Re: help - fillTriangle

Currently, my main method looks like this:

Java:

public static void main (String[] args)
    {
        c = new Console ();

        int x1, x2, x3, y1, y2, y3;


        x1 = 5; //(int) Math.ceil (Math.random () * c.maxx ());
        x2 = 500; //(int) Math.ceil (Math.random () * c.maxx ());
        x3 = 300; //(int) Math.ceil (Math.random () * c.maxx ());

        y1 = 10; //(int) Math.ceil (Math.random () * c.maxy ());
        y2 = 200; //(int) Math.ceil (Math.random () * c.maxy ());
        y3 = 450; //(int) Math.ceil (Math.random () * c.maxy ());

        fillTriangle (x1, y1, x2, y2, x3, y3);

        c.drawString ("x1, y1", x1, y1);
        c.drawString ("x2, y2", x2, y2);
        c.drawString ("x3, y3", x3, y3);

    } // main method


My current method for filling the triangle looks like this:

Java:

public static void fillTriangle (int x1, int y1, int x2, int y2, int x3, int y3)
    {

        c.drawLine (x1, y1, x2, y2);
        c.drawLine (x2, y2, x3, y3);
        c.drawLine (x3, y3, x1, y1);

        double slopex = x3 - x2;
        double slopey = y3 - y2;
        double slope = slopey / slopex;

        System.out.println (slope); //I put this here so i could see what the slope was ...

        for (int i = y3 ; i >= y2 ; i += slope)
        {

            x2++;

            c.drawLine (x1, y1, x2, i);

        }


My problem is that when I output it, it looks like this:

Posted Image, might have been reduced in size. Click Image to view fullscreen.

I tried subtracting the slope, subtracting the x-coordinate, but it doesn't work Sad. Does anyone know what I'm doing wrong?

Author:  DemonWasp [ Thu Apr 28, 2011 3:58 pm ]
Post subject:  RE:help - fillTriangle

Well, the first line it draws goes from (x1,y1) to (x2, y3). The reason it does this is because you decided to start i at y3, but then use x2 as the starting x coordinate. If you use x3 instead, it will be closer to what you want.

The second thing to fix is that your for-loop continuation condition ( i >= y2 ) isn't right.

The next thing to fix is that you're adding a double to an int over and over again in that for loop and doing that will lead to inaccuracy. Consider replacing that int with a double and using Math.round(), otherwise your slope calculation will be wrong.


You may want to consider reading up on http://en.wikipedia.org/wiki/Bresenham's_line_algorithm , which is what you've sort-of-almost implemented above. However, even if you implement this perfectly, it won't really do what you want it to do: you will still see "holes" in your triangle. Far better to implement this using the standard Java drawing APIs than hacking together your own version.

Author:  whoareyou [ Thu Apr 28, 2011 5:50 pm ]
Post subject:  RE:help - fillTriangle

1) I replaced the x2 with x3 and now it aligns at (x2, y2) =]

2) Why isn't that right?

3) I noticed that there was something wrong with the slope! Should I be fixing the int-double problem when calculating the slope, or in the for-loop?

ps. the triangle now goes straight down! :O
Posted Image, might have been reduced in size. Click Image to view fullscreen.

Author:  whoareyou [ Thu Apr 28, 2011 7:07 pm ]
Post subject:  RE:help - fillTriangle

OK I got the fill working for this specified triangle, but if I change the x and y coordinates by doing a Math.ciel (Math.Round ()*c.maxx) some of the triangles don't fill.

Author:  DemonWasp [ Thu Apr 28, 2011 9:56 pm ]
Post subject:  RE:help - fillTriangle

Go look at Bresenhem's line algorithm (I linked it). What you're doing here is drawing lines from one corner to each pixel on the opposite side, and to do that you need to determine which pixels are in the opposite side. That's what Bresenhem's algorithm gives you, regardless of the location of the vertices.


: