2
$\begingroup$

I am going through code snippet that reads in a triangular model, calculates & store the normal with each Triangle object and eventually check the consistencies of winding order. Let us define a triangle with the vertices v1, v2 and v3. The face normal of the triangle is calculated as follows:

void calculateFaceNormal()
{
   //vector from v3 to v1
   double dx13, dy13, dz13;

   //vector from v3 to v2
   double dx23, dy23, dz23;

    dx13 = v1.x_ - v3.x_;
    dy13 = v1.y_ - v3.y_;
    dz13 = v1.z_ - v3.z_;

    dx23 = v2.x_ - v3.x_;
    dy23 = v2.y_ - v3.y_;
    dz23 = v2.z_ - v3.z_;

    // Cross product gives normal.
    x_ = dy13*dz23 - dy23*dz13;
    y_ = dz13*dx23 - dz23*dx13;
    z_ = dx13*dy23 - dx23*dy13;
}

Each Triangle object store the references of its neighboring triangles as follows:

class Triangle()
{
  public:
    .......
    .......

    const Triangle *edge12Granne_;
    const Triangle *edge23Granne_;
    const Triangle *edge31Granne_;

    bool isGranne12NormalConsistent() const;
    bool isGranne23NormalConsistent() const;
    bool isGranne31NormalConsistent() const;
};

Now I am writing down only one of the functions whose definition is not clear to me and I believe that if someone could explain the theories behind it,I shall be able to understand the rest of the other two functions.

bool Triangle::isGranne12NormalConsistent() const
{
    // Find opposing vertex in neighbour.
    if (edge12Granne_->edge12Granne_ == this)
    {
        /*
         * two triangle are neighbors to each other by
         * the adjecent edge that constitutes both the
         * triangles.
         * */

        // v2 | w1
        // v1 | w2
        if (v1_.id_ == edge12Granne_->v2_.id_)
        {
            // Ok (reversed order compared to this.)
            return true;
        }
        else
        {
            // Not ok, same order!
            return false;
        }
    }
    else if (edge12Granne_->edge23Granne_ == this)
    {
        // v2 | w2
        // v1 | w3
        if (v1_.id_ == edge12Granne_->v3_.id_)
        {
            // Ok (reversed order compared to this.)
            return true;
        }
        else
        {
            // Not ok, same order!
            return false;
        }
    }
    else
    {
        // v2 | w3
        // v1 | w1
        if (v1_.id_ == edge12Granne_->v1_.id_)
        {
            // Ok (reversed order compared to this.)
            return true;
        }
        else
        {
            // Not ok, same order!
            return false;
        }
    }
}
$\endgroup$

1 Answer 1

2
$\begingroup$

The function in your third code snippet is checking for the winding order to be consistent between two neighboring triangles. It does this by looking at the order in which vertices are listed in their shared edge. If the two triangles have consistent winding (both counterclockwise for instance), they will have opposite orientations for the shared edge.

A diagram may help see this: diagram of two triangles with vertex winding

The vertex order is indicated by the blue arrows:

t0: v0, v1, v2
t1: v1, v3, v2

If you look at the shared edge (v1–v2), it appears in the first triangle with order v1, v2, and in the other with order v2, v1 (cycling around the end of the vertex list back to the beginning).

The function in your snippet takes a triangle and looks at one of its neighbors, checks all three possibilities for which edge in the second triangle is the shared one, and checks that the vertices in that (other triangle's) edge appear in the reverse order to the vertices in the current triangle's edge. It returns true if this is the case, and false otherwise.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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