void LayerTriangulation::triangulate1(int layer0, int layer1, const std::vector<Point2D> &points) { std::vector<int> &idx0 = layers[layer0]; std::vector<int> &idx1 = layers[layer1]; int point0 = lowest[layer0], point1 = 0; real min_dist = distance(points[idx0[point0]], points[idx1[point1]]); for (int index = 1; index < idx1.size(); ++index) { real dist = distance(points[idx0[point0]], points[idx1[index]]); if (dist < min_dist) { point1 = index; min_dist = dist; } } int end0 = point0, end1 = point1; do { edges.push_back(std::make_pair(idx0[point0], idx1[point1])); int next0 = (point0 + 1) % idx0.size(), next1 = (point1 + 1) % idx1.size(); if ((point0 == end0 && next1 == end1 && idx1.size() > 1) || (point1 == end1 && next0 == end0)) break; if (!is_ccw(points[idx0[point0]], points[idx1[point1]], points[idx1[next1]])) { // Check if we can build next triangle if (!is_ccw(points[idx0[next0]], points[idx1[point1]], points[idx1[next1]])) { // Check triangle with minimum angle real angle0 = std::min(min_angle(points[idx0[point0]], points[idx1[point1]], points[idx1[next1]]), min_angle(points[idx0[point0]], points[idx1[next1]], points[idx0[next0]])); real angle1 = std::min(min_angle(points[idx0[point0]], points[idx0[next0]], points[idx1[point1]]), min_angle(points[idx0[next0]], points[idx1[next1]], points[idx1[point1]])); if (angle0 > angle1) { point1 = next1; } else { point0 = next0; } } else { point1 = next1; } } else { point0 = next0; } } while (point0 != end0 || point1 != end1); }
void LayerTriangulation::grahamScan0(const std::vector<int> &indices, const std::vector<Point2D> &points, std::vector<int> &inner) { if (indices.size() == 0) return; layers.push_back(std::vector<int>()); std::vector<int> &layer = layers.back(); if (indices.size() < 3) { for (int index : indices) layer.push_back(index); } else if (indices.size() == 3) { layer.push_back(indices[0]); layer.push_back(indices[1]); layer.push_back(indices[2]); } else { std::vector<bool> mask(indices.size(), false); layer.reserve(indices.size()); layer.push_back(0); layer.push_back(1); layer.push_back(2); for (size_t index = 3; index < indices.size(); ++index) { int prev_index = layer.back(); layer.pop_back(); while (!is_ccw(points[indices[layer.back()]], points[indices[prev_index]], points[indices[index]])) { mask[prev_index] = true; prev_index = layer.back(); layer.pop_back(); } layer.push_back(prev_index); layer.push_back(index); } for (size_t index = 0; index < layer.size(); ++index) { layer[index] = indices[layer[index]]; } inner.push_back(indices[0]); for (size_t index = 0; index < mask.size(); ++index) { if (mask[index]) inner.push_back(indices[index]); } } }
void LayerTriangulation::triangulate0(int layer0, int layer1, const std::vector<Point2D> &points) { int point0 = lowest[layer0]; int point1 = lowest[layer1]; std::vector<int> &idx0 = layers[layer0]; std::vector<int> &idx1 = layers[layer1]; do { edges.push_back(std::make_pair(idx0[point0], idx1[point1])); if (!is_ccw(points[idx0[point0]], points[idx1[point1]], points[idx1[(point1 + 1) % idx1.size()]])) { point1 = (point1 + 1) % idx1.size(); } else { point0 = (point0 + 1) % idx0.size(); } } while (point0 != lowest[layer0] || point1 != lowest[layer1]); }
//------------------------------------------------------------------------ void vcgen_contour::rewind(unsigned) { if(m_status == initial) { m_src_vertices.close(true); if(m_auto_detect) { if(!is_oriented(m_orientation)) { m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ? path_flags_ccw : path_flags_cw; } } if(is_oriented(m_orientation)) { m_stroker.width(is_ccw(m_orientation) ? m_width : -m_width); } } m_status = ready; m_src_vertex = 0; }
void LayerTriangulation::grahamScan1(const std::vector<int> &indices, const std::vector<Point2D> &points, std::vector<int> &inner) { if (indices.size() <= 1) return; layers.push_back(std::vector<int>()); std::vector<int> &layer = layers.back(); if (indices.size() < 4) { for (size_t index = 1; index < indices.size(); ++index) { layer.push_back(indices[index]); } } else if (indices.size() == 4) { if (is_ccw(points[indices[1]], points[indices[2]], points[indices[3]])) { layer.push_back(indices[1]); layer.push_back(indices[2]); layer.push_back(indices[3]); } else { layer.push_back(indices[1]); layer.push_back(indices[3]); layer.push_back(indices[2]); } } else { std::deque<int> hull; std::vector<bool> mask(indices.size(), false); hull.push_back(0); hull.push_back(1); hull.push_back(2); for (size_t index = 3; index < indices.size(); ++index) { int prev_index = hull.back(); hull.pop_back(); while (!is_ccw(points[indices[hull.back()]], points[indices[prev_index]], points[indices[index]])) { mask[prev_index] = true; prev_index = hull.back(); hull.pop_back(); } hull.push_back(prev_index); hull.push_back(index); } mask[1] = true; hull.pop_front(); for (int index = (int)indices.size() - 1; index > 0; --index) { if (mask[index]) { int prev_index = hull.back(); hull.pop_back(); while (!is_ccw(points[indices[hull.back()]], points[indices[prev_index]], points[indices[index]])) { mask[prev_index] = true; prev_index = hull.back(); hull.pop_back(); } mask[prev_index] = false; mask[index] = false; hull.push_back(prev_index); hull.push_back(index); } } mask[1] = false; hull.pop_back(); for (auto it = hull.begin(); it != hull.end(); ++it) { layer.push_back(indices[*it]); } inner.push_back(indices[0]); for (size_t index = 0; index < mask.size(); ++index) { if (mask[index]) inner.push_back(indices[index]); } } }