Расчет видимой площади многоугольника с точки зрения - PullRequest
1 голос
/ 28 января 2020

Я хочу вычислить видимую площадь многоугольника с точки зрения. Скажем, вы смотрите на квадрат 2 х 2 метра поперек, видимая площадь для вас будет 4 м2.

Теперь представьте, что квадрат повернут как-то, тогда видимая площадь будет меньше. Для этого я решил использовать следующие логики c:

V3_ c (центр масс многоугольника)

V3_v (позиция зрителя)

  1. Построить плоскость, проходящую через V3_v, с нормалью (V3_ c - V3_v) .normalize ()
  2. Спроецировать многоугольник на эту плоскость и вычислить площадь

Как я могу сделать это в CGAL?

enter image description here

enter image description here

ОБНОВЛЕНИЕ:

По совету @ 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 * оригинальная область должна дать площадь.

1 Ответ

1 голос
/ 29 января 2020

Для вычисления центроида вашего многоугольника вы можете использовать CGAL :: centroid () . Затем, чтобы построить свою плоскость, вы можете использовать конструктор Plane_3, который принимает точку и нормаль . После этого вы можете проецировать каждую точку вашего многоугольника с помощью Plane_3 :: projection () , а затем я предлагаю использовать to_2D () для этих новых точек, чтобы получить Point_2, и уметь использовать area_2 () .

...