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:
#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);
}