1
\$\begingroup\$

I am having an issue rasterizing a triangle. The goal is to calculate barycentric coordinates and make the triangle based off those coordinates. I am having an issue with having weird jaggy missing pixels on one of my edges. The code is pretty messy currently but here is what I've got:

#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <algorithm>
#include "Image.h"

// This allows you to skip the `std::` in front of C++ standard library
// functions. You can also say `using std::cout` to be more selective.
// You should never do this in a header file.
using namespace std;

struct boundingBox{
    int xmin;
    int xmax;
    int ymin;
    int ymax;
} box;

struct Triangle{
    int xCoordA;
    int yCoordA;
    int xCoordB;
    int yCoordB;
    int xCoordC;
    int yCoordC;
} t;

struct Point{
    float x;
    float y;
} P;


int main(int argc, char **argv)
{



    if(argc < 19 || argc > 19) {
        cout << "Usage: L02 filename width height Vertex1-x Vertex1-y Vertex1-Red Vertex-1-Green Vertex-1-Blue Vertex2-x Vertex2-y Vertex-2-Red Vertex-2-Green Vertex2-2-Blue Vertex3-x Vertex3-y Vertex-3-Red Vertex-3-Green Vertex-3-Blue" << endl;
        return 0;
    }
    // Output filename
    string filename(argv[1]);
    // Width of image
    int width = atoi(argv[2]);
    // Height of image
    int height = atoi(argv[3]);
    // Coordinates of vertex 1
    t.xCoordA = atoi(argv[4]);
    t.yCoordA = atoi(argv[5]);
    //color of vertex 1
    int red1 = atoi(argv[6]);
    int green1 = atoi(argv[7]);
    int blue1 = atoi(argv[8]);
    //coordinates of vertex 2
    t.xCoordB = atoi(argv[9]);
    t.yCoordB = atoi(argv[10]);
    //color of vertex 2
    int red2 = atoi(argv[11]);
    int green2 = atoi(argv[12]);
    int blue2 = atoi(argv[13]);
    //coordinates of vertex 3
    t.xCoordC = atoi(argv[14]);
    t.yCoordC = atoi(argv[15]);
    //color of vertex 3
    int red3 = atoi(argv[16]);
    int green3 = atoi(argv[17]);
    int blue3 = atoi(argv[18]);


    // Find bounding box values
    int xMaxTemp = max((t.xCoordA), (t.xCoordB));
    box.xmax = max(xMaxTemp, (t.xCoordC));
    int yMaxTemp = max((t.yCoordA), (t.yCoordB));
    box.ymax = max(yMaxTemp, (t.yCoordC));
    int xMinTemp = min((t.xCoordA), (t.xCoordB));
    box.xmin = min(xMinTemp, (t.xCoordC));
    int yMinTemp = min((t.yCoordA), (t.yCoordB));
    box.ymin = min(yMinTemp, (t.yCoordC));
    // Create the image. We're using a `shared_ptr`, a C++11 feature.
    auto image = make_shared<Image>(width, height);

    for (int i = box.xmin; i <= box.xmax; i++)
    {
        for (int j = box.ymin; j <= box.ymax; j++)
        {
            P.x = static_cast<float>(i);
            P.y = static_cast<float>(j);
            float denAlpha = ((t.yCoordB - t.yCoordC) * t.xCoordA + (t.xCoordC - t.xCoordB) * t.yCoordA + (t.xCoordB * t.yCoordC) - (t.xCoordC * t.yCoordB));
            float denBeta = ((t.yCoordC - t.yCoordA) * t.xCoordB + (t.xCoordA - t.xCoordC) * t.yCoordB + (t.xCoordC * t.yCoordA) - (t.xCoordA * t.yCoordC));
            float numAlpha = ((t.yCoordB - t.yCoordC) * P.x + (t.xCoordC - t.xCoordB) * P.y + (t.xCoordB * t.yCoordC) - (t.xCoordC * t.yCoordB));
            float numBeta = ((t.yCoordC - t.yCoordA) * P.x + (t.xCoordA - t.xCoordC) * P.y + (t.xCoordC * t.yCoordA) - (t.xCoordA * t.yCoordC));
            float alpha =  numAlpha / denAlpha;
            float beta = numBeta / denBeta;
            float gamma = 1.0 - alpha - beta;


            if (alpha >= 0.0 && beta >= 0.0 && gamma >= 0.0)
            {
                //Then we are in triangle
                int myRed = (red1 * alpha) + (red2 * beta) + (red3 * gamma);
                int myGreen = (green1 * alpha) + (green2 * beta) + (green3 * gamma);
                int myBlue = (blue1 * alpha) + (blue2 * beta) + (blue3 * gamma);
                image->setPixel(P.x, P.y, myRed, myGreen, myBlue);
            }
            else{
                //we are not in triangle
                image->setPixel(P.x, P.y,  0, 0, 0);
            }
        }
    }
    image->writeToFile(filename);
    return 0;
}

I should only need to check if the coordinates are >= 0 since I am using the bounding box to check the other side.

For some reason when I run it this is what the triangle looks like

enter image description here

The hypotenuse has weird jaggy/ missing pixel edges.

I have been working with my instructor for 2 whole lab sessions now, and changing the way I calculate the bary-coordinates hasn't solved anything.

\$\endgroup\$
2
  • \$\begingroup\$ Do you still have the problem if you replace image->setPixel(P.x, P.y, myRed, myGreen, myBlue); with image->setPixel(i, j, 255, 255, 255);? \$\endgroup\$
    – Jay
    Jan 30, 2018 at 0:36
  • \$\begingroup\$ @Jay Unfortunate yes... I just tried that \$\endgroup\$
    – Joe
    Jan 30, 2018 at 2:42

1 Answer 1

2
\$\begingroup\$

Turns out I needed to fully calculate the Gamma, instead of doing that shortcut.

That solved the issue!

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .