Area of a polygon



  • On 02/07/2014 at 12:39, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   13 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hi,

    I'm trying to find the area of a polygon. And I was wondering if there's a better way than how I'm doing it?
    Right now I'm splitting it up into two triangles. And getting the first triangle's area like this:

        PolygonObject *obj = (PolygonObject* ) doc->GetActiveObject();  
      if(!obj || obj->GetType() != Opolygon) return FALSE;  
      
      CPolygon poly = obj->GetPolygonW()[0];  //Get the first polygon in the object to find it's area  
      
      Vector p1 = obj->GetPointW()[poly.a];  
      Vector p2 = obj->GetPointW()[poly.b];  
      Vector p3 = obj->GetPointW()[poly.c];  
      Vector p4 = obj->GetPointW()[poly.d];  
      
      Real side1 = sqrt( (p2.x-p1.x) + (p2.y-p1.y) + (p2.z-p1.z) );  //Distance a-b  
      Real side2 = sqrt( (p3.x-p2.x) + (p3.y-p2.y) + (p3.z-p2.z) );  //Distance b-c  
      Real side3 = sqrt( (p3.x-p1.x) + (p3.y-p1.y) + (p3.z-p1.z) );  //Distance c-a The hypotenuse  
      Real s = (side1+side2+side3)/2;  
      Real area= sqrt(s*(s-side1)*(s-side2)*(s-side3));    //The area of only this side (triangle) of the polygon  
      GePrint(RealToString(area));
    

    This only gives me the area for the left hand triangle area of the polygon.
    So now do I have to run the same damned code all over again. Using the right side edges to get the other polygon's area. Then add them together?

    Repeating the same code twice just to get both triangle's areas seems a bit silly to me.
    Is there a better(shorter) way to get the area of a polygon?

    -ScottA



  • On 02/07/2014 at 12:55, xxxxxxxx wrote:

    The area of a triangle spanning three points (a,b,c) can be found by the following formula: 0.5*((b-a)%(c-a)), where % is the cross product.

    Splitting quads into two triangles makes sense to me. If you are worried about repeating code, just wrap the triangle area calculation in a (possibly inlined) function.

    /Filip



  • On 02/07/2014 at 15:43, xxxxxxxx wrote:

    // Area of polygon
    //*---------------------------------------------------------------------------*
    Real UnfurlObj::TriangleArea(const Vector& v0, const Vector& v1, const Vector& v2)
    //*---------------------------------------------------------------------------*
    {
    	// A(triangle) = 1/2 * |(v1-v0)X(v2-v0)|
    	return (0.5 * Len((v1-v0)%(v2-v0)));
    }
    //*---------------------------------------------------------------------------*
    Real UnfurlObj::QuadrangleArea(const Vector& v0, const Vector& v1, const Vector& v2, const Vector& v3)
    //*---------------------------------------------------------------------------*
    {
    	// TriangleArea(v0,v1,v2)+TriangleArea(v2,v3,v0)
    	return (0.5 * Len((v1-v0)%(v2-v0)))+(0.5 * Len((v3-v2)%(v0-v2)));
    }
    


  • On 02/07/2014 at 16:35, xxxxxxxx wrote:

    Thanks guys.
    I reworked my code and it turned out that I didn't need to duplicate it as much as I had thought.
    But the version you guys gave returns a different value than my version.
    On the default C4D polygon object. My code returns an area value of: 100
    But your code returns a value of: 10,000
    Which one is the correct area value? 100 or 10,000?

    Here they are both in the same code. Using the same polygon points of the default C4D polygon object.
    Am I making a math error in one of them?

        PolygonObject *obj = (PolygonObject* ) doc->GetActiveObject();  
      if(!obj || obj->GetType() != Opolygon) return FALSE;  
      
      CPolygon poly = obj->GetPolygonW()[0];  
      Vector p1 = obj->GetPointW()[poly.a];  
      Vector p2 = obj->GetPointW()[poly.b];  
      Vector p3 = obj->GetPointW()[poly.c];  
      Vector p4 = obj->GetPointW()[poly.d];      
      
      Real side1 = sqrt( (p2.x-p1.x) + (p2.y-p1.y) + (p2.z-p1.z) );  //Distance b-a  
      Real side2 = sqrt( (p3.x-p2.x) + (p3.y-p2.y) + (p3.z-p2.z) );  //Distance c-b  
      Real side3 = sqrt( (p3.x-p4.x) + (p3.y-p4.y) + (p3.z-p4.z) );  //Distance c-d  
      Real side4 = sqrt( (p4.x-p1.x) + (p4.y-p1.y) + (p4.z-p1.z) );  //Distance d-a  
      Real hypot = sqrt( (p3.x-p1.x) + (p3.y-p1.y) + (p3.z-p1.z) );  //Distance c-a The hypotenuse      
      
      //The area of only the left side (triangle) of the polygon  
      Real s = (side1+side2+hypot)/2;   
      Real a1 = sqrt(s*(s-side1)*(s-side2)*(s-hypot));  
      
      //The area of only the right side (triangle) of the polygon  
      Real s2 = (side4+side3+hypot)/2;  
      Real a2 = sqrt(s2*(s2-side3)*(s2-side4)*(s2-hypot));    //The area of only this side (triangle) of the polygon  
      
      //The area of both triangles  
      GePrint(RealToString(a1 + a2));  //Prints 100  
      
      //Alternative way to get the area of both triangles  
      Real area = 0.5 * Len((p2-p1)%(p3-p1))  \+ 0.5 * Len((p4-p3)%(p1-p3)); //Prints 10,000  
      GePrint(RealToString(area));
    

    -ScottA



  • On 02/07/2014 at 18:38, xxxxxxxx wrote:

    All that I know is that the 0.5*((b-a)%(c-a)) method is mathematically sound.  I do not see why sqrt() is involved at all.  The area of a square is NxN where N is the length of each side.  For a (right) triangle, it is 1/2 NxN and the cross product method gives similar results on the general triangle.



  • On 02/07/2014 at 19:18, xxxxxxxx wrote:

    Ok then.
    I guess 10,000 is the correct answer. I just wanted to be 100% certain.

    I used sqrt because I didn't want a vector type as the distance values between the points.
    I wanted a "Real" value to be the result. Because I thought it would be less confusing to get the area from that. But I guess that's an improper thing to do.

    -ScottA


Log in to reply