mirror of https://github.com/CGAL/cgal
Fixed arrangement basic drawing code
This commit is contained in:
parent
151132c88e
commit
986746b1dd
|
|
@ -27,6 +27,8 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <boost/math/special_functions/ellint_2.hpp>
|
||||||
|
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Cartesian.h>
|
||||||
#include <CGAL/tags.h>
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/Arr_tags.h>
|
#include <CGAL/Arr_tags.h>
|
||||||
|
|
@ -642,6 +644,10 @@ public:
|
||||||
*oi++ = Approximate_point_2(xt, yt);
|
*oi++ = Approximate_point_2(xt, yt);
|
||||||
return oi;
|
return oi;
|
||||||
}
|
}
|
||||||
|
if (arc.orientation() == CLOCKWISE) {
|
||||||
|
std::swap(xs, xt);
|
||||||
|
std::swap(ys, yt);
|
||||||
|
}
|
||||||
auto r = CGAL::to_double(arc.r());
|
auto r = CGAL::to_double(arc.r());
|
||||||
auto s = CGAL::to_double(arc.s());
|
auto s = CGAL::to_double(arc.s());
|
||||||
auto t = CGAL::to_double(arc.t());
|
auto t = CGAL::to_double(arc.t());
|
||||||
|
|
@ -650,6 +656,9 @@ public:
|
||||||
auto w = CGAL::to_double(arc.w());
|
auto w = CGAL::to_double(arc.w());
|
||||||
std::cout << r << "," << s << "," << t << "," << u << "," << v << "," << w
|
std::cout << r << "," << s << "," << t << "," << u << "," << v << "," << w
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
std::cout << "curve: (" << xs << "," << ys
|
||||||
|
<< ") => (" << xt << "," << yt << ")"
|
||||||
|
<< std::endl;
|
||||||
{
|
{
|
||||||
// Compute the cos and sin of the rotation angle
|
// Compute the cos and sin of the rotation angle
|
||||||
// In case of a circle, cost == 1 and sint = 0
|
// In case of a circle, cost == 1 and sint = 0
|
||||||
|
|
@ -695,15 +704,30 @@ public:
|
||||||
auto xds = xs - cx;
|
auto xds = xs - cx;
|
||||||
auto yds = ys - cy;
|
auto yds = ys - cy;
|
||||||
auto ts = std::atan2(a*(cost*yds - sint*xds),b*(sint*yds + cost*xds));
|
auto ts = std::atan2(a*(cost*yds - sint*xds),b*(sint*yds + cost*xds));
|
||||||
|
if (ts < 0) ts += 2*M_PI;
|
||||||
auto xdt = xt - cx;
|
auto xdt = xt - cx;
|
||||||
auto ydt = yt - cy;
|
auto ydt = yt - cy;
|
||||||
auto tt = std::atan2(a*(cost*ydt - sint*xdt),b*(sint*ydt + cost*xdt));
|
auto tt = std::atan2(a*(cost*ydt - sint*xdt),b*(sint*ydt + cost*xdt));
|
||||||
|
std::cout << "xdt, ydt, tt: " << xdt << "," << ydt << ", " << tt << std::endl;
|
||||||
|
if (tt < 0) tt += 2*M_PI;
|
||||||
|
std::cout << "ts,tt: " << ts << "," << tt << std::endl;
|
||||||
|
|
||||||
auto delta = std::abs(tt - ts) / (size-1);
|
namespace bm = boost::math;
|
||||||
double t((arc.orientation() == COUNTERCLOCKWISE) ? ts : tt);
|
auto ratio = b/a;
|
||||||
|
auto k = 1 - (ratio*ratio);
|
||||||
|
auto ps = std::atan2(b*std::tan(ts), a);
|
||||||
|
if (ps < 0) ps += 2*M_PI;
|
||||||
|
auto ds = a*bm::ellint_2(k, ps);
|
||||||
|
auto pt = std::atan2(b*std::tan(tt), a);
|
||||||
|
if (pt < 0) pt += 2*M_PI;
|
||||||
|
auto dt = a*bm::ellint_2(k, pt);
|
||||||
|
std::cout << "ps,pt: " << ps << ", " << pt << std::endl;
|
||||||
|
std::cout << "ds,dt: " << ds << ", " << dt << std::endl;
|
||||||
|
|
||||||
*oi++ = (arc.orientation() == COUNTERCLOCKWISE) ?
|
if (tt < ts) tt += 2*M_PI;
|
||||||
Approximate_point_2(xs, ys) : Approximate_point_2(xt, yt);
|
auto delta = (tt - ts) / (size-1);
|
||||||
|
auto t(ts);
|
||||||
|
*oi++ = Approximate_point_2(xs, ys);
|
||||||
t += delta;
|
t += delta;
|
||||||
for (size_t i = 1; i < size-1; ++i) {
|
for (size_t i = 1; i < size-1; ++i) {
|
||||||
auto x = a*std::cos(t)*cost - b*std::sin(t)*sint + cx;
|
auto x = a*std::cos(t)*cost - b*std::sin(t)*sint + cx;
|
||||||
|
|
@ -713,8 +737,7 @@ public:
|
||||||
*oi++ = Approximate_point_2(x, y);
|
*oi++ = Approximate_point_2(x, y);
|
||||||
t += delta;
|
t += delta;
|
||||||
}
|
}
|
||||||
*oi++ = (arc.orientation() == COUNTERCLOCKWISE) ?
|
*oi++ = Approximate_point_2(xt, yt);
|
||||||
Approximate_point_2(xt, yt) : Approximate_point_2(xs, ys);
|
|
||||||
}
|
}
|
||||||
return oi;
|
return oi;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef CGAL_DRAW_ARRANGEMENT_2_H
|
#ifndef CGAL_DRAW_ARRANGEMENT_2_H
|
||||||
#define CGAL_DRAW_ARRANGEMENT_2_H
|
#define CGAL_DRAW_ARRANGEMENT_2_H
|
||||||
|
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <CGAL/Qt/Basic_viewer_qt.h>
|
#include <CGAL/Qt/Basic_viewer_qt.h>
|
||||||
#include <CGAL/Qt/init_ogl_context.h>
|
#include <CGAL/Qt/init_ogl_context.h>
|
||||||
|
|
@ -42,8 +42,12 @@ public:
|
||||||
for (auto it = m_arr.unbounded_faces_begin();
|
for (auto it = m_arr.unbounded_faces_begin();
|
||||||
it != m_arr.unbounded_faces_end(); ++it)
|
it != m_arr.unbounded_faces_end(); ++it)
|
||||||
add_face(it, c);
|
add_face(it, c);
|
||||||
|
|
||||||
|
// Add edges that do not separe faces.
|
||||||
for (auto it = m_arr.edges_begin(); it != m_arr.edges_end(); ++it)
|
for (auto it = m_arr.edges_begin(); it != m_arr.edges_end(); ++it)
|
||||||
add_edge(it);
|
if (it->face() == it->twin()->face()) add_edge(it);
|
||||||
|
|
||||||
|
// Add all points
|
||||||
for (auto it = m_arr.vertices_begin(); it != m_arr.vertices_end(); ++it)
|
for (auto it = m_arr.vertices_begin(); it != m_arr.vertices_end(); ++it)
|
||||||
add_vertex(it);
|
add_vertex(it);
|
||||||
}
|
}
|
||||||
|
|
@ -51,10 +55,11 @@ public:
|
||||||
protected:
|
protected:
|
||||||
//!
|
//!
|
||||||
virtual void add_ccb(Ccb_halfedge_const_circulator circ) {
|
virtual void add_ccb(Ccb_halfedge_const_circulator circ) {
|
||||||
std::cout << "1 add_ccb\n";
|
auto curr = circ;
|
||||||
typename Arr::Ccb_halfedge_const_circulator curr = circ;
|
do {
|
||||||
do this->add_point_in_face(curr->source()->point());
|
this->add_point_in_face(curr->source()->point());
|
||||||
while (++curr != circ);
|
add_edge(curr);
|
||||||
|
} while (++curr != circ);
|
||||||
}
|
}
|
||||||
|
|
||||||
//!
|
//!
|
||||||
|
|
@ -78,7 +83,7 @@ protected:
|
||||||
|
|
||||||
for (auto it = face->inner_ccbs_begin(); it != face->inner_ccbs_end(); ++it)
|
for (auto it = face->inner_ccbs_begin(); it != face->inner_ccbs_end(); ++it)
|
||||||
{
|
{
|
||||||
std::map<Face_const_handle, bool> visited;
|
std::unordered_map<Face_const_handle, bool> visited;
|
||||||
auto curr = *it;
|
auto curr = *it;
|
||||||
do {
|
do {
|
||||||
auto new_face = curr->twin()->face();
|
auto new_face = curr->twin()->face();
|
||||||
|
|
@ -163,12 +168,55 @@ public:
|
||||||
virtual void add_ccb(Ccb_halfedge_const_circulator circ) {
|
virtual void add_ccb(Ccb_halfedge_const_circulator circ) {
|
||||||
const auto* traits = this->m_arr.geometry_traits();
|
const auto* traits = this->m_arr.geometry_traits();
|
||||||
auto approx = traits->approximate_2_object();
|
auto approx = traits->approximate_2_object();
|
||||||
typename Arr::Ccb_halfedge_const_circulator curr = circ;
|
auto cmp_xy = traits->compare_xy_2_object();
|
||||||
|
auto cmp_y = traits->compare_y_at_x_right_2_object();
|
||||||
|
|
||||||
|
// Find the first halfedge directed from left to right
|
||||||
|
auto curr = circ;
|
||||||
|
do if (curr->direction() == CGAL::ARR_LEFT_TO_RIGHT) break;
|
||||||
|
while (++curr != circ);
|
||||||
|
Halfedge_const_handle ext = curr;
|
||||||
|
|
||||||
|
// Find the halfedge incident to the lexicographically smallest vertex,
|
||||||
|
// such that there is no other halfedge underneath.
|
||||||
do {
|
do {
|
||||||
|
// Discard edges not directed from left to right:
|
||||||
|
if (curr->direction() != CGAL::ARR_LEFT_TO_RIGHT) continue;
|
||||||
|
|
||||||
|
|
||||||
|
auto res = cmp_xy(curr->source()->point(), ext->source()->point());
|
||||||
|
|
||||||
|
// Discard the edges inciden to a point strictly larger than the point
|
||||||
|
// incident to the stored extreme halfedge:
|
||||||
|
if (res == LARGER) continue;
|
||||||
|
|
||||||
|
// Store the edge inciden to a point strictly smaller:
|
||||||
|
if (res == SMALLER) {
|
||||||
|
ext = curr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The incident points are equal; compare the halfedges themselves:
|
||||||
|
if (cmp_y(curr->curve(), ext->curve(), curr->source()->point()) ==
|
||||||
|
SMALLER)
|
||||||
|
ext = curr;
|
||||||
|
} while (++curr != circ);
|
||||||
|
|
||||||
|
// Iterate, starting from the lexicographically smallest vertex
|
||||||
|
curr = ext;
|
||||||
|
do {
|
||||||
|
while (curr->face() == curr->twin()->face())
|
||||||
|
curr = curr->twin()->next();
|
||||||
std::vector<typename Gt::Approximate_point_2> polyline;
|
std::vector<typename Gt::Approximate_point_2> polyline;
|
||||||
approx(curr->curve(), 10, std::back_inserter(polyline));
|
approx(curr->curve(), 10, std::back_inserter(polyline));
|
||||||
for (const auto& p : polyline) this->add_point_in_face(p);
|
auto it = polyline.begin();
|
||||||
} while (++curr != circ);
|
auto prev = it++;
|
||||||
|
for (; it != polyline.end(); prev = it++) {
|
||||||
|
this->add_segment(*prev, *it);
|
||||||
|
this->add_point_in_face(*prev);
|
||||||
|
}
|
||||||
|
curr = curr->next();
|
||||||
|
} while (curr != ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
//!
|
//!
|
||||||
|
|
@ -180,8 +228,7 @@ public:
|
||||||
|
|
||||||
auto it = polyline.begin();
|
auto it = polyline.begin();
|
||||||
auto prev = it++;
|
auto prev = it++;
|
||||||
for (; it != polyline.end(); prev = it++)
|
for (; it != polyline.end(); prev = it++) this->add_segment(*prev, *it);
|
||||||
this->add_segment(*prev, *it);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue