mirror of https://github.com/CGAL/cgal
implemented treatment of needles
This commit is contained in:
parent
122c0488a4
commit
88e5066154
|
|
@ -24,13 +24,12 @@
|
|||
|
||||
#include <CGAL/Arrangement_2.h>
|
||||
#include <stack>
|
||||
#include <deque>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace Visibility_2 {
|
||||
|
||||
template<class Arrangement_2>
|
||||
template<class Arrangement_2, class Regularization_tag>
|
||||
class Simple_visibility_2 {
|
||||
|
||||
public:
|
||||
|
|
@ -40,20 +39,25 @@ public:
|
|||
typedef Arrangement_2 Output_Arrangement_2;
|
||||
|
||||
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
|
||||
typedef typename Arrangement_2::Ccb_halfedge_const_circulator Ccb_halfedge_const_circulator;
|
||||
typedef typename Arrangement_2::Ccb_halfedge_const_circulator
|
||||
Ccb_halfedge_const_circulator;
|
||||
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
|
||||
|
||||
typedef typename Geometry_traits_2::Point_2 Point_2;
|
||||
typedef typename Geometry_traits_2::Ray_2 Ray_2;
|
||||
typedef typename Geometry_traits_2::Segment_2 Segment_2;
|
||||
typedef typename Geometry_traits_2::Line_2 Line_2;
|
||||
typedef typename Geometry_traits_2::Vector_2 Vector_2;
|
||||
typedef typename Geometry_traits_2::Direction_2 Direction_2;
|
||||
typedef typename Geometry_traits_2::FT Number_type;
|
||||
|
||||
|
||||
Simple_visibility_2() : p_arr(NULL) {};
|
||||
Simple_visibility_2() : p_arr(NULL), geom_traits(NULL) {};
|
||||
|
||||
/*! Constructor given an arrangement and the Regularization tag. */
|
||||
Simple_visibility_2(const Input_Arrangement_2 &arr/*, Regularization_tag r_t*/): p_arr(&arr) {};
|
||||
Simple_visibility_2(const Input_Arrangement_2 &arr):
|
||||
p_arr(&arr) {
|
||||
geom_traits = p_arr->geometry_traits();
|
||||
};
|
||||
|
||||
bool is_attached() {
|
||||
return (p_arr != NULL);
|
||||
|
|
@ -61,82 +65,95 @@ public:
|
|||
|
||||
void attach(const Input_Arrangement_2 &arr) {
|
||||
p_arr = &arr;
|
||||
geom_traits = p_arr->geometry_traits();
|
||||
}
|
||||
|
||||
void detach() {
|
||||
p_arr = NULL;
|
||||
geom_traits = NULL;
|
||||
}
|
||||
|
||||
Input_Arrangement_2 arr() {
|
||||
return *p_arr;
|
||||
}
|
||||
|
||||
void visibility_region(Point_2 &q,
|
||||
const Face_const_handle face,
|
||||
Output_Arrangement_2 &out_arr
|
||||
) {
|
||||
void visibility_region(Point_2 &q, const Face_const_handle face,
|
||||
Output_Arrangement_2 &out_arr) {
|
||||
|
||||
typename Input_Arrangement_2::Ccb_halfedge_const_circulator circ = face->outer_ccb();
|
||||
typename Input_Arrangement_2::Ccb_halfedge_const_circulator circ =
|
||||
face->outer_ccb();
|
||||
typename Input_Arrangement_2::Ccb_halfedge_const_circulator curr = circ;
|
||||
typename Input_Arrangement_2::Halfedge_const_handle he = curr;
|
||||
|
||||
std::vector<Point_2> temp_vertices;
|
||||
Point_2 intersect_pt;
|
||||
Point_2 min_intersect_pt;
|
||||
bool intersect_on_endpoint = false;
|
||||
|
||||
Segment_2 curr_edge(he->source()->point(), he->target()->point());
|
||||
Point_2 curr_vertex = he->source()->point();
|
||||
Number_type min_dist = dist_point_to_segment(q, curr_edge, intersect_pt);
|
||||
Segment_2 curr_min_edge(he->source()->point(), he->target()->point());
|
||||
Point_2 curr_vertex = he->target()->point();
|
||||
min_intersect_pt =
|
||||
Construct_projected_point_2(curr_min_edge.supporting_line(), q);
|
||||
|
||||
temp_vertices.push_back(curr_vertex);
|
||||
Number_type min_dist = Compute_squared_distance_2(q, curr_edge);
|
||||
|
||||
int min_dist_index = 0;
|
||||
int index = 0;
|
||||
int index = 1;
|
||||
|
||||
// Push all vertices and determine edge minimum in terms of squared distance to query point
|
||||
curr++;
|
||||
// Push all vertices and determine edge minimum in terms
|
||||
// of squared distance to query point
|
||||
do {
|
||||
he = curr;
|
||||
curr_edge = Segment_2(he->source()->point(), he->target()->point());
|
||||
Number_type curr_dist = Compute_squared_distance_2(q, curr_edge);
|
||||
|
||||
Number_type curr_dist = dist_point_to_segment(q, curr_edge, intersect_pt);
|
||||
if (curr_dist < min_dist) {
|
||||
min_dist = curr_dist;
|
||||
min_dist_index = index;
|
||||
min_intersect_pt = intersect_pt;
|
||||
curr_min_edge = curr_edge;
|
||||
}
|
||||
temp_vertices.push_back(he->source()->point());
|
||||
temp_vertices.push_back(he->target()->point());
|
||||
index++;
|
||||
} while (++curr != circ);
|
||||
|
||||
std::cout << "min_index = " << min_dist_index << std::endl;
|
||||
// Only now compute the intersection point
|
||||
min_intersect_pt =
|
||||
Construct_projected_point_2(curr_min_edge.supporting_line(), q);
|
||||
|
||||
if (min_intersect_pt != curr_min_edge.source() &&
|
||||
min_intersect_pt != curr_min_edge.target()) {
|
||||
vertices.push_back(min_intersect_pt);
|
||||
}
|
||||
|
||||
vertices.push_back(intersect_pt);
|
||||
// Now create vector so that first vertex v0 is visible
|
||||
for (unsigned int k = min_dist_index ; k < temp_vertices.size() ; k++) {
|
||||
std::cout << "Pushing " << temp_vertices[k] << std::endl;
|
||||
vertices.push_back(temp_vertices[k]);
|
||||
}
|
||||
for (unsigned int k = 0 ; k < min_dist_index ; k++) {
|
||||
std::cout << "Pushing " << temp_vertices[k] << std::endl;
|
||||
vertices.push_back(temp_vertices[k]);
|
||||
}
|
||||
// Push first vertex again to fulfill algo precondition
|
||||
vertices.push_back(intersect_pt);
|
||||
|
||||
std::cout << "Vertices:\n";
|
||||
for (unsigned int k = 0 ; k < vertices.size() ; k++) {
|
||||
std::cout << vertices[k] << std::endl;
|
||||
// Push first vertex again to fulfill algo precondition
|
||||
if (min_intersect_pt != curr_min_edge.source() &&
|
||||
min_intersect_pt != curr_min_edge.target()) {
|
||||
vertices.push_back(min_intersect_pt);
|
||||
}
|
||||
else {
|
||||
vertices.push_back(vertices[0]);
|
||||
}
|
||||
|
||||
visibility_region_impl(q, out_arr);
|
||||
visibility_region_impl(q);
|
||||
|
||||
std::cout << "RESULT: " << std::endl;
|
||||
typename std::deque<Segment_2> segments;
|
||||
typename std::vector<Point_2> points;
|
||||
if (!s.empty()) {
|
||||
Point_2 prev_pt = s.top();
|
||||
std::cout << "prev: " << prev_pt << std::endl;
|
||||
if (prev_pt == intersect_pt) {
|
||||
if (prev_pt == min_intersect_pt) {
|
||||
s.pop();
|
||||
if (!s.empty()) {
|
||||
prev_pt = s.top();
|
||||
points.push_back(prev_pt);
|
||||
}
|
||||
}
|
||||
if (!s.empty()) {
|
||||
|
|
@ -144,43 +161,31 @@ public:
|
|||
}
|
||||
while(!s.empty()) {
|
||||
Point_2 curr_pt = s.top();
|
||||
std::cout << "curr: " << curr_pt << std::endl;
|
||||
if (curr_pt == intersect_pt) {
|
||||
if (curr_pt == min_intersect_pt) {
|
||||
s.pop();
|
||||
}
|
||||
else {
|
||||
segments.push_front(Segment_2(curr_pt, prev_pt));
|
||||
points.push_back(curr_pt);
|
||||
prev_pt = curr_pt;
|
||||
s.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "initial\n";
|
||||
for (typename std::deque<Segment_2>::iterator it = segments.begin(); it != segments.end(); it++) {
|
||||
std::cout << it->source() << " " << it->target() << std::endl;
|
||||
std::reverse(points.begin(), points.end());
|
||||
std::vector<Segment_2> segments;
|
||||
treat_needles(q, points, segments);
|
||||
CGAL::insert_non_intersecting_curves(out_arr,
|
||||
segments.begin(),
|
||||
segments.end());
|
||||
}
|
||||
|
||||
// Close the loop
|
||||
std::cout << "src: " << segments[0].source() << std::endl;
|
||||
std::cout << "trg: " << segments[segments.size()-1].target() << std::endl;
|
||||
segments.push_back(Segment_2(segments[segments.size()-1].target(), segments[0].source()));
|
||||
|
||||
for (typename std::deque<Segment_2>::iterator it = segments.begin(); it != segments.end(); it++) {
|
||||
std::cout << it->source() << " " << it->target() << std::endl;
|
||||
}
|
||||
CGAL::insert(out_arr, segments.begin(), segments.end());
|
||||
}
|
||||
|
||||
void visibility_region(const Point_2 &q,
|
||||
const Halfedge_const_handle he,
|
||||
Output_Arrangement_2 &out_arr
|
||||
) {
|
||||
void visibility_region(const Point_2 &q, const Halfedge_const_handle he,
|
||||
Output_Arrangement_2 &out_arr ) {
|
||||
|
||||
if (q != he->source()->point()) {
|
||||
if (q != he->target()->point()) {
|
||||
s.push(q);
|
||||
// vertices.push_back(q);
|
||||
vertices.push_back(he->target()->point());
|
||||
}
|
||||
else {
|
||||
|
|
@ -193,7 +198,8 @@ public:
|
|||
}
|
||||
|
||||
typename Input_Arrangement_2::Face_const_handle face = he->face();
|
||||
typename Input_Arrangement_2::Ccb_halfedge_const_circulator circ = face->outer_ccb();
|
||||
typename Input_Arrangement_2::Ccb_halfedge_const_circulator circ =
|
||||
face->outer_ccb();
|
||||
typename Input_Arrangement_2::Ccb_halfedge_const_circulator curr;
|
||||
typename Input_Arrangement_2::Halfedge_const_handle he_handle = circ;
|
||||
|
||||
|
|
@ -208,56 +214,99 @@ public:
|
|||
he_handle = curr;
|
||||
vertices.push_back(Point_2(he_handle->source()->point()));
|
||||
|
||||
typename Input_Arrangement_2::Ccb_halfedge_const_circulator next;
|
||||
next = curr;
|
||||
next++;
|
||||
|
||||
while (curr != circ) {
|
||||
he_handle = curr;
|
||||
Point_2 curr_vertex = he_handle->target()->point();
|
||||
vertices.push_back(curr_vertex);
|
||||
curr++;
|
||||
next = curr;
|
||||
next++;
|
||||
}
|
||||
vertices.push_back(q);
|
||||
std::cout << "Vertices:" << std::endl;
|
||||
for (unsigned int i = 0 ; i < vertices.size() ; i++) {
|
||||
std::cout << vertices[i] << std::endl;
|
||||
|
||||
visibility_region_impl(q);
|
||||
|
||||
typename std::vector<Point_2> points;
|
||||
if (!s.empty()) {
|
||||
Point_2 prev_pt = s.top();
|
||||
if (prev_pt != q) {
|
||||
points.push_back(prev_pt);
|
||||
}
|
||||
if (!s.empty()) {
|
||||
s.pop();
|
||||
}
|
||||
while(!s.empty()) {
|
||||
Point_2 curr_pt = s.top();
|
||||
if (curr_pt != q) {
|
||||
points.push_back(curr_pt);
|
||||
}
|
||||
s.pop();
|
||||
}
|
||||
}
|
||||
|
||||
visibility_region_impl(q, out_arr);
|
||||
std::reverse(points.begin(), points.end());
|
||||
std::vector<Segment_2> segments;
|
||||
treat_needles(q, points, segments);
|
||||
CGAL::insert_non_intersecting_curves(out_arr, segments.begin(), segments.end());
|
||||
}
|
||||
|
||||
void print_arrangement(const Arrangement_2 &arr) {
|
||||
typedef typename Arrangement_2::Edge_const_iterator Edge_const_iterator;
|
||||
Edge_const_iterator eit;
|
||||
std::cout << arr.number_of_edges() << " edges:" << std::endl;
|
||||
for (eit = arr.edges_begin(); eit != arr.edges_end(); ++eit)
|
||||
std::cout << "[" << eit->curve() << "]" << std::endl;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Input_Arrangement_2 *p_arr;
|
||||
const Geometry_traits_2 *geom_traits;
|
||||
std::stack<Point_2> s;
|
||||
std::vector<Point_2> vertices;
|
||||
enum {LEFT, RIGHT, SCANA, SCANB, SCANC, SCAND, FINISH} upcase;
|
||||
|
||||
Number_type dist_point_to_segment(const Point_2 &p, const Segment_2 &seg, Point_2 &intersect_pt) {
|
||||
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
|
||||
|
||||
Vector_2 v(seg);
|
||||
Vector_2 w(seg.source(), p);
|
||||
Number_type c1 = w*v;
|
||||
if (c1 <= 0) {
|
||||
intersect_pt = seg.source();
|
||||
return squared_distance(p, seg.source());
|
||||
bool LessDistanceToPoint_2(const Point_2 &p, const Point_2 &q,
|
||||
const Point_2 &r) const {
|
||||
typename Geometry_traits_2::Less_distance_to_point_2 less_dist =
|
||||
geom_traits->less_distance_to_point_2_object();
|
||||
return less_dist(p, q, r);
|
||||
}
|
||||
|
||||
Number_type c2 = v*v;
|
||||
if (c2 <= c1) {
|
||||
intersect_pt = seg.target();
|
||||
return squared_distance(p, seg.target());
|
||||
bool Collinear(const Point_2 &p, const Point_2 &q,
|
||||
const Point_2 &r) const {
|
||||
typename Geometry_traits_2::Collinear_2 collinear_fnct =
|
||||
geom_traits->collinear_2_object();
|
||||
return collinear_fnct(p, q, r);
|
||||
}
|
||||
/*
|
||||
Object_2 Intersect_2(const Segment_2 &s1, const Segment_2 &s2) {
|
||||
typename Geometry_traits_2::Intersect_2 intersect_fnct =
|
||||
geom_traits->intersect_2_object();
|
||||
return intersect_fnct(s1, s2);
|
||||
}
|
||||
*/
|
||||
Orientation Orientation_2(const Point_2 &p, const Point_2 &q,
|
||||
const Point_2 &r) {
|
||||
typename Geometry_traits_2::Orientation_2 orient =
|
||||
geom_traits->orientation_2_object();
|
||||
return orient(p, q, r);
|
||||
}
|
||||
|
||||
Number_type b = c1/c2;
|
||||
intersect_pt = Point_2(seg.source() + b*v);
|
||||
return squared_distance(p, intersect_pt);
|
||||
Point_2 Construct_projected_point_2(const Line_2 &l, const Point_2 &p) {
|
||||
typename Geometry_traits_2::Construct_projected_point_2 construct_proj =
|
||||
geom_traits->construct_projected_point_2_object();
|
||||
return construct_proj(l, p);
|
||||
}
|
||||
|
||||
Number_type Compute_squared_distance_2(const Point_2 &p,
|
||||
const Segment_2 &seg) {
|
||||
typename Geometry_traits_2::Compute_squared_distance_2 compute_dist =
|
||||
geom_traits->compute_squared_distance_2_object();
|
||||
return compute_dist(p, seg);
|
||||
}
|
||||
|
||||
bool do_overlap(const Point_2 &a, const Point_2 &b, const Point_2 &c) {
|
||||
if (collinear(a, b, c)) {
|
||||
std::cout << a << " " << b << " " << c << " are collinear" << std::endl;
|
||||
Segment_2 s1(a, b);
|
||||
Segment_2 s2(a, c);
|
||||
const Segment_2 *seg_overlap;
|
||||
|
|
@ -269,13 +318,93 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
void visibility_region_impl(const Point_2 &q, Output_Arrangement_2 &out_arr) {
|
||||
void treat_needles(const Point_2 &q, typename std::vector<Point_2> &points,
|
||||
typename std::vector<Segment_2> &segments) {
|
||||
|
||||
typename std::vector<Point_2>::size_type i = 0;
|
||||
|
||||
while (CGAL::collinear(points[i], points[points.size()-1],
|
||||
points[points.size()-2]) ||
|
||||
CGAL::collinear(points[i], points[i+1], points[points.size()-1])) {
|
||||
|
||||
points.push_back(points[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
points.push_back(points[i]);
|
||||
|
||||
std::vector<Point_2> forward_needle;
|
||||
std::vector<Point_2> backward_needle;
|
||||
|
||||
while (i+1 < points.size()) {
|
||||
if ((i+2 < points.size()) &&
|
||||
(Orientation_2(points[i],
|
||||
points[i+1],
|
||||
points[i+2]) == CGAL::COLLINEAR)) {
|
||||
|
||||
Point_2 needle_start = points[i];
|
||||
Direction_2 forward_dir(Segment_2(points[i], points[i+1]));
|
||||
forward_needle.push_back(points[i]);
|
||||
forward_needle.push_back(points[i+1]);
|
||||
|
||||
while ((i+2 < points.size()) &&
|
||||
(Orientation_2(points[i],
|
||||
points[i+1],
|
||||
points[i+2]) == CGAL::COLLINEAR)) {
|
||||
|
||||
Direction_2 check_dir(Segment_2(points[i+1], points[i+2]));
|
||||
if (forward_dir == check_dir) {
|
||||
forward_needle.push_back(points[i+2]);
|
||||
}
|
||||
else if (check_dir == -forward_dir) {
|
||||
backward_needle.push_back(points[i+2]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
std::reverse(backward_needle.begin(), backward_needle.end());
|
||||
|
||||
std::vector<Point_2> merged_needle;
|
||||
|
||||
// Now merge the two vectors
|
||||
unsigned int itr_fst = 0, itr_snd = 0;
|
||||
while (itr_fst < forward_needle.size() &&
|
||||
itr_snd < backward_needle.size()) {
|
||||
|
||||
if (LessDistanceToPoint_2(q, forward_needle[itr_fst],
|
||||
backward_needle[itr_snd])) {
|
||||
merged_needle.push_back(forward_needle[itr_fst]);
|
||||
itr_fst++;
|
||||
}
|
||||
else {
|
||||
merged_needle.push_back(backward_needle[itr_snd]);
|
||||
itr_snd++;
|
||||
}
|
||||
}
|
||||
while (itr_fst < forward_needle.size()) {
|
||||
merged_needle.push_back(forward_needle[itr_fst]);
|
||||
itr_fst++;
|
||||
}
|
||||
while (itr_snd < backward_needle.size()) {
|
||||
merged_needle.push_back(backward_needle[itr_snd]);
|
||||
itr_snd++;
|
||||
}
|
||||
for (unsigned int p = 0 ; p+1 < merged_needle.size() ; p++) {
|
||||
segments.push_back(Segment_2(merged_needle[p], merged_needle[p+1]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
segments.push_back(Segment_2(points[i], points[i+1]));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void visibility_region_impl(const Point_2 &q) {
|
||||
|
||||
int i = 0;
|
||||
Point_2 w;
|
||||
|
||||
if (orientation(q, vertices[0], vertices[1]) == CGAL::LEFT_TURN) {
|
||||
std::cout << "left" << std::endl;
|
||||
if (Orientation_2(q, vertices[0], vertices[1]) == CGAL::LEFT_TURN) {
|
||||
upcase = LEFT;
|
||||
i = 1;
|
||||
w = vertices[1];
|
||||
|
|
@ -283,7 +412,6 @@ protected:
|
|||
s.push(vertices[1]);
|
||||
}
|
||||
else {
|
||||
std::cout << "scana" << std::endl;
|
||||
upcase = SCANA;
|
||||
i = 1;
|
||||
w = vertices[1];
|
||||
|
|
@ -291,7 +419,6 @@ protected:
|
|||
}
|
||||
|
||||
do {
|
||||
std::cout << "CASE: " << upcase << std::endl;
|
||||
switch(upcase) {
|
||||
case LEFT:
|
||||
left(i, w, q);
|
||||
|
|
@ -315,10 +442,8 @@ protected:
|
|||
if (upcase == LEFT) {
|
||||
// Check if (s_t-1, s_t) intersects (q, vn)
|
||||
Point_2 s_t = s.top();
|
||||
std::cout << "s_t= " << s_t << std::endl;
|
||||
s.pop();
|
||||
Point_2 s_t_prev = s.top();
|
||||
std::cout << "s_t-1= " << s_t_prev << std::endl;
|
||||
Segment_2 s1(s_t_prev, s_t);
|
||||
Segment_2 s2(q, vertices[vertices.size()-1]);
|
||||
CGAL::Object result = CGAL::intersection(s1, s2);
|
||||
|
|
@ -328,13 +453,10 @@ protected:
|
|||
CGAL::Object result2 = CGAL::intersection(s3, s2);
|
||||
if (const Point_2 *vertex_new = CGAL::object_cast<Point_2>(&result2)){
|
||||
if ((*vertex_new) != (s_t_prev) && (*vertex_new != s_t)) {
|
||||
std::cout << "switch to scanb" << std::endl;
|
||||
upcase = SCANB;
|
||||
std::cout << "pushing " << *vertex_new << std::endl;
|
||||
s.push(*vertex_new);
|
||||
}
|
||||
else { // Do not alter stack if it doesn't intersect - push back s_t
|
||||
std::cout << "skipping because it is endpoint" << std::endl;
|
||||
s.push(s_t);
|
||||
}
|
||||
}
|
||||
|
|
@ -346,42 +468,36 @@ protected:
|
|||
s.push(s_t);
|
||||
}
|
||||
}
|
||||
if (i == 9) {
|
||||
// exit(0);
|
||||
}
|
||||
} while(upcase != FINISH);
|
||||
}
|
||||
|
||||
void left(int &i, Point_2 &w, const Point_2 &query_pt) {
|
||||
std::cout << "begin left with i = " << i << std::endl;
|
||||
if (i == vertices.size() - 1) {
|
||||
std::cout << "done" << std::endl;
|
||||
upcase = FINISH;
|
||||
}
|
||||
else if (orientation(query_pt, vertices[i], vertices[i+1]) == CGAL::LEFT_TURN) {
|
||||
std::cout << "left::left turn with i =" << i << std::endl;
|
||||
else if (Orientation_2(query_pt,
|
||||
vertices[i],
|
||||
vertices[i+1]) == CGAL::LEFT_TURN) {
|
||||
upcase = LEFT;
|
||||
std::cout << "left::pushing1 " << vertices[i+1] << std::endl;
|
||||
s.push(vertices[i+1]);
|
||||
w = vertices[i+1];
|
||||
i++;
|
||||
}
|
||||
else if (orientation(query_pt, vertices[i], vertices[i+1]) == CGAL::RIGHT_TURN) {
|
||||
std::cout << "left::right turn with i = " << i << std::endl;
|
||||
else if (Orientation_2(query_pt,
|
||||
vertices[i],
|
||||
vertices[i+1]) == CGAL::RIGHT_TURN) {
|
||||
Point_2 s_t = s.top();
|
||||
std::cout << "left:: s_t = " << s_t << std::endl;
|
||||
s.pop();
|
||||
Point_2 s_t_prev = s.top();
|
||||
std::cout << "left:: s_t-i = " << s_t_prev << std::endl;
|
||||
s.pop();
|
||||
if (orientation(s_t_prev, vertices[i], vertices[i+1]) == CGAL::RIGHT_TURN) {
|
||||
std::cout << "left::switched to scana" << std::endl;
|
||||
if (Orientation_2(s_t_prev,
|
||||
vertices[i],
|
||||
vertices[i+1]) == CGAL::RIGHT_TURN) {
|
||||
upcase = SCANA;
|
||||
w = vertices[i+1];
|
||||
i++;
|
||||
} // Both conditions have to be met to move on. Thus same else branch as below
|
||||
else {
|
||||
std::cout << "left::switching to right mode branch1" << std::endl;
|
||||
upcase = RIGHT;
|
||||
w = vertices[i];
|
||||
i++;
|
||||
|
|
@ -390,12 +506,10 @@ protected:
|
|||
s.push(s_t);
|
||||
}
|
||||
else {
|
||||
std::cout << "left::switching to right mode" << std::endl;
|
||||
upcase = RIGHT;
|
||||
i++;
|
||||
w = vertices[i];
|
||||
}
|
||||
std::cout << "leaving left with i = " << i << std::endl;
|
||||
}
|
||||
|
||||
void right(int &i, Point_2 &w, const Point_2 &query_pt) {
|
||||
|
|
@ -403,38 +517,40 @@ protected:
|
|||
// (a) (z, s_j, v_i) is a right turn and (z, s_j-1, v_i) is a left turn, or
|
||||
// (b) (z, s_j-1, s_j) is a forward move and (v_i-1, v_i) intersects (s_j-1, s_j)
|
||||
bool found = false;
|
||||
std::cout << "entered right with i = " << i << std::endl;
|
||||
while(!found && !s.empty()) {
|
||||
Point_2 s_j = s.top();
|
||||
std::cout << "right:: considering s_j = " << s_j << std::endl;
|
||||
s.pop();
|
||||
if (!s.empty()) {
|
||||
Point_2 s_j_prev = s.top();
|
||||
std::cout << "right:: s_j-1 = " << s_j_prev << std::endl;
|
||||
|
||||
// Check condition (a)
|
||||
if ((orientation(query_pt, s_j, vertices[i]) == CGAL::RIGHT_TURN)
|
||||
&& (orientation(query_pt, s_j_prev, vertices[i]) == CGAL::LEFT_TURN)) {
|
||||
std::cout << "right:: case A" << std::endl;
|
||||
if ((Orientation_2(query_pt,
|
||||
s_j,
|
||||
vertices[i]) == CGAL::RIGHT_TURN) &&
|
||||
(Orientation_2(query_pt,
|
||||
s_j_prev,
|
||||
vertices[i]) == CGAL::LEFT_TURN)) {
|
||||
found = true;
|
||||
Segment_2 s1(s_j_prev, s_j);
|
||||
Ray_2 s2(query_pt, vertices[i]);
|
||||
CGAL::Object result = intersection(s1, s2);
|
||||
CGAL::Object result = CGAL::intersection(s1, s2);
|
||||
if (const Point_2 *ipoint = CGAL::object_cast<Point_2>(&result)) {
|
||||
std::cout << "s_j is now = " << *ipoint << std::endl;
|
||||
s_j = *ipoint;
|
||||
}
|
||||
|
||||
if (orientation(query_pt, vertices[i], vertices[i+1]) == CGAL::RIGHT_TURN) {
|
||||
std::cout << "case a1" << std::endl;
|
||||
if (Orientation_2(query_pt,
|
||||
vertices[i],
|
||||
vertices[i+1]) == CGAL::RIGHT_TURN) {
|
||||
upcase = RIGHT;
|
||||
s.push(s_j);
|
||||
w = vertices[i];
|
||||
i++;
|
||||
}
|
||||
else if ((orientation(query_pt, vertices[i], vertices[i+1]) == CGAL::LEFT_TURN)
|
||||
&& (orientation(vertices[i-1], vertices[i], vertices[i+1]) == CGAL::RIGHT_TURN)) {
|
||||
std::cout << "case a2: right::switch to left" << std::endl;
|
||||
else if ((Orientation_2(query_pt,
|
||||
vertices[i],
|
||||
vertices[i+1]) == CGAL::LEFT_TURN) &&
|
||||
(Orientation_2(vertices[i-1],
|
||||
vertices[i],
|
||||
vertices[i+1]) == CGAL::RIGHT_TURN)) {
|
||||
upcase = LEFT;
|
||||
s.push(s_j);
|
||||
s.push(vertices[i]);
|
||||
|
|
@ -443,7 +559,6 @@ protected:
|
|||
i++;
|
||||
}
|
||||
else {
|
||||
std::cout << "case a3" << std::endl;
|
||||
upcase = SCANC;
|
||||
s.push(s_j);
|
||||
w = vertices[i];
|
||||
|
|
@ -454,31 +569,29 @@ protected:
|
|||
// Check if v_i-1, v_i intersects (s_j-1, s_j)
|
||||
Segment_2 s1(s_j_prev, s_j);
|
||||
Segment_2 s2(vertices[i-1], vertices[i]);
|
||||
CGAL::Object result = intersection(s1, s2);
|
||||
CGAL::Object result = CGAL::intersection(s1, s2);
|
||||
if (const Point_2 *ipoint = CGAL::object_cast<Point_2>(&result)) {
|
||||
// Keep s_j off the stack
|
||||
std::cout << "right:: case B" << std::endl;
|
||||
found = true;
|
||||
upcase = SCAND;
|
||||
w = *ipoint;
|
||||
}
|
||||
}
|
||||
else if ((orientation(query_pt, s_j, vertices[i]) == CGAL::RIGHT_TURN)
|
||||
&& (orientation(query_pt, s_j_prev, vertices[i]) == CGAL::COLLINEAR)) {
|
||||
std::cout << "we're here in collinear" << std::endl;
|
||||
else if ((Orientation_2(query_pt,
|
||||
s_j,
|
||||
vertices[i]) == CGAL::RIGHT_TURN) &&
|
||||
(Orientation_2(query_pt,
|
||||
s_j_prev,
|
||||
vertices[i]) == CGAL::COLLINEAR)) {
|
||||
found = true;
|
||||
upcase = LEFT;
|
||||
std::cout << "right::pushing " << vertices[i] << std::endl;
|
||||
std::cout << "right::pushing " << vertices[i+1] << std::endl;
|
||||
s.push(vertices[i]);
|
||||
s.push(vertices[i+1]);
|
||||
w = vertices[i+1];
|
||||
i++;
|
||||
}
|
||||
std::cout << "right::FOUND? = " << found << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "leaving right with i = " << i << std::endl;
|
||||
}
|
||||
|
||||
void scana(int &i, Point_2 &w, const Point_2 &query_pt) {
|
||||
|
|
@ -487,50 +600,49 @@ protected:
|
|||
int k = i;
|
||||
Point_2 intersection_pt;
|
||||
while (k+1 < vertices.size()) {
|
||||
std::cout << "Considering edge: " << vertices[k] << " " << vertices[k+1] << std::endl;
|
||||
Segment_2 s1(vertices[k], vertices[k+1]);
|
||||
std::cout << "With edge: " << query_pt << " " << s.top() << std::endl;
|
||||
Ray_2 s2(query_pt, s.top());
|
||||
CGAL::Object result = intersection(s1, s2);
|
||||
if (const Point_2 *ipoint = CGAL::object_cast<Point_2>(&result)) {
|
||||
found = true;
|
||||
std::cout << " found edge!" << std::endl;
|
||||
intersection_pt = *ipoint;
|
||||
std::cout << intersection_pt << std::endl;
|
||||
break;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
if (found) {
|
||||
if ((orientation(query_pt, vertices[k], vertices[k+1]) == CGAL::RIGHT_TURN)
|
||||
&& (!do_overlap(query_pt, s.top(), intersection_pt))) {
|
||||
std::cout << "if1" << std::endl;
|
||||
if ((Orientation_2(query_pt,
|
||||
vertices[k],
|
||||
vertices[k+1]) == CGAL::RIGHT_TURN) &&
|
||||
(!do_overlap(query_pt, s.top(), intersection_pt))) {
|
||||
|
||||
upcase = RIGHT;
|
||||
i = k+1;
|
||||
w = intersection_pt;
|
||||
}
|
||||
else if ((orientation(query_pt, vertices[k], vertices[k+1]) == CGAL::RIGHT_TURN)
|
||||
&& (do_overlap(query_pt, s.top(), intersection_pt))) {
|
||||
std::cout << "elseif1" << std::endl;
|
||||
else if ((Orientation_2(query_pt,
|
||||
vertices[k],
|
||||
vertices[k+1]) == CGAL::RIGHT_TURN) &&
|
||||
(do_overlap(query_pt, s.top(), intersection_pt))) {
|
||||
|
||||
upcase = SCAND;
|
||||
i = k+1;
|
||||
w = intersection_pt;
|
||||
}
|
||||
else if ((orientation(query_pt, vertices[k], vertices[k+1]) == CGAL::LEFT_TURN)
|
||||
&& (do_overlap(query_pt, s.top(), intersection_pt))) {
|
||||
std::cout << "elseif2" << std::endl;
|
||||
else if ((Orientation_2(query_pt,
|
||||
vertices[k],
|
||||
vertices[k+1]) == CGAL::LEFT_TURN) &&
|
||||
(do_overlap(query_pt, s.top(), intersection_pt))) {
|
||||
|
||||
upcase = LEFT;
|
||||
i = k+1;
|
||||
s.push(intersection_pt);
|
||||
std::cout << "scana::pushing " << intersection_pt << std::endl;
|
||||
if (intersection_pt != vertices[k+1]) {
|
||||
std::cout << "scana::pushing " << vertices[k+1] << std::endl;
|
||||
s.push(vertices[k+1]);
|
||||
}
|
||||
w = vertices[k+1];
|
||||
}
|
||||
else {
|
||||
std::cout << "should never occur" << std::endl;
|
||||
// This case never occurs
|
||||
}
|
||||
}
|
||||
|
|
@ -545,7 +657,7 @@ protected:
|
|||
while (k+1 < vertices.size()) {
|
||||
Segment_2 s1(vertices[k], vertices[k+1]);
|
||||
Segment_2 s2(s_t, vertices[vertices.size()-1]);
|
||||
CGAL::Object result = intersection(s1, s2);
|
||||
CGAL::Object result = CGAL::intersection(s1, s2);
|
||||
if (const Point_2 *ipoint = CGAL::object_cast<Point_2>(&result)) {
|
||||
if (*ipoint != s_t) {
|
||||
intersection_pt = *ipoint;
|
||||
|
|
@ -556,8 +668,9 @@ protected:
|
|||
k++;
|
||||
}
|
||||
if (found) {
|
||||
if ((intersection_pt == vertices[k+1]) && (intersection_pt == vertices[vertices.size()-1])) {
|
||||
std::cout << "scanb::done\n";
|
||||
if ((intersection_pt == vertices[k+1]) &&
|
||||
(intersection_pt == vertices[vertices.size()-1])) {
|
||||
|
||||
upcase = FINISH;
|
||||
w = vertices[vertices.size()-1];
|
||||
s.push(vertices[vertices.size()-1]);
|
||||
|
|
@ -576,20 +689,16 @@ protected:
|
|||
|
||||
void scanc(int &i,Point_2 &w, const Point_2 &query_pt) {
|
||||
// Scan v_i, v_i+1, ..., v_n-1, v_n for the first edge to intersect (s_t, w)
|
||||
std::cout << "entered scanc with i = " << i << std::endl;
|
||||
Point_2 s_t = s.top();
|
||||
int k = i;
|
||||
bool found = false;
|
||||
Point_2 intersection_pt;
|
||||
std::cout << "size: " << vertices.size() << std::endl;
|
||||
while (k+1 < vertices.size()) {
|
||||
std::cout << "doesn't get here" << std::endl;
|
||||
Segment_2 s1(vertices[k], vertices[k+1]);
|
||||
Segment_2 s2(s_t, w);
|
||||
CGAL::Object result = intersection(s1, s2);
|
||||
CGAL::Object result = CGAL::intersection(s1, s2);
|
||||
if (const Point_2 *ipoint = CGAL::object_cast<Point_2>(&result)) {
|
||||
found = true;
|
||||
std::cout << "scanc::found" << std::endl;
|
||||
intersection_pt = *ipoint;
|
||||
break;
|
||||
}
|
||||
|
|
@ -600,7 +709,6 @@ protected:
|
|||
i = k+1;
|
||||
w = intersection_pt;
|
||||
}
|
||||
std::cout << "leaving scanc" << std::endl;
|
||||
}
|
||||
|
||||
void scand(int &i, Point_2 &w, const Point_2 &query_pt) {
|
||||
|
|
@ -612,7 +720,7 @@ protected:
|
|||
while (k+1 < vertices.size()) {
|
||||
Segment_2 s1(vertices[k], vertices[k+1]);
|
||||
Segment_2 s2(s_t, w);
|
||||
CGAL::Object result = intersection(s1, s2);
|
||||
CGAL::Object result = CGAL::intersection(s1, s2);
|
||||
if (const Point_2 *ipoint = CGAL::object_cast<Point_2>(&result)) {
|
||||
found = true;
|
||||
intersection_pt = *ipoint;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
# Test case 4 for simple polygons. See https://cgal.geometryfactory.com/CGAL/Members/wiki/Visibility/TestCases
|
||||
7
|
||||
6
|
||||
0 0
|
||||
4 0
|
||||
8 3
|
||||
12 3
|
||||
4 3
|
||||
2 3
|
||||
0 3
|
||||
7
|
||||
6
|
||||
0 1
|
||||
1 2
|
||||
2 3
|
||||
2 4
|
||||
4 5
|
||||
5 6
|
||||
6 0
|
||||
5 0
|
||||
|
|
@ -47,20 +47,20 @@ int main() {
|
|||
Arrangement_2 arr;
|
||||
std::ifstream input("./data/simple_polygon_test_case_1.in");
|
||||
CGAL::create_arrangement_from_file<Arrangement_2>(arr, input);
|
||||
CGAL::Visibility_2::Simple_visibility_2<Arrangement_2> visibility;
|
||||
assert(false == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2> >(visibility)));
|
||||
CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false> visibility;
|
||||
assert(false == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false> >(visibility)));
|
||||
visibility.attach(arr);
|
||||
assert(true == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2> >(visibility)));
|
||||
assert(true == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false> >(visibility)));
|
||||
visibility.detach();
|
||||
assert(false == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2> >(visibility)));
|
||||
assert(false == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false> >(visibility)));
|
||||
visibility.attach(arr);
|
||||
assert(true == (CGAL::test_are_equal<Arrangement_2>(arr, visibility.arr())));
|
||||
|
||||
// Run test cases from https://cgal.geometryfactory.com/CGAL/Members/wiki/Visibility/TestCases
|
||||
assert(true == (CGAL::simple_polygon_test_case_1<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2>, Arrangement_2> ()));
|
||||
// assert(true == (CGAL::simple_polygon_test_case_2<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2>, Arrangement_2> ()));
|
||||
// assert(true == (CGAL::simple_polygon_test_case_3<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2>, Arrangement_2> ()));
|
||||
// assert(true == (CGAL::simple_polygon_test_case_4<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2>, Arrangement_2> ()));
|
||||
assert(true == (CGAL::simple_polygon_test_case_1<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false>, Arrangement_2> ()));
|
||||
assert(true == (CGAL::simple_polygon_test_case_2<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false>, Arrangement_2> ()));
|
||||
assert(true == (CGAL::simple_polygon_test_case_3<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false>, Arrangement_2> ()));
|
||||
assert(true == (CGAL::simple_polygon_test_case_4<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false>, Arrangement_2> ()));
|
||||
}
|
||||
{
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
|
||||
|
|
@ -73,19 +73,20 @@ int main() {
|
|||
Arrangement_2 arr;
|
||||
std::ifstream input("./data/simple_polygon_test_case_1.in");
|
||||
CGAL::create_arrangement_from_file<Arrangement_2>(arr, input);
|
||||
CGAL::Visibility_2::Simple_visibility_2<Arrangement_2> visibility;
|
||||
assert(false == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2> >(visibility)));
|
||||
CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false> visibility;
|
||||
assert(false == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false> >(visibility)));
|
||||
visibility.attach(arr);
|
||||
assert(true == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2> >(visibility)));
|
||||
assert(true == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false> >(visibility)));
|
||||
visibility.detach();
|
||||
assert(false == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2> >(visibility)));
|
||||
assert(false == (CGAL::test_is_attached<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false> >(visibility)));
|
||||
visibility.attach(arr);
|
||||
assert(true == (CGAL::test_are_equal<Arrangement_2>(arr, visibility.arr())));
|
||||
|
||||
// Run test cases from https://cgal.geometryfactory.com/CGAL/Members/wiki/Visibility/TestCases
|
||||
assert(true == (CGAL::simple_polygon_test_case_1<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2>, Arrangement_2> ()));
|
||||
/* assert(true == (CGAL::simple_polygon_test_case_2<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2>, Arrangement_2> ()));
|
||||
assert(true == (CGAL::simple_polygon_test_case_3<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2>, Arrangement_2> ()));*/
|
||||
assert(true == (CGAL::simple_polygon_test_case_1<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false>, Arrangement_2> ()));
|
||||
assert(true == (CGAL::simple_polygon_test_case_2<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false>, Arrangement_2> ()));
|
||||
assert(true == (CGAL::simple_polygon_test_case_3<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false>, Arrangement_2> ()));
|
||||
assert(true == (CGAL::simple_polygon_test_case_4<CGAL::Visibility_2::Simple_visibility_2<Arrangement_2, CGAL::Tag_false>, Arrangement_2> ()));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue