void get_path_extents(PathIterator& path, const agg::trans_affine& trans, double* x0, double* y0, double* x1, double* y1, double* xm, double* ym) { typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> nan_removed_t; typedef agg::conv_curve<nan_removed_t> curve_t; double x, y; unsigned code; transformed_path_t tpath(path, trans); nan_removed_t nan_removed(tpath, true, path.has_curves()); curve_t curved_path(nan_removed); curved_path.rewind(0); while ((code = curved_path.vertex(&x, &y)) != agg::path_cmd_stop) { if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) { continue; } if (x < *x0) *x0 = x; if (y < *y0) *y0 = y; if (x > *x1) *x1 = x; if (y > *y1) *y1 = y; /* xm and ym are the minimum positive values in the data, used by log scaling */ if (x > 0.0 && x < *xm) *xm = x; if (y > 0.0 && y < *ym) *ym = y; } }
bool path_in_path(PathIterator& a, const agg::trans_affine& atrans, PathIterator& b, const agg::trans_affine& btrans) { typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> no_nans_t; typedef agg::conv_curve<no_nans_t> curve_t; if (a.total_vertices() < 3) return false; transformed_path_t b_path_trans(b, btrans); no_nans_t b_no_nans(b_path_trans, true, b.has_curves()); curve_t b_curved(b_no_nans); double x, y; b_curved.rewind(0); while (b_curved.vertex(&x, &y) != agg::path_cmd_stop) { if (!::point_in_path(x, y, a, atrans)) return false; } return true; }
void _cleanup_path(PathIterator& path, const agg::trans_affine& trans, bool remove_nans, bool do_clip, const agg::rect_base<double>& rect, e_snap_mode snap_mode, double stroke_width, bool do_simplify, bool return_curves, std::vector<double>& vertices, std::vector<npy_uint8>& codes) { typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> nan_removal_t; typedef PathClipper<nan_removal_t> clipped_t; typedef PathSnapper<clipped_t> snapped_t; typedef PathSimplifier<snapped_t> simplify_t; typedef agg::conv_curve<simplify_t> curve_t; transformed_path_t tpath(path, trans); nan_removal_t nan_removed(tpath, remove_nans, path.has_curves()); clipped_t clipped(nan_removed, do_clip, rect); snapped_t snapped(clipped, snap_mode, path.total_vertices(), stroke_width); simplify_t simplified(snapped, do_simplify, path.simplify_threshold()); vertices.reserve(path.total_vertices() * 2); codes.reserve(path.total_vertices()); if (return_curves) { __cleanup_path(simplified, vertices, codes); } else { curve_t curve(simplified); __cleanup_path(curve, vertices, codes); } }
bool path_intersects_path(PathIterator& p1, PathIterator& p2) { typedef PathNanRemover<PathIterator> no_nans_t; typedef agg::conv_curve<no_nans_t> curve_t; if (p1.total_vertices() < 2 || p2.total_vertices() < 2) { return false; } no_nans_t n1(p1, true, p1.has_curves()); no_nans_t n2(p2, true, p2.has_curves()); curve_t c1(n1); curve_t c2(n2); double x11, y11, x12, y12; double x21, y21, x22, y22; c1.vertex(&x11, &y11); while (c1.vertex(&x12, &y12) != agg::path_cmd_stop) { c2.rewind(0); c2.vertex(&x21, &y21); while (c2.vertex(&x22, &y22) != agg::path_cmd_stop) { if (segments_intersect(x11, y11, x12, y12, x21, y21, x22, y22)) { return true; } x21 = x22; y21 = y22; } x11 = x12; y11 = y12; } return false; }
inline bool point_on_path(double x, double y, double r, PathIterator& path, const agg::trans_affine& trans) { typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> no_nans_t; typedef agg::conv_curve<no_nans_t> curve_t; typedef agg::conv_stroke<curve_t> stroke_t; transformed_path_t trans_path(path, trans); no_nans_t nan_removed_path(trans_path, true, path.has_curves()); curve_t curved_path(nan_removed_path); stroke_t stroked_path(curved_path); stroked_path.width(r * 2.0); return point_in_path_impl(x, y, stroked_path); }
inline bool point_in_path(double x, double y, PathIterator& path, const agg::trans_affine& trans) { typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> no_nans_t; typedef agg::conv_curve<no_nans_t> curve_t; if (path.total_vertices() < 3) { return false; } transformed_path_t trans_path(path, trans); no_nans_t no_nans_path(trans_path, true, path.has_curves()); curve_t curved_path(no_nans_path); return point_in_path_impl(x, y, curved_path); }
PathCleanupIterator(PyObject* path, agg::trans_affine trans, bool remove_nans, bool do_clip, const agg::rect_base<double>& rect, e_snap_mode snap_mode, double stroke_width, bool do_simplify) : m_path_obj(path, true), m_path_iter(m_path_obj), m_transform(trans), m_transformed(m_path_iter, m_transform), m_nan_removed(m_transformed, remove_nans, m_path_iter.has_curves()), m_clipped(m_nan_removed, do_clip, rect), m_snapped(m_clipped, snap_mode, m_path_iter.total_vertices(), stroke_width), m_simplify(m_snapped, do_simplify && m_path_iter.should_simplify(), m_path_iter.simplify_threshold()) { Py_INCREF(path); m_path_iter.rewind(0); }