Я хочу вычислить видимую площадь многоугольника с точки зрения. Скажем, вы смотрите на квадрат 2 х 2 метра поперек, видимая площадь для вас будет 4 м2.
Теперь представьте, что квадрат повернут как-то, тогда видимая площадь будет меньше. Для этого я решил использовать следующие логики c:
V3_ c (центр масс многоугольника)
V3_v (позиция зрителя)
- Построить плоскость, проходящую через V3_v, с нормалью (V3_ c - V3_v) .normalize ()
- Спроецировать многоугольник на эту плоскость и вычислить площадь
Как я могу сделать это в CGAL?
ОБНОВЛЕНИЕ:
По совету @ mgimeno я использовал следующий (почти псевдо) код.
#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;
}
Вывод:
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
Я не уверен, как работает to_2d но, конечно, не так, как я надеюсь. Вычисленная площадь равна 20 вместо фактических 100.
Кстати, я также начал понимать, что эта цель может быть достигнута простым вычислением угла между направлением обзора (V_ c - V_v) и нормальный из полонга. sin * оригинальная область должна дать площадь.