Thread: Making a teapot using triangles

  1. #1
    Registered User
    Join Date
    Sep 2020
    Posts
    6

    Making a teapot using triangles

    Your task is to complete the functions listed below. Together these functions provide functionality to draw filled triangles on the screen. In addition, the functions enable you to scale the size of a triangle and move (translate) a triangle to a given position on the screen.
    Each triangle is described by a triangle_t data structure. All the functions below accept a pointer to a triangle data structure as input. Each function needs to access and modify the fields of the data structure as appropriate.

    Note that triangle scale is specified as a floating-point number, while the triangle coordinates are integer variables. You will need to think about conversions between integer and floating-point numbers to make the scaling function work properly. When scaling, translation, and drawing works, embark on the code for filling the triangles.

    i managed to go this far, but still no tea pot appear on my screen, i think i am doing something wrong can you help me please , i think there is something to with triangle scale is specified as a floating-point number, while the triangle coordinates are integer variables. here what i worte so far :

    Code:
    
    
    Code:
    #include<stdlib.h>
    #include<stdio.h>
    #include<SDL.h>
    #include"triangle.h"
    #include"drawline.h"
    
    #defineTRIANGLE_PENCOLOR0xBBBB0000
    
    /* 
     * Print triangle coordinates along with a message
     */
    void print_triangle(triangle_t *triangle, char *msg)
    {
        printf("%s: %d,%d - %d,%d - %d,%d\n",
            msg,
            triangle->x1, triangle->y1, 
            triangle->x2, triangle->y2, 
            triangle->x3, triangle->y3);
    }
    
    /*
     * Return 0 if triangle coordinates are outside the surface boundary. 1 otherwise.
     */
    int sanity_check_triangle(SDL_Surface *surface, triangle_t *triangle)
    {
        if (triangle->sx1 < 0 || triangle->sx1 >= surface->w ||
            triangle->sx2 < 0 || triangle->sx2 >= surface->w ||
            triangle->sx3 < 0 || triangle->sx3 >= surface->w ||
            triangle->sy1 < 0 || triangle->sy1 >= surface->h ||
            triangle->sy2 < 0 || triangle->sy2 >= surface->h ||
            triangle->sy3 < 0 || triangle->sy3 >= surface->h) {
            return 0;
        } else {
            return 1;
        }
    }
    
    /*
     * Scale triangle, altering the on-screen coordinates(e.g. triangle->sx1)
     */
    void scale_triangle(triangle_t *triangle)
    {
        // TODO: Replace the code below with code that scales each triangle coordinate. 
        // The scaling factor is specified in triangle->scale.
        // Remember that this function MUST write to the on-surface coordinates.
        // Do not alter the model coordinates.
    
        float dx1=0, dx2=0, dx3=0;
        float dy1=0, dy2=0, dy3=0;
        
        triangle->sx1 = triangle->x1;
        triangle->sx2 = triangle->x2;
        triangle->sx3 = triangle->x3;
        triangle->sy1 = triangle->y2;
        triangle->sy2 = triangle->y1;
        triangle->sy3 = triangle->y3;
        
        dx1=((triangle->x2-triangle->x1)*triangle->scale);
        dx2=((triangle->x3-triangle->x2)*triangle->scale);
        dx3= ((triangle->x1-triangle->x3)*triangle->scale);
        dy1=((triangle->y2-triangle->y1)*triangle->scale);
        dy2= ((triangle->y3-triangle->y2)*triangle->scale);
        dy3= ((triangle->y1-triangle->y3)*triangle->scale);
        
        triangle->sx1= triangle->sx3+dx3;
        triangle->sx2= triangle->sx1+dx1;
        triangle->sx3=triangle->sx2+dx2;
        triangle->sy1= triangle->sy3+dy3;
        triangle->sy2= triangle->sy1+dy1;
        triangle->sy3=triangle->sy2+dy2;
    }
    
    /*
     * Move the triangle to the center of the surface,
     * altering the on-screen coordinates(e.g. triangle->sx1)
     */
    void translate_triangle(triangle_t *triangle)
    {
        // TODO: Insert code that moves the triangle on the surface.
        // The translation coordinates are specified in triangle->tx and triangle->ty.
        // Remember to use the on-surface coordinates (triangle->sx1, etc.)
        triangle->tx = 1024/2;
        triangle->ty = 768/2;
    
        triangle->sx1=(triangle->tx+triangle->sx1);
        triangle->sx2 = (triangle->tx+triangle->sx2);
        triangle->sx3 =(triangle->tx+triangle->sx3);
        triangle->sy1 = (triangle->ty+triangle->sy1);
        triangle->sy2= (triangle->ty+triangle->sy2);
        triangle->sy3 = (triangle->ty+triangle->sy3);
        
    }
    
    /*
     * Calculate the triangle bounding box,
     * altering fields of the triangle's rect(e.g. triangle->rect.x)
     */
    void calculate_triangle_bounding_box(triangle_t *triangle)
    {
        // TODO: Insert code that calculates the bounding box of a triangle.
        // Remember to use the on-surface coordinates (triangle->sx1, etc.)
        // The bounding box coordinates should be written to 
        // triangle->rect.x, triangle->rect.y, triangle->rect.w, triangle->rect.h
        triangle->rect.w = triangle->rect.w - triangle->rect.x;
        triangle->rect.y = triangle->rect.y - triangle->rect.h; 
    
        // Calculate max value for x
        triangle->rect.w = triangle->sx1;
        if (triangle->sx2 > triangle->rect.w)
        {
            triangle->rect.w = triangle->sx2;
        }
        if (triangle->sx3 > triangle->rect.w)
        {
            triangle->rect.w = triangle->sx3;
        }
    
        // Calculate min value for x
        triangle->rect.x = triangle->sx1;
        if (triangle->sx2 < triangle->rect.x)
        {
            triangle->rect.x = triangle->sx2;
        }
        if (triangle->sx3 < triangle->rect.x)
        {
            triangle->rect.x = triangle->sx3;
        }
        
        // Calculate max value for y
        triangle->rect.y = triangle->sy1;
        if (triangle->sy2 > triangle->rect.y)
        {
            triangle->rect.y = triangle->sy2;
        }
        if (triangle->sy3 > triangle->rect.y)
        {
            triangle->rect.y = triangle->sy3;
        }
        
        // Calculate min value for y
        triangle->rect.h = triangle->sy1;
        if (triangle->sy2 < triangle->rect.h)
        {
            triangle->rect.h = triangle->sy2;
        }
        if (triangle->sy3 < triangle->rect.h)
        {
            triangle->rect.h = triangle->sy3;
        }
        
    }
    
    /*
     * Fill the triangle on the surface with the triangle's color
     */
    void fill_triangle(SDL_Surface *surface, triangle_t *triangle)
    {
        // TODO: Insert code that fills the triangle with the color specified in triangle->fillcolor.
        // Hint: Draw the triangle with color TRIANGLE_PENCOLOR (this color can not
        // occur in e.g. the teapot or the example triangles).  Thus, if your 
        // approach to filling the triangle relies on looking for the edges of
        // the triangle on the surface (via the GetPixel function), you will find those
        // edges even if the triangle overlaps with a triangle that has already
        // been drawn on the surface.
    
        int i, j, k;
    
        for (k = triangle->rect.h; k <= triangle->rect.h; k++)
        {
        for(i = triangle->rect.x; i <= triangle->rect.w; i++)
        
            if (get_pixel(surface, i, k) == TRIANGLE_PENCOLOR)
            {
                break;
            }
        for (j = triangle->rect.y; j <= triangle->rect.h; j++)
            if (get_pixel(surface, j, k) == TRIANGLE_PENCOLOR)
            {
                break;
            }
      
              draw_line(surface, i, k, j, k, triangle->fillcolor);
        }
    }
    
    /*
     * Draw a filled triangle on the given surface
     */
    void draw_triangle(SDL_Surface *surface, triangle_t *triangle)
    {
        int isOK;
        /* Scale. */
        scale_triangle(triangle);
        
        /* Translate. */
        translate_triangle(triangle);
        
        /* Determine bounding box */
        calculate_triangle_bounding_box(triangle);
    
        /* Sanity check that triangle is within surface boundaries. */
        isOK = sanity_check_triangle(surface, triangle);
        if (!isOK) {
            print_triangle(triangle, "Triangle outside surface boundaries");
            return;
        }
    
        /* 
         * TODO: Insert calls to draw_line to draw the triangle.
         * Remember to use the on-surface coordinates (triangle->sx1, etc.)
         */
        draw_line(surface, triangle->sx1, triangle->sy1, triangle->sx2, triangle->sy2, TRIANGLE_PENCOLOR);
        draw_line(surface, triangle->sx2, triangle->sy2, triangle->sx3, triangle->sy3, TRIANGLE_PENCOLOR);
        draw_line(surface, triangle->sx3, triangle->sy3, triangle->sx1, triangle->sy1, TRIANGLE_PENCOLOR);
    
        /* Fill triangle */
        fill_triangle(surface, triangle);
    
    }
    
    



  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    3,920
    I suggest posting the contents of "triangle.h" and "drawline.h" files.
    I also suggest posting the exact area you need help on.

    Is it a build problem or a run-time problem? You post implies an run-time problem.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  3. #3
    Registered User
    Join Date
    Sep 2020
    Posts
    6
    thank you for reply, i think its run-time problem

    triangle.h
    Code:
    #ifndef TRIANGLE_H_
    #define TRIANGLE_H_
    
    
    #include <SDL.h>
    
    
    #ifndef M_PI
    #define M_PI (3.14159265358979323846)
    #endif
    
    
    typedef struct triangle triangle_t;
    
    
    struct triangle {
        /* Model coordinates, where each pair resemble a corner  */
        int x1, y1;
        int x2, y2;
        int x3, y3;
    
    
        /* The color the triangle is to be filled with */
        unsigned int fillcolor;
        
        /* Scale factor, meaning 0.5 should half the size, 1 keep, and 2.0 double */
        float scale;
    
    
        /* The point (tx, ty) where the center of the teapot should be placed on-screen */
        int tx, ty;
        
        /* 
         * Bounding box of on-screen coordinates:
         * rect.x - x-coordinate of the bounding box' top left corner
         * rect.y - y-coordinate of the bounding box' top left corner
         * rect.w - width of the bounding box
         * rect.h - height of the bounding box
         */
        SDL_Rect rect;
    
    
        /* On-screen coordinates, where each pair resemble a corner */
        int sx1, sy1;
        int sx2, sy2;
        int sx3, sy3;
    };
    
    
    /*
     * Draw a filled triangle on the given surface
     */
    void draw_triangle(SDL_Surface *surface, triangle_t *triangle);
    
    
    
    
    #endif /*TRIANGLE_H_*/
    drawline.h
    Code:
    #ifndef DRAWLINE_H_
    #define DRAWLINE_H_
    
    
    #include <SDL.h>
    
    
    /*
     * Draw a line on the surface from point (x1, y1) to point (x2, y2) using color
     */
    void draw_line(SDL_Surface *surface, int x1, int y1, int x2, int y2, Uint32 color);
    
    
    /* 
     * Read color of pixel (x, y) from the surface
     */
    Uint32 get_pixel(SDL_Surface *surface, int x, int y);
    
    
    /* 
     * Set pixel (x, y) on the surface to the given color
     */
    void set_pixel(SDL_Surface *surface, int x, int y, Uint32 color);
    
    
    #endif /* DRAWLINE_H_ */

  4. #4

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    456
    The scaling code looks wrong to me. Normally you assume that the origin of the model is the point you scale about. So scaling is a simple scalar multiply.

    If you are not scaling round the model origin, you need to translate to whatever point you are scaling about, then apply the multiply. Then you might need to translate back. However I don't think that's the case here.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  6. #6
    Registered User
    Join Date
    Sep 2020
    Posts
    6
    so no one can help me , i have 2 days left to deliver the assignment

  7. #7
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,883
    Did you know that some people post their assignments on here and try to get other people to do all the work for them?

    I'm sure that is not what your trying to do, so you'll need to ask things more like: "I tried this, expected this, but that happened, so I tried this, but that happened"
    Fact - Beethoven wrote his first symphony in C

  8. #8
    Registered User
    Join Date
    Sep 2020
    Posts
    6
    this what i did. i post what i did and i did my best but i am still having problems

  9. #9
    Registered User
    Join Date
    Sep 2020
    Posts
    6
    i am still having probelm with calculating bounding box and fill the triangles with colors

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Making a teapot using triangles
    By dnc in forum C Programming
    Replies: 1
    Last Post: 10-22-2015, 09:08 AM
  2. Making a teapot in C with triangles
    By RST in forum C Programming
    Replies: 5
    Last Post: 10-15-2013, 03:17 PM
  3. Making a teapot using triangles.
    By LEL in forum C Programming
    Replies: 21
    Last Post: 10-15-2013, 11:03 AM
  4. Direct X & C# - Teapot
    By AlexIllsley in forum C# Programming
    Replies: 3
    Last Post: 08-14-2009, 03:52 AM
  5. Drawing triangles in C#
    By John_L in forum C# Programming
    Replies: 2
    Last Post: 03-15-2008, 08:48 AM

Tags for this Thread