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