Reputation: 166
I want to calculate the apparent area of a polygon from a view point. Say, you are looking at a 2 x 2 meters square from across, the apparent area for you would be 4 m2.
Now image the square is rotated somehow, then the apparent area would be smaller. To do this, I figured I could use the following logic:
V3_c (center of mass of the polygon)
V3_v (viewer's position)
How can I do this in CGAL?
UPDATE:
Upon @mgimeno's suggestions I've used the following (almost pseudo) code.
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/centroid.h>
#include <iostream>
#include <vector>
#include "print_utils.h"
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
typedef Kernel::Point_2 Point_2;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Plane_3 Plane_3;
typedef Kernel::Vector_3 Vector_3;
typedef Kernel::FT ValueType;
using namespace std;
int main(int argc, char* argv[])
{
Point_3 viewer(0, 0, 0);
cout << "Viewer: " << viewer << endl;
Point_3 a(-5, -5, 5);
Point_3 b(-5, -5, -5);
Point_3 c(5, -5, -5);
Point_3 d(5, -5, 5);
cout << "Surface: " << a << ", " << b << ", " << c << ", " << d << endl;
std::vector<Point_3> vertices;
vertices.push_back(a);
vertices.push_back(b);
vertices.push_back(c);
vertices.push_back(d);
Point_3 center = CGAL::centroid(vertices.begin(), vertices.end(), CGAL::Dimension_tag<0>());
cout << "Center of surface: " << center << endl;
Vector_3 normal = center - viewer;
Plane_3 plane(viewer, normal);
cout << "Plane passing thorough viewer orthogonal to surface: " << plane << endl;
Point_3 pa = plane.projection(a);
Point_3 pb = plane.projection(b);
Point_3 pc = plane.projection(c);
Point_3 pd = plane.projection(d);
cout << "Projected surface onto the plane: " << pa << ", " << pb << ", " << pc << ", " << pd << endl;
Point_2 pa2 = plane.to_2d(pa);
Point_2 pb2 = plane.to_2d(pb);
Point_2 pc2 = plane.to_2d(pc);
Point_2 pd2 = plane.to_2d(pd);
cout << "to_2d of the projected plane: " << pa2 << ", " << pb2 << ", " << pc2 << ", " << pd2 << endl;
std::vector<Point_2> vertices2;
vertices2.push_back(pa2);
vertices2.push_back(pb2);
vertices2.push_back(pc2);
vertices2.push_back(pd2);
ValueType result;
CGAL::area_2(vertices2.begin(), vertices2.end(), result);
cout << "Area of to_2d'ed vertices: " << result << endl;
return EXIT_SUCCESS;
}
The output is:
Viewer: 0 0 0
Surface: -5 -5 5, -5 -5 -5, 5 -5 -5, 5 -5 5
Center of surface: 0 -5 0
Plane passing thorough viewer orthogonal to surface: 0 -5 0 0
Projected surface onto the plane: -5 0 5, -5 0 -5, 5 0 -5, 5 0 5
to_2d of the projected plane: -5 1, -5 -1, 5 -1, 5 1
Area of to_2d'ed vertices: 20
I'm not sure how to_2d works but certainly not the way I hope it would. The computed area is 20 instead of the actual 100.
BTW, I've also begin to realize that this goal could be achieved by simple computing the angle between the viewing direction (V_c - V_v) and normal ofthe polyong. sin a * original_area should give the area.
Upvotes: 2
Views: 239
Reputation: 726
To compute the centroid of your polygon you can use CGAL::centroid(). Then to construct your plane you can use the constructor of Plane_3 that takes a point and a normal. After that you can project each point of your polygon using Plane_3::projection(), and then I'd propose to use to_2D() on those new points to get Point_2, and be able to use area_2().
Upvotes: 1