From f8aaf1972bd67344c23d5bbd2552daf6065f448d Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 13 Aug 2014 21:09:59 +0800 Subject: [PATCH] Clipping for RECT types. Breaks a little. When using QuadTrees, RECT_OUTLINE and RECT_FILLED are clipped to the quadtree node. This lets you zoom in forever on rectangles with a couple of caveats: 1. This is technically wrong for RECT_OUTLINE, as more lines will be added. 2. There are a couple of issues related to the fact that only one node is visible at a time. Notably: (a) You lose the infinite precision when stradling a quadtree boundary, which will happen eventually. (b) Zooming out will show random broken things. However, if you look at shape.svg, you can see how moving the camera around when both the RECT and the BEZIER are in view, the RECT moves smoothly and the BEZIER doesn't. --- src/document.cpp | 46 +++++++++++++++++++++++++++++++++++++++++----- src/document.h | 2 ++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/document.cpp b/src/document.cpp index 6038b19..9cb5aa8 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -99,6 +99,46 @@ void Document::GenBaseQuadtree() GenQuadChild(0, QTC_TOP_LEFT); } +int Document::ClipObjectToQuadChild(int object_id, QuadTreeNodeChildren type) +{ + switch (m_objects.types[object_id]) + { + case RECT_FILLED: + case RECT_OUTLINE: + { + Rect obj_bounds = TransformToQuadChild(m_objects.bounds[object_id], type); + if (obj_bounds.x < 0) + { + obj_bounds.w += obj_bounds.x; + obj_bounds.x = 0; + } + if (obj_bounds.y < 0) + { + obj_bounds.h += obj_bounds.y; + obj_bounds.y = 0; + } + if (obj_bounds.x + obj_bounds.w > 1) + { + obj_bounds.w += (1 - (obj_bounds.x + obj_bounds.w)); + } + if (obj_bounds.y + obj_bounds.h > 1) + { + obj_bounds.h += (1 - (obj_bounds.y + obj_bounds.h)); + } + m_objects.bounds.push_back(obj_bounds); + m_objects.types.push_back(m_objects.types[object_id]); + m_objects.data_indices.push_back(m_objects.data_indices[object_id]); + return 1; + } + default: + Debug("Adding %s -> %s", m_objects.bounds[object_id].Str().c_str(), TransformToQuadChild(m_objects.bounds[object_id], type).Str().c_str()); + m_objects.bounds.push_back(TransformToQuadChild(m_objects.bounds[object_id], type)); + m_objects.types.push_back(m_objects.types[object_id]); + m_objects.data_indices.push_back(m_objects.data_indices[object_id]); + return 1; + } + return 0; +} QuadTreeIndex Document::GenQuadChild(QuadTreeIndex parent, QuadTreeNodeChildren type) { QuadTreeIndex new_index = m_quadtree.nodes.size(); @@ -109,11 +149,7 @@ QuadTreeIndex Document::GenQuadChild(QuadTreeIndex parent, QuadTreeNodeChildren { if (IntersectsQuadChild(m_objects.bounds[i], type)) { - Debug("Adding %s -> %s", m_objects.bounds[i].Str().c_str(), TransformToQuadChild(m_objects.bounds[i], type).Str().c_str()); - m_objects.bounds.push_back(TransformToQuadChild(m_objects.bounds[i], type)); - m_objects.types.push_back(m_objects.types[i]); - m_objects.data_indices.push_back(m_objects.data_indices[i]); - m_count++; + m_count += ClipObjectToQuadChild(i, type); } } m_quadtree.nodes[new_index].object_end = m_objects.bounds.size(); diff --git a/src/document.h b/src/document.h index 529e4ab..76e3b7f 100644 --- a/src/document.h +++ b/src/document.h @@ -82,6 +82,8 @@ namespace IPDF inline const QuadTree& GetQuadTree() { if (m_quadtree.root_id == QUADTREE_EMPTY) { GenBaseQuadtree(); } return m_quadtree; } QuadTreeIndex GenQuadChild(QuadTreeIndex parent, QuadTreeNodeChildren type); QuadTreeIndex GenQuadParent(QuadTreeIndex child, QuadTreeNodeChildren mytype); + // Returns the number of objects the current object formed when clipped, the objects in question are added to the end of the document. + int ClipObjectToQuadChild(int object_id, QuadTreeNodeChildren type); #endif private: -- 2.20.1