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\$
  • \$\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 '18 at 0:36
  • \$\begingroup\$ @Jay Unfortunate yes... I just tried that \$\endgroup\$ – Joe Jan 30 '18 at 2:42
2
\$\begingroup\$

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

That solved the issue!

\$\endgroup\$
  • 1
    \$\begingroup\$ Don't forget to come back and accept this answer in a couple of days :) \$\endgroup\$ – Alexandre Vaillancourt Jan 30 '18 at 4:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.