集合的可动可分性是处理物体移动集合的问题,如平面上的多边形,在考虑不同类型的运动和不同的分离定义时,如何避免物体之间的碰撞是一个难题.注塑行业就面临这样的实际问题,如何设计模具腔体,才能让避免完好无损的取出产产品且不损坏模具。
CGAL就提供里这样的工具:CGAL::Set_movable_separability_2::Single_mold_translational_casting
该类包含如下几个关键函数,方便处理2D注塑类问题:top_edges() pullout_directions() is_pullout_direction()
.
top_edges()可以求出2D多边形的开口边及对应的拉取方向,如下图所示,前两张图所示多边形存在top_edges(即可以设计相似形状的模具腔体),拉出方向如箭头所示。后两张图所示多边形不存在top_edges,也就是说这样的多边形不能做模具腔体,因为无论从哪个方向都不能将产品从腔体拉出,除非破坏模具。
具体代码如下所示:
#include <list>
#include <fstream>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Set_movable_separability_2/Single_mold_translational_casting/top_edges.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
typedef Kernel::Direction_2 Direction_2;
typedef Kernel::Vector_2 Vector_2;
typedef Kernel::Point_2 Point_2;
// A direction range is a closed range of directions on the unit circle.
typedef std::pair<Direction_2, Direction_2> Direction_range;
typedef Polygon_2::Edge_const_iterator Edge_iter;
// A top edge is identified by the index to an edge of a polygon and the
// corresponding range of pullout directions.
typedef std::pair<Edge_iter, Direction_range> Top_edge;
namespace SMS = CGAL::Set_movable_separability_2;
namespace casting = SMS::Single_mold_translational_casting;
// The main program:
int main(int argc, char* argv[])
{
Polygon_2 polygon;
polygon.push_back(Point_2(0, 0));
polygon.push_back(Point_2(1, 0));
polygon.push_back(Point_2(1, 1));
polygon.push_back(Point_2(0, 1));
std::list<Top_edge> top_edges;
// Example for top_edges_single_mold_translational_casting_2
casting::top_edges(polygon, std::back_inserter(top_edges));
if (top_edges.empty())
std::cout << "The polygon is not castable!" << std::endl;
else {
std::cout << "There are " << top_edges.size() << " top edges:" << std::endl;
for (const auto& top_edge : top_edges) {
std::cout
<< "\tEdge: " << *top_edge.first<< std::endl
<< "\tPullout directions from: " << top_edge.second.first
<< " to " << top_edge.second.second
<< std::endl << std::endl;
}
}
return 0;
}
pullout_directions()接受一个简单的闭合多边形P和多边形P的边e,确定e是否是P的top_edge,如果是,它计算e的拉出方向范围
is_pullout_direction()重载了两个版本:第一个版本接受一个简单的闭合多边形P和一个方向d,确定d是否是P的某个top_edge的拉出方向;另一个版本接受多边形P的边缘e,它确定d是否是e的拉出方向。