File indexing completed on 2024-05-12 03:52:09

0001 /*******************************************************************************
0002 * Author    :  Angus Johnson                                                   *
0003 * Date      :  30 May 2023                                                     *
0004 * Website   :  http://www.angusj.com                                           *
0005 * Copyright :  Angus Johnson 2010-2023                                         *
0006 * Purpose   :  FAST rectangular clipping                                       *
0007 * License   :  http://www.boost.org/LICENSE_1_0.txt                            *
0008 *******************************************************************************/
0009 
0010 #ifndef CLIPPER_RECTCLIP_H
0011 #define CLIPPER_RECTCLIP_H
0012 
0013 #include <cstdlib>
0014 #include <vector>
0015 #include <queue>
0016 #include "clipper.h"
0017 #include "clipper.core.h"
0018 
0019 namespace Clipper2Lib
0020 {
0021 
0022   enum class Location { Left, Top, Right, Bottom, Inside };
0023 
0024   class OutPt2;
0025   typedef std::vector<OutPt2*> OutPt2List;
0026 
0027   class OutPt2 {
0028   public:
0029     Point64 pt;
0030     size_t owner_idx;
0031     OutPt2List* edge;
0032     OutPt2* next;
0033     OutPt2* prev;
0034   };
0035 
0036   //------------------------------------------------------------------------------
0037   // RectClip64
0038   //------------------------------------------------------------------------------
0039 
0040   class RectClip64 {
0041   private:
0042     void ExecuteInternal(const Path64& path);
0043     Path64 GetPath(OutPt2*& op);
0044   protected:
0045     const Rect64 rect_;
0046     const Path64 rect_as_path_;
0047     const Point64 rect_mp_;
0048     Rect64 path_bounds_;
0049     std::deque<OutPt2> op_container_;
0050     OutPt2List results_;  // each path can be broken into multiples
0051     OutPt2List edges_[8]; // clockwise and counter-clockwise
0052     std::vector<Location> start_locs_;
0053     void CheckEdges();
0054     void TidyEdges(int idx, OutPt2List& cw, OutPt2List& ccw);
0055     void GetNextLocation(const Path64& path,
0056       Location& loc, int& i, int highI);
0057     OutPt2* Add(Point64 pt, bool start_new = false);
0058     void AddCorner(Location prev, Location curr);
0059     void AddCorner(Location& loc, bool isClockwise);
0060   public:
0061     explicit RectClip64(const Rect64& rect) :
0062       rect_(rect),
0063       rect_as_path_(rect.AsPath()),
0064       rect_mp_(rect.MidPoint()) {}
0065     Paths64 Execute(const Paths64& paths);
0066   };
0067 
0068   //------------------------------------------------------------------------------
0069   // RectClipLines64
0070   //------------------------------------------------------------------------------
0071 
0072   class RectClipLines64 : public RectClip64 {
0073   private:
0074     void ExecuteInternal(const Path64& path);
0075     Path64 GetPath(OutPt2*& op);
0076   public:
0077     explicit RectClipLines64(const Rect64& rect) : RectClip64(rect) {};
0078     Paths64 Execute(const Paths64& paths);
0079   };
0080 
0081 } // Clipper2Lib namespace
0082 #endif  // CLIPPER_RECTCLIP_H