CMPS-3480 Computer Graphics
Lab-4

Elements of the lab:

Step 1:
We will do some coding together on Zoom.

Do your work in your Odin 3480/4 folder.

Start with lab1.cpp:
   /home/fac/gordon/puplic_html/3480/code/1/lab1.cpp

Do not copy this file if you already have it in your 3480/4 folder.



Homework is below
Homework for lab-4
In lab class we rendered the following objects...

   key 1: circle  
   key 2: square  
   key 4: circle inscribed in square  
   key 5: triangle  

Add the following

   key 3: rectangle
   key 6: a ring
   key 7: checkerboard pattern
   key 8: triangle using odd-even method
   key 9: RGB gradient colored triangle using barycentric coordinates
   key a: triangle with a texture-map


Description of objects

circle
 . define g.center[2] and g.radius
 . find distance from point to center
 . compare distance to radius, and set the color

ring
 . define g.center[2] and g.min_radius, g.max_radius
 . find distance from point to center
 . compare distance to min_radius and max_radius
 . set a color if between radii

rectangle
 . define g.center[2], g.width, g.height
 . find horizontal distance from point to center
 . find vertical distance from point to center
 . compare distances to width and height
 . set a color if within

calculate PI
 . define your window size to be square in shape
 . define a circle that inscribes the square
 . start filling with pixels
 . keep a count of all pixels
 . keep a count of pixels inside the circle
 . pi = 4.0 * circle_pixels / all_pixels
 . at intervals, display pi on your console with printf
 . link

checkerboard (procedural texture)
 . define a width and height of each checkerboard tile
 . start filling with pixels
 . check each pixel to see if it is on a white or black tile
 . do this calculation yourself

   try this...
      1 - divide pixel x by width
      2 - check if even or odd
      3 - divide pixel y by height
      4 - check if even or odd
      5 - if same, set a color
      6 - if different, set a different color

Triangle (odd/even method)
The pseudocode below fills a triangle using Odd-Even rule.

Add this to your program by converting the psuedocode into C++ code.

Determine if point at x, y is inside a triangle.
Use a horizontal line from (x,y) to (infinity,y).
Does line intersect any triangle sides?

notes: vert is a triangle_vertex from g.tri[3]
       a <-- b  means assign b to a

Use the pseudocode below to make this work.

set pixel color to blue
n <-- 0
i <-- 0
while (i < 3) do
    p0 <-- i
    p1 <-- (i+1) mod 3
    ydiff <-- (vert[p1][1] - vert[p0][1])
    if ydiff < 0 then
        SWAP p0 and p1
    end-if
    if y >= vert[p0][1] and y < vert[p1][1] then
        ydiff <-- (vert[p1][1] - vert[p0][1])
        xdiff <-- (vert[p1][0] - vert[p0][0])
        if xdiff not 0 then
            //slope = rise/run
            slope <-- ydiff/xdiff
            //x intersect is difference in y divided by the slope
            xintersect <-- (y - vert[p1][1]) / slope
            if (xintersect + vert[p1][0]) ≥ x then
                increment n
            end-if
        end-if
    end-if
    i <-- i+1
end-do
//odd number indicates inside
if n is odd then
    set pixel color
end-if

--end of pseudocode--


Barycentric coordinates
Fill a triangle using barycentric coordinates.

Heron's formula for triangle area!

You will need to write functions such as...

Flt getLength(Vec p1, Vec p2);
Flt getTriangleArea(Vec p1, Vec p2, Vec p3);
bool getBarycentric(Vec tri[3], int x, int y, Flt *u, Flt *v);

Use the u, v, w components to derive the color of each pixel
in the triangle.

Your triangle will be shaded like this...


On Monday we will get the blended triangle on the screen together.

Insert these three functions into your lab4.cpp program.

double getLength(double p1[2], double p2[2])
{
    double dx = p1[0] - p2[0];
    double dy = p1[1] - p2[1];
    return sqrt(dx*dx + dy*dy);
}

double triangleArea(double tri[3][2])
{
    //get side lengths
    double a = getLength(tri[0], tri[1]);
    double b = getLength(tri[1], tri[2]);
    double c = getLength(tri[2], tri[0]);
    double s = (a+b+c) / 2.0;
    //new code added 9/17/2021
    double heron = s * (s - a) * (s - b) * (s - c);
    if (heron < 0.0)
        heron = -heron;
    return sqrt(heron);
}

bool getBarycentric(double t[3][2], double *pt, double *u, double *v)
{
    //main triangle is already built in t.
    //build sub-triangle st1
    double st1[3][2] = { t[0][0],t[0][1], t[1][0],t[1][1], pt[0],pt[1] };
    //build sub-triangle st2
    double st2[3][2] = { t[1][0],t[1][1], t[2][0],t[2][1], pt[0],pt[1] };
    double areaMain = triangleArea(t);
    double areaSub1 = triangleArea(st1);
    double areaSub2 = triangleArea(st2);
    *u = areaSub1 / areaMain;
    *v = areaSub2 / areaMain;
    return ((*u + *v) <= 1.0 && *u >= 0.0 && *v >= 0.0);
}

Place them just above the physics() function.
Get your mode 9 in-place in your code.

To start this yourself...
1. define in global: double tri[3][2];
2. in check_keys for key 9, generate 3 random points in your g.tri array.
3. in render:
   check for mode 9
   put x,y in double pt[2] array
   call getBarycentric function
   if it returns true,
      double w = 1.0-u-v
      scale u,v,w by 255.0
      use scaled u,v,w as the colors for the pixel
      you are done

We will do the steps above together in class.
Extra credit if you get this working on your own, over the weekend.


Here is one thing we forgot to do in class...
Always check to see if the barycentric coordinates are valid.
Put this check in your code.

if (getBarycentric(...) {
	...
	...
}



Fill triangle with a picture
Fill a triangle with your picture from lab-1.
(or other image)

Bring in the get_image_stream function from your lab1.cpp.

Use barycentric coordinates of each pixel generated to get a color
from your Image data stream.

  1. use 3-half spaces to determine if pixel inside triangle
  2. generate barycentric coordinates for the pixel
  3. use u,v,w to scale each of the 3 (x,y) coordinates on your image.
  4. the sum of the scaled values will be the location of your color.
  5. go get the rgb color from the data stream.

sample image...



Lab-4 art
Lab-4 images from a previous student are below.
Try to make an image similar to ane below.
Think up your own.

Choose a key that, when pressed, will generate your image.

Take a screen shot and put your artwork out on your webpage.


What to turn in...
Your instructor will find your work out on Odin server.